Comparing version 0.9.5-0 to 0.9.6-0
405
API.md
@@ -19,2 +19,4 @@ #API Reference | ||
- [`Promise.longStackTraces()`](#promiselongstacktraces---void) | ||
- [Progression](#progression) | ||
- [`.progressed(Function handler)`](#progressedfunction-handler---promise) | ||
- [Promise resolution](#promise-resolution) | ||
@@ -25,4 +27,7 @@ - [`.fulfill(dynamic value)`](#fulfilldynamic-value---undefined) | ||
- [`.asCallback`](#ascallback---function) | ||
- [Progression](#progression) | ||
- [`.progressed(Function handler)`](#progressedfunction-handler---promise) | ||
- [Promisification](#promisification) | ||
- [`Promise.promisify(Function nodeFunction [, dynamic receiver])`](#promisepromisifyfunction-nodefunction--dynamic-receiver---function) | ||
- [`Promise.promisify(Object target)`](#promisepromisifyobject-target---object) | ||
- [`Promise.promisifyAll(Object target)`](#promisepromisifyallobject-target---object) | ||
- [`.error( [rejectedHandler] )`](#error-rejectedhandler----promise) | ||
- [Collections](#collections) | ||
@@ -64,5 +69,2 @@ - [`.all()`](#all---promise) | ||
- [`.toJSON()`](#tojson---object) | ||
- [`Promise.promisify(Function nodeFunction [, dynamic receiver])`](#promisepromisifyfunction-nodefunction--dynamic-receiver---function) | ||
- [`Promise.promisify(Object target)`](#promisepromisifyobject-target---object) | ||
- [`Promise.promisifyAll(Object target)`](#promisepromisifyallobject-target---object) | ||
- [`Promise.coroutine(GeneratorFunction generatorFunction)`](#promisecoroutinegeneratorfunction-generatorfunction---function) | ||
@@ -117,2 +119,4 @@ - [`Promise.spawn(GeneratorFunction generatorFunction)`](#promisespawngeneratorfunction-generatorfunction---promise) | ||
<hr> | ||
#####`.then([Function fulfilledHandler] [, Function rejectedHandler ] [, Function progressHandler ])` -> `Promise` | ||
@@ -134,2 +138,4 @@ | ||
<hr> | ||
#####`.catch(Function handler)` -> `Promise` | ||
@@ -141,2 +147,4 @@ | ||
<hr> | ||
#####`.catch([Function ErrorClass...], Function handler)` -> `Promise` | ||
@@ -220,2 +228,4 @@ | ||
<hr> | ||
#####`.finally(Function handler)` -> `Promise` | ||
@@ -267,2 +277,4 @@ | ||
<hr> | ||
#####`.bind(dynamic thisArg)` -> `Promise` | ||
@@ -412,2 +424,4 @@ | ||
<hr> | ||
#####`.done([Function fulfilledHandler] [, Function rejectedHandler ] [, Function progressHandler ])` -> `Promise` | ||
@@ -417,2 +431,4 @@ | ||
<hr> | ||
#####`Promise.try(Function fn [, Array<dynamic>|dynamic arguments] [, dynamic ctx] )` -> `Promise` | ||
@@ -439,2 +455,4 @@ | ||
<hr> | ||
#####`Promise.fulfilled(dynamic value)` -> `Promise` | ||
@@ -444,2 +462,4 @@ | ||
<hr> | ||
#####`Promise.rejected(dynamic reason)` -> `Promise` | ||
@@ -449,2 +469,4 @@ | ||
<hr> | ||
#####`Promise.pending()` -> `PromiseResolver` | ||
@@ -454,2 +476,4 @@ | ||
<hr> | ||
#####`Promise.cast(dynamic value)` -> `Promise` | ||
@@ -474,2 +498,4 @@ | ||
<hr> | ||
#####`Promise.bind(dynamic thisArg)` -> `Promise` | ||
@@ -479,2 +505,4 @@ | ||
<hr> | ||
#####`Promise.is(dynamic value)` -> `boolean` | ||
@@ -489,2 +517,4 @@ | ||
<hr> | ||
#####`Promise.longStackTraces()` -> `void` | ||
@@ -544,2 +574,4 @@ | ||
<hr> | ||
##Progression | ||
@@ -551,2 +583,4 @@ | ||
<hr> | ||
##Promise resolution | ||
@@ -558,2 +592,4 @@ | ||
<hr> | ||
#####`.fulfill(dynamic value)` -> `undefined` | ||
@@ -563,2 +599,4 @@ | ||
<hr> | ||
#####`.reject(dynamic reason)` -> `undefined` | ||
@@ -568,2 +606,4 @@ | ||
<hr> | ||
#####`.progress(dynamic value)` -> `undefined` | ||
@@ -590,2 +630,4 @@ | ||
<hr> | ||
#####`.asCallback` -> `Function` | ||
@@ -622,2 +664,176 @@ | ||
<hr> | ||
##Promisification | ||
#####`Promise.promisify(Function nodeFunction [, dynamic receiver])` -> `Function` | ||
Returns a function that will wrap the given `nodeFunction`. Instead of taking a callback, the returned function will return a promise whose fate is decided by the callback behavior of the given node function. The node function should conform to node.js convention of accepting a callback as last argument and calling that callback with error as the first argument and success value on the second argument. | ||
If the `nodeFunction` calls its callback with multiple success values, the fulfillment value will be an array of them. | ||
If you pass a `receiver`, the `nodeFunction` will be called as a method on the `receiver`. | ||
Example of promisifying the asynchronous `readFile` of node.js `fs`-module: | ||
```js | ||
var readFile = Promise.promisify(require("fs").readFile); | ||
readFile("myfile.js", "utf8").then(function(contents){ | ||
return eval(contents); | ||
}).then(function(result){ | ||
console.log("The result of evaluating myfile.js", result); | ||
}).catch(SyntaxError, function(e){ | ||
console.log("File had syntax error", e); | ||
//Catch any other error | ||
}).catch(function(e){ | ||
console.log("Error reading file", e); | ||
}); | ||
``` | ||
Note that if the node function is a method of some object, you need to pass the object as the second argument like so: | ||
```js | ||
var redisGet = Promise.promisify(redisClient.get, redisClient); | ||
redisGet.then(function(){ | ||
//... | ||
}); | ||
``` | ||
**Tip** | ||
Use [`.spread`](#spreadfunction-fulfilledhandler--function-rejectedhandler----promise) with APIs that have multiple success values: | ||
```js | ||
var Promise = require("bluebird"); | ||
var request = Promise.promisify(require('request')); | ||
request("http://www.google.com").spread(function(request, body) { | ||
console.log(body); | ||
}).catch(function(err) { | ||
console.error(err); | ||
}); | ||
``` | ||
The above uses [request](https://github.com/mikeal/request) library which has a callback signature of multiple success values. | ||
<hr> | ||
#####`Promise.promisify(Object target)` -> `Object` | ||
This overload has been **deprecated**. The overload will continue working for now. The recommended method for promisifying multiple methods at once is [`Promise.promisifyAll(Object target)`](#promisepromisifyallobject-target---object) | ||
<hr> | ||
#####`Promise.promisifyAll(Object target)` -> `Object` | ||
Promisifies the entire object by going through the object's properties and creating an async equivalent of each function on the object and its prototype chain. The promisified method name will be the original method name postfixed with `Async`. Returns the input object. | ||
Note that the original methods on the object are not overwritten but new methods are created with the `Async`-postfix. For example, if you `promisifyAll()` the node.js `fs` object use `fs.statAsync()` to call the promisified `stat` method. | ||
Example: | ||
```js | ||
Promise.promisifyAll(RedisClient.prototype); | ||
//Later on, all redis client instances have promise returning functions: | ||
redisClient.hexistsAsync("myhash", "field").then(function(v){ | ||
}).catch(function(e){ | ||
}); | ||
``` | ||
If you don't want to write on foreign prototypes, you can sub-class the target and promisify your subclass: | ||
```js | ||
function MyRedisClient() { | ||
RedisClient.apply(this, arguments); | ||
} | ||
MyRedisClient.prototype = Object.create(RedisClient.prototype); | ||
MyRedisClient.prototype.constructor = MyRedisClient; | ||
Promise.promisify(MyRedisClient.prototype); | ||
``` | ||
The promisified methods will be written on the `MyRedisClient.prototype` instead. This specific example doesn't actually work with `node_redis` because the `createClient` factory is hardcoded to instantiate `RedisClient` from closure. | ||
It also works on singletons or specific instances: | ||
```js | ||
var fs = Promise.promisifyAll(require("fs")); | ||
fs.readFileAsync("myfile.js", "utf8").then(function(contents){ | ||
console.log(contents); | ||
}).catch(function(e){ | ||
console.error(e.stack); | ||
}); | ||
``` | ||
The entire prototype chain of the object is promisified on the object. Only enumerable are considered. If the object already has a promisified version of the method, it will be skipped. The target methods are assumed to conform to node.js callback convention of accepting a callback as last argument and calling that callback with error as the first argument and success value on the second argument. If the node method calls its callback with multiple success values, the fulfillment value will be an array of them. | ||
If a method already has `"Async"` postfix, it will be duplicated. E.g. `getAsync`'s promisified name is `getAsyncAsync`. | ||
<hr> | ||
#####`.error( [rejectedHandler] )` -> `Promise` | ||
Sugar method for: | ||
```js | ||
somePromise.catch(Promise.RejectionError, function(e){ | ||
}); | ||
``` | ||
If a promisified function errbacks the node-style callback with an untyped error or a primitive, it will be automatically wrapped as `RejectionError` which has `.cause` property storing the original error. This is essentially providing separation between expected errors and unexpected errors. | ||
This method is expected to be used when wrapping libraries such as `fs` that don't use typed errors. If a library provides typed errors when an expected error happens, you can just use typed catches for them. | ||
In the following example you might want to handle just the `SyntaxError` from JSON.parse and Filesystem errors from `fs` but let programmer errors bubble as unhandled rejections: | ||
```js | ||
var fs = Promise.promisifyAll(require("fs")); | ||
fs.readFileAsync("myfile.json").then(JSON.parse).then(function (json) { | ||
console.log("Successful json") | ||
}).catch(SyntaxError, function (e) { | ||
console.error("file contains invalid json"); | ||
}).error(function (e) { | ||
console.error("unable to read file, because: ", e.message); | ||
}); | ||
``` | ||
Now, because there is no catch-all handler, if you typed `console.lag` (causes an error you don't expect), you will see: | ||
``` | ||
Possibly unhandled TypeError: Object #<Console> has no method 'lag' | ||
at application.js:8:13 | ||
From previous event: | ||
at Object.<anonymous> (application.js:7:4) | ||
at Module._compile (module.js:449:26) | ||
at Object.Module._extensions..js (module.js:467:10) | ||
at Module.load (module.js:349:32) | ||
at Function.Module._load (module.js:305:12) | ||
at Function.Module.runMain (module.js:490:10) | ||
at startup (node.js:121:16) | ||
at node.js:761:3 | ||
``` | ||
*( If you don't get the above - you need to enable [long stack traces](#promiselongstacktraces---void) )* | ||
And if the file contains invalid JSON: | ||
``` | ||
file contains invalid json | ||
``` | ||
And if the `fs` module causes an error like file not found: | ||
``` | ||
unable to read file, because: ENOENT, open 'not_there.txt' | ||
``` | ||
<hr> | ||
##Collections | ||
@@ -632,2 +848,4 @@ | ||
<hr> | ||
#####`.props()` -> `Promise` | ||
@@ -637,2 +855,4 @@ | ||
<hr> | ||
#####`.settle()` -> `Promise` | ||
@@ -642,2 +862,4 @@ | ||
<hr> | ||
#####`.any()` -> `Promise` | ||
@@ -647,2 +869,4 @@ | ||
<hr> | ||
#####`.some(int count)` -> `Promise` | ||
@@ -652,2 +876,4 @@ | ||
<hr> | ||
#####`.spread([Function fulfilledHandler] [, Function rejectedHandler ])` -> `Promise` | ||
@@ -675,2 +901,4 @@ | ||
<hr> | ||
#####`.map(Function mapper)` -> `Promise` | ||
@@ -680,2 +908,4 @@ | ||
<hr> | ||
#####`.reduce(Function reducer [, dynamic initialValue])` -> `Promise` | ||
@@ -685,2 +915,4 @@ | ||
<hr> | ||
#####`.filter(Function filterer)` -> `Promise` | ||
@@ -720,2 +952,4 @@ | ||
<hr> | ||
#####`Promise.all(Array<dynamic>|Promise values)` -> `Promise` | ||
@@ -742,2 +976,4 @@ | ||
<hr> | ||
#####`Promise.props(Object|Promise object)` -> `Promise` | ||
@@ -770,2 +1006,4 @@ | ||
<hr> | ||
#####`Promise.settle(Array<dynamic>|Promise values)` -> `Promise` | ||
@@ -777,2 +1015,4 @@ | ||
<hr> | ||
#####`Promise.any(Array<dynamic>|Promise values)` -> `Promise` | ||
@@ -782,2 +1022,4 @@ | ||
<hr> | ||
#####`Promise.some(Array<dynamic>|Promise values, int count)` -> `Promise` | ||
@@ -804,2 +1046,4 @@ | ||
<hr> | ||
#####`Promise.join([dynamic value...])` -> `Promise` | ||
@@ -825,2 +1069,4 @@ | ||
<hr> | ||
#####`Promise.map(Array<dynamic>|Promise values, Function mapper)` -> `Promise` | ||
@@ -836,2 +1082,4 @@ | ||
<hr> | ||
#####`Promise.reduce(Array<dynamic>|Promise values, Function reducer [, dynamic initialValue])` -> `Promise` | ||
@@ -845,2 +1093,4 @@ | ||
<hr> | ||
#####`Promise.filter(Array<dynamic>|Promise values, Function filterer)` -> `Promise` | ||
@@ -854,2 +1104,4 @@ | ||
<hr> | ||
##Cancellation | ||
@@ -876,2 +1128,4 @@ | ||
<hr> | ||
#####`.cancel()` -> `Promise` | ||
@@ -893,2 +1147,4 @@ | ||
<hr> | ||
#####`.fork([Function fulfilledHandler] [, Function rejectedHandler ] [, Function progressHandler ])` -> `Promise` | ||
@@ -900,6 +1156,10 @@ | ||
<hr> | ||
#####`.uncancellable()` -> `Promise` | ||
Create an uncancellable promise based on this promise | ||
Create an uncancellable promise based on this promise. | ||
<hr> | ||
#####`.isCancellable()` -> `boolean` | ||
@@ -909,2 +1169,4 @@ | ||
<hr> | ||
##Synchronous inspection | ||
@@ -938,2 +1200,4 @@ | ||
<hr> | ||
#####`.isFulfilled()` -> `boolean` | ||
@@ -943,2 +1207,4 @@ | ||
<hr> | ||
#####`.isRejected()` -> `boolean` | ||
@@ -948,2 +1214,4 @@ | ||
<hr> | ||
#####`.isPending()` -> `boolean` | ||
@@ -953,2 +1221,4 @@ | ||
<hr> | ||
#####`.isResolved()` -> `boolean` | ||
@@ -958,2 +1228,4 @@ | ||
<hr> | ||
#####`.inspect()` -> `PromiseInspection` | ||
@@ -983,2 +1255,3 @@ | ||
<hr> | ||
@@ -999,2 +1272,4 @@ ##Utility | ||
<hr> | ||
#####`.get(String propertyName)` -> `Promise` | ||
@@ -1010,2 +1285,4 @@ | ||
<hr> | ||
#####`.nodeify([Function callback])` -> `Promise` | ||
@@ -1048,5 +1325,8 @@ | ||
<hr> | ||
#####`.toString()` -> `String` | ||
<hr> | ||
#####`.toJSON()` -> `Object` | ||
@@ -1056,107 +1336,4 @@ | ||
<hr> | ||
#####`Promise.promisify(Function nodeFunction [, dynamic receiver])` -> `Function` | ||
Returns a function that will wrap the given `nodeFunction`. Instead of taking a callback, the returned function will return a promise whose fate is decided by the callback behavior of the given node function. The node function should conform to node.js convention of accepting a callback as last argument and calling that callback with error as the first argument and success value on the second argument. | ||
If the `nodeFunction` calls its callback with multiple success values, the fulfillment value will be an array of them. | ||
If you pass a `receiver`, the `nodeFunction` will be called as a method on the `receiver`. | ||
Example of promisifying the asynchronous `readFile` of node.js `fs`-module: | ||
```js | ||
var readFile = Promise.promisify(require("fs").readFile); | ||
readFile("myfile.js", "utf8").then(function(contents){ | ||
return eval(contents); | ||
}).then(function(result){ | ||
console.log("The result of evaluating myfile.js", result); | ||
}).catch(SyntaxError, function(e){ | ||
console.log("File had syntax error", e); | ||
//Catch any other error | ||
}).catch(function(e){ | ||
console.log("Error reading file", e); | ||
}); | ||
``` | ||
Note that if the node function is a method of some object, you need to pass the object as the second argument like so: | ||
```js | ||
var redisGet = Promise.promisify(redisClient.get, redisClient); | ||
redisGet.then(function(){ | ||
//... | ||
}); | ||
``` | ||
**Tip** | ||
Use [`.spread`](#spreadfunction-fulfilledhandler--function-rejectedhandler----promise) with APIs that have multiple success values: | ||
```js | ||
var Promise = require("bluebird"); | ||
var request = Promise.promisify(require('request')); | ||
request("http://www.google.com").spread(function(request, body) { | ||
console.log(body); | ||
}).catch(function(err) { | ||
console.error(err); | ||
}); | ||
``` | ||
The above uses [request](https://github.com/mikeal/request) library which has a callback signature of multiple success values. | ||
#####`Promise.promisify(Object target)` -> `Object` | ||
This overload has been **deprecated**. The overload will continue working for now. The recommended method for promisifying multiple methods at once is [`Promise.promisifyAll(Object target)`](#promisepromisifyallobject-target---object) | ||
#####`Promise.promisifyAll(Object target)` -> `Object` | ||
Promisifies the entire object by going through the object's properties and creating an async equivalent of each function on the object and its prototype chain. The promisified method name will be the original method name postfixed with `Async`. Returns the input object. | ||
Note that the original methods on the object are not overwritten but new methods are created with the `Async`-postfix. For example, if you `promisifyAll()` the node.js `fs` object use `fs.statAsync()` to call the promisified `stat` method. | ||
Example: | ||
```js | ||
Promise.promisifyAll(RedisClient.prototype); | ||
//Later on, all redis client instances have promise returning functions: | ||
redisClient.hexistsAsync("myhash", "field").then(function(v){ | ||
}).catch(function(e){ | ||
}); | ||
``` | ||
If you don't want to write on foreign prototypes, you can sub-class the target and promisify your subclass: | ||
```js | ||
function MyRedisClient() { | ||
RedisClient.apply(this, arguments); | ||
} | ||
MyRedisClient.prototype = Object.create(RedisClient.prototype); | ||
MyRedisClient.prototype.constructor = MyRedisClient; | ||
Promise.promisify(MyRedisClient.prototype); | ||
``` | ||
The promisified methods will be written on the `MyRedisClient.prototype` instead. This specific example doesn't actually work with `node_redis` because the `createClient` factory is hardcoded to instantiate `RedisClient` from closure. | ||
It also works on singletons or specific instances: | ||
```js | ||
var fs = Promise.promisifyAll(require("fs")); | ||
fs.readFileAsync("myfile.js", "utf8").then(function(contents){ | ||
console.log(contents); | ||
}).catch(function(e){ | ||
console.error(e.stack); | ||
}); | ||
``` | ||
The entire prototype chain of the object is promisified on the object. Only enumerable are considered. If the object already has a promisified version of the method, it will be skipped. The target methods are assumed to conform to node.js callback convention of accepting a callback as last argument and calling that callback with error as the first argument and success value on the second argument. If the node method calls its callback with multiple success values, the fulfillment value will be an array of them. | ||
If a method already has `"Async"` postfix, it will be duplicated. E.g. `getAsync`'s promisified name is `getAsyncAsync`. | ||
#####`Promise.coroutine(GeneratorFunction generatorFunction)` -> `Function` | ||
@@ -1215,2 +1392,4 @@ | ||
<hr> | ||
#####`Promise.spawn(GeneratorFunction generatorFunction)` -> `Promise` | ||
@@ -1262,2 +1441,4 @@ | ||
<hr> | ||
#####`Promise.noConflict()` -> `Object` | ||
@@ -1282,2 +1463,4 @@ | ||
<hr> | ||
#####`Promise.onPossiblyUnhandledRejection(Function handler)` -> `undefined` | ||
@@ -1294,1 +1477,3 @@ | ||
Passing no value or a non-function will have the effect of removing any kind of handling for possibly unhandled rejections. | ||
<hr> |
@@ -141,2 +141,3 @@ "use strict"; | ||
var globals = { | ||
Error: true, | ||
TypeError: true, | ||
@@ -143,0 +144,0 @@ __DEBUG__: false, |
@@ -103,5 +103,14 @@ /** | ||
var captureStackTrace = (function stackDetection() { | ||
function snip( str ) { | ||
var maxChars = 41; | ||
if( str.length < maxChars ) { | ||
return str; | ||
} | ||
return str.substr(0, maxChars - 3) + "..."; | ||
} | ||
function formatNonError( obj ) { | ||
var str = obj.toString(); | ||
if( str === "[object Object]") { | ||
var ruselessToString = /\[object [a-zA-Z0-9$_]+\]/; | ||
if( ruselessToString.test( str ) ) { | ||
try { | ||
@@ -115,3 +124,3 @@ var newStr = JSON.stringify(obj); | ||
} | ||
return ("(<" + str + ">, no stack trace)"); | ||
return ("(<" + snip( str ) + ">, no stack trace)"); | ||
} | ||
@@ -205,2 +214,2 @@ | ||
return CapturedTrace; | ||
}; | ||
}; |
@@ -24,2 +24,3 @@ /** | ||
var global = require("./global.js"); | ||
var Objectfreeze = global.Object.freeze; | ||
var util = require( "./util.js"); | ||
@@ -29,2 +30,3 @@ var inherits = util.inherits; | ||
var notEnumerableProp = util.notEnumerableProp; | ||
var Error = global.Error; | ||
@@ -103,6 +105,35 @@ function isStackAttached( val ) { | ||
function RejectionError( message ) { | ||
this.name = "RejectionError"; | ||
this.message = message; | ||
this.cause = message; | ||
if( message instanceof Error ) { | ||
this.message = message.message; | ||
this.stack = message.stack; | ||
} | ||
else if( Error.captureStackTrace ) { | ||
Error.captureStackTrace( this, this.constructor ); | ||
} | ||
} | ||
inherits( RejectionError, Error ); | ||
var key = "__BluebirdErrorTypes__"; | ||
var errorTypes = global[key]; | ||
if( !errorTypes ) { | ||
errorTypes = Objectfreeze({ | ||
CancellationError: CancellationError, | ||
TimeoutError: TimeoutError, | ||
RejectionError: RejectionError | ||
}); | ||
notEnumerableProp( global, key, errorTypes ); | ||
} | ||
module.exports = { | ||
Error: Error, | ||
TypeError: TypeError, | ||
CancellationError: CancellationError, | ||
TimeoutError: TimeoutError, | ||
CancellationError: errorTypes.CancellationError, | ||
RejectionError: errorTypes.RejectionError, | ||
TimeoutError: errorTypes.TimeoutError, | ||
attachDefaultState: attachDefaultState, | ||
@@ -116,2 +147,2 @@ ensureNotHandled: ensureNotHandled, | ||
canAttach: canAttach | ||
}; | ||
}; |
@@ -24,8 +24,43 @@ /** | ||
var util = require( "./util.js" ); | ||
var maybeWrapAsError = util.maybeWrapAsError; | ||
var errors = require( "./errors.js"); | ||
var TimeoutError = errors.TimeoutError; | ||
var RejectionError = errors.RejectionError; | ||
var async = require( "./async.js" ); | ||
var haveGetters = util.haveGetters; | ||
var nodebackForResolver = util.nodebackForResolver; | ||
function isUntypedError( obj ) { | ||
return obj instanceof Error && | ||
Object.getPrototypeOf( obj ) === Error.prototype; | ||
} | ||
function wrapAsRejectionError( obj ) { | ||
if( isUntypedError( obj ) ) { | ||
return new RejectionError( obj ); | ||
} | ||
return obj; | ||
} | ||
function nodebackForResolver( resolver ) { | ||
function PromiseResolver$_callback( err, value ) { | ||
if( err ) { | ||
resolver.reject( wrapAsRejectionError( maybeWrapAsError( err ) ) ); | ||
} | ||
else { | ||
if( arguments.length > 2 ) { | ||
var len = arguments.length; | ||
var val = new Array( len - 1 ); | ||
for( var i = 1; i < len; ++i ) { | ||
val[ i - 1 ] = arguments[ i ]; | ||
} | ||
value = val; | ||
} | ||
resolver.fulfill( value ); | ||
} | ||
} | ||
return PromiseResolver$_callback; | ||
} | ||
var PromiseResolver; | ||
@@ -51,2 +86,4 @@ if( !haveGetters ) { | ||
PromiseResolver._nodebackForResolver = nodebackForResolver; | ||
PromiseResolver.prototype.toString = function PromiseResolver$toString() { | ||
@@ -53,0 +90,0 @@ return "[object PromiseResolver]"; |
@@ -48,2 +48,3 @@ /** | ||
var TimeoutError = errors.TimeoutError; | ||
var RejectionError = errors.RejectionError; | ||
var ensureNotHandled = errors.ensureNotHandled; | ||
@@ -945,3 +946,6 @@ var withHandledMarked = errors.withHandledMarked; | ||
Promise.TypeError = TypeError; | ||
};/** | ||
Promise.RejectionError = RejectionError; | ||
}; | ||
/** | ||
* Copyright (c) 2013 Petka Antonov | ||
@@ -993,2 +997,3 @@ * | ||
var TimeoutError = errors.TimeoutError; | ||
var RejectionError = errors.RejectionError; | ||
var ensureNotHandled = errors.ensureNotHandled; | ||
@@ -1890,2 +1895,4 @@ var withHandledMarked = errors.withHandledMarked; | ||
Promise.TypeError = TypeError; | ||
Promise.RejectionError = RejectionError; | ||
require('./synchronous_inspection.js')(Promise); | ||
@@ -1910,2 +1917,2 @@ require('./any.js')(Promise,Promise$_All,PromiseArray); | ||
}; | ||
}; |
@@ -24,173 +24,180 @@ /** | ||
module.exports = function( Promise ) { | ||
var THIS = {}; | ||
var util = require( "./util.js"); | ||
var withAppended = util.withAppended; | ||
var maybeWrapAsError = util.maybeWrapAsError; | ||
var nodebackForResolver = util.nodebackForResolver; | ||
var canEvaluate = util.canEvaluate; | ||
var notEnumerableProp = util.notEnumerableProp; | ||
var deprecated = util.deprecated; | ||
var ASSERT = require( "./assert.js" ); | ||
var THIS = {}; | ||
var util = require( "./util.js"); | ||
var errors = require( "./errors.js" ); | ||
var nodebackForResolver = require( "./promise_resolver.js" ) | ||
._nodebackForResolver; | ||
var RejectionError = errors.RejectionError; | ||
var withAppended = util.withAppended; | ||
var maybeWrapAsError = util.maybeWrapAsError; | ||
var canEvaluate = util.canEvaluate; | ||
var notEnumerableProp = util.notEnumerableProp; | ||
var deprecated = util.deprecated; | ||
var ASSERT = require( "./assert.js" ); | ||
function makeNodePromisifiedEval( callback, receiver, originalName ) { | ||
function getCall(count) { | ||
var args = new Array(count); | ||
for( var i = 0, len = args.length; i < len; ++i ) { | ||
args[i] = "a" + (i+1); | ||
} | ||
var comma = count > 0 ? "," : ""; | ||
Promise.prototype.error = function( fn ) { | ||
return this.caught( RejectionError, fn ); | ||
}; | ||
if( typeof callback === "string" && | ||
receiver === THIS ) { | ||
return "this['" + callback + "']("+args.join(",") + | ||
comma +" fn);"+ | ||
"break;"; | ||
} | ||
return ( receiver === void 0 | ||
? "callback("+args.join(",")+ comma +" fn);" | ||
: "callback.call("+( receiver === THIS | ||
? "this" | ||
: "receiver" )+", "+args.join(",") + comma + " fn);" ) + | ||
"break;"; | ||
function makeNodePromisifiedEval( callback, receiver, originalName ) { | ||
function getCall(count) { | ||
var args = new Array(count); | ||
for( var i = 0, len = args.length; i < len; ++i ) { | ||
args[i] = "a" + (i+1); | ||
} | ||
var comma = count > 0 ? "," : ""; | ||
function getArgs() { | ||
return "var args = new Array( len + 1 );" + | ||
"var i = 0;" + | ||
"for( var i = 0; i < len; ++i ) { " + | ||
" args[i] = arguments[i];" + | ||
"}" + | ||
"args[i] = fn;"; | ||
if( typeof callback === "string" && | ||
receiver === THIS ) { | ||
return "this['" + callback + "']("+args.join(",") + | ||
comma +" fn);"+ | ||
"break;"; | ||
} | ||
return ( receiver === void 0 | ||
? "callback("+args.join(",")+ comma +" fn);" | ||
: "callback.call("+( receiver === THIS | ||
? "this" | ||
: "receiver" )+", "+args.join(",") + comma + " fn);" ) + | ||
"break;"; | ||
} | ||
var callbackName = ( typeof originalName === "string" ? | ||
originalName + "Async" : | ||
"promisified" ); | ||
return new Function("Promise", "callback", "receiver", | ||
"withAppended", "maybeWrapAsError", "nodebackForResolver", | ||
"var ret = function " + callbackName + | ||
"( a1, a2, a3, a4, a5 ) {\"use strict\";" + | ||
"var len = arguments.length;" + | ||
"var resolver = Promise.pending( " + callbackName + " );" + | ||
"var fn = nodebackForResolver( resolver );"+ | ||
"try{" + | ||
"switch( len ) {" + | ||
"case 1:" + getCall(1) + | ||
"case 2:" + getCall(2) + | ||
"case 3:" + getCall(3) + | ||
"case 0:" + getCall(0) + | ||
"case 4:" + getCall(4) + | ||
"case 5:" + getCall(5) + | ||
"default: " + getArgs() + (typeof callback === "string" | ||
? "this['" + callback + "'].apply(" | ||
: "callback.apply(" | ||
) + | ||
( receiver === THIS ? "this" : "receiver" ) + | ||
", args ); break;" + | ||
"}" + | ||
"}" + | ||
"catch(e){ " + | ||
"" + | ||
"resolver.reject( maybeWrapAsError( e ) );" + | ||
"}" + | ||
"return resolver.promise;" + | ||
"" + | ||
"}; ret.__isPromisified__ = true; return ret;" | ||
)(Promise, callback, receiver, withAppended, | ||
maybeWrapAsError, nodebackForResolver); | ||
function getArgs() { | ||
return "var args = new Array( len + 1 );" + | ||
"var i = 0;" + | ||
"for( var i = 0; i < len; ++i ) { " + | ||
" args[i] = arguments[i];" + | ||
"}" + | ||
"args[i] = fn;"; | ||
} | ||
function makeNodePromisifiedClosure( callback, receiver ) { | ||
function promisified() { | ||
var _receiver = receiver; | ||
if( receiver === THIS ) _receiver = this; | ||
if( typeof callback === "string" ) { | ||
callback = _receiver[callback]; | ||
} | ||
var resolver = Promise.pending( promisified ); | ||
var fn = nodebackForResolver( resolver ); | ||
try { | ||
callback.apply( _receiver, withAppended( arguments, fn ) ); | ||
} | ||
catch(e) { | ||
resolver.reject( maybeWrapAsError( e ) ); | ||
} | ||
return resolver.promise; | ||
var callbackName = ( typeof originalName === "string" ? | ||
originalName + "Async" : | ||
"promisified" ); | ||
return new Function("Promise", "callback", "receiver", | ||
"withAppended", "maybeWrapAsError", "nodebackForResolver", | ||
"var ret = function " + callbackName + | ||
"( a1, a2, a3, a4, a5 ) {\"use strict\";" + | ||
"var len = arguments.length;" + | ||
"var resolver = Promise.pending( " + callbackName + " );" + | ||
"var fn = nodebackForResolver( resolver );"+ | ||
"try{" + | ||
"switch( len ) {" + | ||
"case 1:" + getCall(1) + | ||
"case 2:" + getCall(2) + | ||
"case 3:" + getCall(3) + | ||
"case 0:" + getCall(0) + | ||
"case 4:" + getCall(4) + | ||
"case 5:" + getCall(5) + | ||
"default: " + getArgs() + (typeof callback === "string" | ||
? "this['" + callback + "'].apply(" | ||
: "callback.apply(" | ||
) + | ||
( receiver === THIS ? "this" : "receiver" ) + | ||
", args ); break;" + | ||
"}" + | ||
"}" + | ||
"catch(e){ " + | ||
"" + | ||
"resolver.reject( maybeWrapAsError( e ) );" + | ||
"}" + | ||
"return resolver.promise;" + | ||
"" + | ||
"}; ret.__isPromisified__ = true; return ret;" | ||
)(Promise, callback, receiver, withAppended, | ||
maybeWrapAsError, nodebackForResolver); | ||
} | ||
function makeNodePromisifiedClosure( callback, receiver ) { | ||
function promisified() { | ||
var _receiver = receiver; | ||
if( receiver === THIS ) _receiver = this; | ||
if( typeof callback === "string" ) { | ||
callback = _receiver[callback]; | ||
} | ||
promisified.__isPromisified__ = true; | ||
return promisified; | ||
var resolver = Promise.pending( promisified ); | ||
var fn = nodebackForResolver( resolver ); | ||
try { | ||
callback.apply( _receiver, withAppended( arguments, fn ) ); | ||
} | ||
catch(e) { | ||
resolver.reject( maybeWrapAsError( e ) ); | ||
} | ||
return resolver.promise; | ||
} | ||
promisified.__isPromisified__ = true; | ||
return promisified; | ||
} | ||
var makeNodePromisified = canEvaluate | ||
? makeNodePromisifiedEval | ||
: makeNodePromisifiedClosure; | ||
var makeNodePromisified = canEvaluate | ||
? makeNodePromisifiedEval | ||
: makeNodePromisifiedClosure; | ||
function f(){} | ||
function isPromisified( fn ) { | ||
return fn.__isPromisified__ === true; | ||
} | ||
var hasProp = {}.hasOwnProperty; | ||
var roriginal = new RegExp( "__beforePromisified__" + "$" ); | ||
function _promisify( callback, receiver, isAll ) { | ||
if( isAll ) { | ||
var changed = 0; | ||
var o = {}; | ||
for( var key in callback ) { | ||
if( !roriginal.test( key ) && | ||
!hasProp.call( callback, | ||
( key + "__beforePromisified__" ) ) && | ||
typeof callback[ key ] === "function" ) { | ||
var fn = callback[key]; | ||
if( !isPromisified( fn ) ) { | ||
changed++; | ||
var originalKey = key + "__beforePromisified__"; | ||
var promisifiedKey = key + "Async"; | ||
notEnumerableProp( callback, originalKey, fn ); | ||
o[ promisifiedKey ] = | ||
makeNodePromisified( originalKey, THIS, key ); | ||
} | ||
function f(){} | ||
function isPromisified( fn ) { | ||
return fn.__isPromisified__ === true; | ||
} | ||
var hasProp = {}.hasOwnProperty; | ||
var roriginal = new RegExp( "__beforePromisified__" + "$" ); | ||
function _promisify( callback, receiver, isAll ) { | ||
if( isAll ) { | ||
var changed = 0; | ||
var o = {}; | ||
for( var key in callback ) { | ||
if( !roriginal.test( key ) && | ||
!hasProp.call( callback, | ||
( key + "__beforePromisified__" ) ) && | ||
typeof callback[ key ] === "function" ) { | ||
var fn = callback[key]; | ||
if( !isPromisified( fn ) ) { | ||
changed++; | ||
var originalKey = key + "__beforePromisified__"; | ||
var promisifiedKey = key + "Async"; | ||
notEnumerableProp( callback, originalKey, fn ); | ||
o[ promisifiedKey ] = | ||
makeNodePromisified( originalKey, THIS, key ); | ||
} | ||
} | ||
if( changed > 0 ) { | ||
for( var key in o ) { | ||
if( hasProp.call( o, key ) ) { | ||
callback[key] = o[key]; | ||
} | ||
} | ||
if( changed > 0 ) { | ||
for( var key in o ) { | ||
if( hasProp.call( o, key ) ) { | ||
callback[key] = o[key]; | ||
} | ||
f.prototype = callback; | ||
} | ||
f.prototype = callback; | ||
} | ||
return callback; | ||
} | ||
else { | ||
return makeNodePromisified( callback, receiver, void 0 ); | ||
} | ||
return callback; | ||
} | ||
else { | ||
return makeNodePromisified( callback, receiver, void 0 ); | ||
} | ||
} | ||
Promise.promisify = function Promise$Promisify( callback, receiver ) { | ||
if( typeof callback === "object" && callback !== null ) { | ||
deprecated( "Promise.promisify for promisifying entire objects " + | ||
"is deprecated. Use Promise.promisifyAll instead." ); | ||
return _promisify( callback, receiver, true ); | ||
} | ||
if( typeof callback !== "function" ) { | ||
throw new TypeError( "callback must be a function" ); | ||
} | ||
if( isPromisified( callback ) ) { | ||
return callback; | ||
} | ||
return _promisify( | ||
callback, | ||
arguments.length < 2 ? THIS : receiver, | ||
false ); | ||
}; | ||
Promise.promisify = function Promise$Promisify( callback, receiver ) { | ||
if( typeof callback === "object" && callback !== null ) { | ||
deprecated( "Promise.promisify for promisifying entire objects " + | ||
"is deprecated. Use Promise.promisifyAll instead." ); | ||
return _promisify( callback, receiver, true ); | ||
} | ||
if( typeof callback !== "function" ) { | ||
throw new TypeError( "callback must be a function" ); | ||
} | ||
if( isPromisified( callback ) ) { | ||
return callback; | ||
} | ||
return _promisify( | ||
callback, | ||
arguments.length < 2 ? THIS : receiver, | ||
false ); | ||
}; | ||
Promise.promisifyAll = function Promise$PromisifyAll( target ) { | ||
if( typeof target !== "function" && typeof target !== "object" ) { | ||
throw new TypeError( "Cannot promisify " + typeof target ); | ||
} | ||
return _promisify( target, void 0, true ); | ||
}; | ||
Promise.promisifyAll = function Promise$PromisifyAll( target ) { | ||
if( typeof target !== "function" && typeof target !== "object" ) { | ||
throw new TypeError( "Cannot promisify " + typeof target ); | ||
} | ||
return _promisify( target, void 0, true ); | ||
}; | ||
}; | ||
@@ -157,23 +157,2 @@ /** | ||
function nodebackForResolver( resolver ) { | ||
function PromiseResolver$_callback( err, value ) { | ||
if( err ) { | ||
resolver.reject( maybeWrapAsError( err ) ); | ||
} | ||
else { | ||
if( arguments.length > 2 ) { | ||
var len = arguments.length; | ||
var val = new Array( len - 1 ); | ||
for( var i = 1; i < len; ++i ) { | ||
val[ i - 1 ] = arguments[ i ]; | ||
} | ||
value = val; | ||
} | ||
resolver.fulfill( value ); | ||
} | ||
} | ||
return PromiseResolver$_callback; | ||
} | ||
function withAppended( target, appendee ) { | ||
@@ -218,4 +197,3 @@ var len = target.length; | ||
asString: asString, | ||
maybeWrapAsError: maybeWrapAsError, | ||
nodebackForResolver: nodebackForResolver | ||
maybeWrapAsError: maybeWrapAsError | ||
}; |
@@ -103,5 +103,14 @@ /** | ||
var captureStackTrace = (function stackDetection() { | ||
function snip( str ) { | ||
var maxChars = 41; | ||
if( str.length < maxChars ) { | ||
return str; | ||
} | ||
return str.substr(0, maxChars - 3) + "..."; | ||
} | ||
function formatNonError( obj ) { | ||
var str = obj.toString(); | ||
if( str === "[object Object]") { | ||
var ruselessToString = /\[object [a-zA-Z0-9$_]+\]/; | ||
if( ruselessToString.test( str ) ) { | ||
try { | ||
@@ -115,3 +124,3 @@ var newStr = JSON.stringify(obj); | ||
} | ||
return ("(<" + str + ">, no stack trace)"); | ||
return ("(<" + snip( str ) + ">, no stack trace)"); | ||
} | ||
@@ -205,2 +214,2 @@ | ||
return CapturedTrace; | ||
}; | ||
}; |
@@ -24,2 +24,3 @@ /** | ||
var global = require("./global.js"); | ||
var Objectfreeze = global.Object.freeze; | ||
var util = require( "./util.js"); | ||
@@ -29,2 +30,3 @@ var inherits = util.inherits; | ||
var notEnumerableProp = util.notEnumerableProp; | ||
var Error = global.Error; | ||
@@ -103,6 +105,35 @@ function isStackAttached( val ) { | ||
function RejectionError( message ) { | ||
this.name = "RejectionError"; | ||
this.message = message; | ||
this.cause = message; | ||
if( message instanceof Error ) { | ||
this.message = message.message; | ||
this.stack = message.stack; | ||
} | ||
else if( Error.captureStackTrace ) { | ||
Error.captureStackTrace( this, this.constructor ); | ||
} | ||
} | ||
inherits( RejectionError, Error ); | ||
var key = "__BluebirdErrorTypes__"; | ||
var errorTypes = global[key]; | ||
if( !errorTypes ) { | ||
errorTypes = Objectfreeze({ | ||
CancellationError: CancellationError, | ||
TimeoutError: TimeoutError, | ||
RejectionError: RejectionError | ||
}); | ||
notEnumerableProp( global, key, errorTypes ); | ||
} | ||
module.exports = { | ||
Error: Error, | ||
TypeError: TypeError, | ||
CancellationError: CancellationError, | ||
TimeoutError: TimeoutError, | ||
CancellationError: errorTypes.CancellationError, | ||
RejectionError: errorTypes.RejectionError, | ||
TimeoutError: errorTypes.TimeoutError, | ||
attachDefaultState: attachDefaultState, | ||
@@ -116,2 +147,2 @@ ensureNotHandled: ensureNotHandled, | ||
canAttach: canAttach | ||
}; | ||
}; |
@@ -24,8 +24,43 @@ /** | ||
var util = require( "./util.js" ); | ||
var maybeWrapAsError = util.maybeWrapAsError; | ||
var errors = require( "./errors.js"); | ||
var TimeoutError = errors.TimeoutError; | ||
var RejectionError = errors.RejectionError; | ||
var async = require( "./async.js" ); | ||
var haveGetters = util.haveGetters; | ||
var nodebackForResolver = util.nodebackForResolver; | ||
function isUntypedError( obj ) { | ||
return obj instanceof Error && | ||
Object.getPrototypeOf( obj ) === Error.prototype; | ||
} | ||
function wrapAsRejectionError( obj ) { | ||
if( isUntypedError( obj ) ) { | ||
return new RejectionError( obj ); | ||
} | ||
return obj; | ||
} | ||
function nodebackForResolver( resolver ) { | ||
function PromiseResolver$_callback( err, value ) { | ||
if( err ) { | ||
resolver.reject( wrapAsRejectionError( maybeWrapAsError( err ) ) ); | ||
} | ||
else { | ||
if( arguments.length > 2 ) { | ||
var len = arguments.length; | ||
var val = new Array( len - 1 ); | ||
for( var i = 1; i < len; ++i ) { | ||
val[ i - 1 ] = arguments[ i ]; | ||
} | ||
value = val; | ||
} | ||
resolver.fulfill( value ); | ||
} | ||
} | ||
return PromiseResolver$_callback; | ||
} | ||
var PromiseResolver; | ||
@@ -51,2 +86,4 @@ if( !haveGetters ) { | ||
PromiseResolver._nodebackForResolver = nodebackForResolver; | ||
PromiseResolver.prototype.toString = function PromiseResolver$toString() { | ||
@@ -53,0 +90,0 @@ return "[object PromiseResolver]"; |
@@ -48,2 +48,3 @@ /** | ||
var TimeoutError = errors.TimeoutError; | ||
var RejectionError = errors.RejectionError; | ||
var ensureNotHandled = errors.ensureNotHandled; | ||
@@ -941,3 +942,6 @@ var withHandledMarked = errors.withHandledMarked; | ||
Promise.TypeError = TypeError; | ||
};/** | ||
Promise.RejectionError = RejectionError; | ||
}; | ||
/** | ||
* Copyright (c) 2013 Petka Antonov | ||
@@ -989,2 +993,3 @@ * | ||
var TimeoutError = errors.TimeoutError; | ||
var RejectionError = errors.RejectionError; | ||
var ensureNotHandled = errors.ensureNotHandled; | ||
@@ -1882,2 +1887,4 @@ var withHandledMarked = errors.withHandledMarked; | ||
Promise.TypeError = TypeError; | ||
Promise.RejectionError = RejectionError; | ||
require('./synchronous_inspection.js')(Promise); | ||
@@ -1902,2 +1909,2 @@ require('./any.js')(Promise,Promise$_All,PromiseArray); | ||
}; | ||
}; |
@@ -24,173 +24,180 @@ /** | ||
module.exports = function( Promise ) { | ||
var THIS = {}; | ||
var util = require( "./util.js"); | ||
var withAppended = util.withAppended; | ||
var maybeWrapAsError = util.maybeWrapAsError; | ||
var nodebackForResolver = util.nodebackForResolver; | ||
var canEvaluate = util.canEvaluate; | ||
var notEnumerableProp = util.notEnumerableProp; | ||
var deprecated = util.deprecated; | ||
var ASSERT = require( "./assert.js" ); | ||
var THIS = {}; | ||
var util = require( "./util.js"); | ||
var errors = require( "./errors.js" ); | ||
var nodebackForResolver = require( "./promise_resolver.js" ) | ||
._nodebackForResolver; | ||
var RejectionError = errors.RejectionError; | ||
var withAppended = util.withAppended; | ||
var maybeWrapAsError = util.maybeWrapAsError; | ||
var canEvaluate = util.canEvaluate; | ||
var notEnumerableProp = util.notEnumerableProp; | ||
var deprecated = util.deprecated; | ||
var ASSERT = require( "./assert.js" ); | ||
function makeNodePromisifiedEval( callback, receiver, originalName ) { | ||
function getCall(count) { | ||
var args = new Array(count); | ||
for( var i = 0, len = args.length; i < len; ++i ) { | ||
args[i] = "a" + (i+1); | ||
} | ||
var comma = count > 0 ? "," : ""; | ||
Promise.prototype.error = function( fn ) { | ||
return this.caught( RejectionError, fn ); | ||
}; | ||
if( typeof callback === "string" && | ||
receiver === THIS ) { | ||
return "this['" + callback + "']("+args.join(",") + | ||
comma +" fn);"+ | ||
"break;"; | ||
} | ||
return ( receiver === void 0 | ||
? "callback("+args.join(",")+ comma +" fn);" | ||
: "callback.call("+( receiver === THIS | ||
? "this" | ||
: "receiver" )+", "+args.join(",") + comma + " fn);" ) + | ||
"break;"; | ||
function makeNodePromisifiedEval( callback, receiver, originalName ) { | ||
function getCall(count) { | ||
var args = new Array(count); | ||
for( var i = 0, len = args.length; i < len; ++i ) { | ||
args[i] = "a" + (i+1); | ||
} | ||
var comma = count > 0 ? "," : ""; | ||
function getArgs() { | ||
return "var args = new Array( len + 1 );" + | ||
"var i = 0;" + | ||
"for( var i = 0; i < len; ++i ) { " + | ||
" args[i] = arguments[i];" + | ||
"}" + | ||
"args[i] = fn;"; | ||
if( typeof callback === "string" && | ||
receiver === THIS ) { | ||
return "this['" + callback + "']("+args.join(",") + | ||
comma +" fn);"+ | ||
"break;"; | ||
} | ||
return ( receiver === void 0 | ||
? "callback("+args.join(",")+ comma +" fn);" | ||
: "callback.call("+( receiver === THIS | ||
? "this" | ||
: "receiver" )+", "+args.join(",") + comma + " fn);" ) + | ||
"break;"; | ||
} | ||
var callbackName = ( typeof originalName === "string" ? | ||
originalName + "Async" : | ||
"promisified" ); | ||
return new Function("Promise", "callback", "receiver", | ||
"withAppended", "maybeWrapAsError", "nodebackForResolver", | ||
"var ret = function " + callbackName + | ||
"( a1, a2, a3, a4, a5 ) {\"use strict\";" + | ||
"var len = arguments.length;" + | ||
"var resolver = Promise.pending( " + callbackName + " );" + | ||
"var fn = nodebackForResolver( resolver );"+ | ||
"try{" + | ||
"switch( len ) {" + | ||
"case 1:" + getCall(1) + | ||
"case 2:" + getCall(2) + | ||
"case 3:" + getCall(3) + | ||
"case 0:" + getCall(0) + | ||
"case 4:" + getCall(4) + | ||
"case 5:" + getCall(5) + | ||
"default: " + getArgs() + (typeof callback === "string" | ||
? "this['" + callback + "'].apply(" | ||
: "callback.apply(" | ||
) + | ||
( receiver === THIS ? "this" : "receiver" ) + | ||
", args ); break;" + | ||
"}" + | ||
"}" + | ||
"catch(e){ " + | ||
"" + | ||
"resolver.reject( maybeWrapAsError( e ) );" + | ||
"}" + | ||
"return resolver.promise;" + | ||
"" + | ||
"}; ret.__isPromisified__ = true; return ret;" | ||
)(Promise, callback, receiver, withAppended, | ||
maybeWrapAsError, nodebackForResolver); | ||
function getArgs() { | ||
return "var args = new Array( len + 1 );" + | ||
"var i = 0;" + | ||
"for( var i = 0; i < len; ++i ) { " + | ||
" args[i] = arguments[i];" + | ||
"}" + | ||
"args[i] = fn;"; | ||
} | ||
function makeNodePromisifiedClosure( callback, receiver ) { | ||
function promisified() { | ||
var _receiver = receiver; | ||
if( receiver === THIS ) _receiver = this; | ||
if( typeof callback === "string" ) { | ||
callback = _receiver[callback]; | ||
} | ||
var resolver = Promise.pending( promisified ); | ||
var fn = nodebackForResolver( resolver ); | ||
try { | ||
callback.apply( _receiver, withAppended( arguments, fn ) ); | ||
} | ||
catch(e) { | ||
resolver.reject( maybeWrapAsError( e ) ); | ||
} | ||
return resolver.promise; | ||
var callbackName = ( typeof originalName === "string" ? | ||
originalName + "Async" : | ||
"promisified" ); | ||
return new Function("Promise", "callback", "receiver", | ||
"withAppended", "maybeWrapAsError", "nodebackForResolver", | ||
"var ret = function " + callbackName + | ||
"( a1, a2, a3, a4, a5 ) {\"use strict\";" + | ||
"var len = arguments.length;" + | ||
"var resolver = Promise.pending( " + callbackName + " );" + | ||
"var fn = nodebackForResolver( resolver );"+ | ||
"try{" + | ||
"switch( len ) {" + | ||
"case 1:" + getCall(1) + | ||
"case 2:" + getCall(2) + | ||
"case 3:" + getCall(3) + | ||
"case 0:" + getCall(0) + | ||
"case 4:" + getCall(4) + | ||
"case 5:" + getCall(5) + | ||
"default: " + getArgs() + (typeof callback === "string" | ||
? "this['" + callback + "'].apply(" | ||
: "callback.apply(" | ||
) + | ||
( receiver === THIS ? "this" : "receiver" ) + | ||
", args ); break;" + | ||
"}" + | ||
"}" + | ||
"catch(e){ " + | ||
"" + | ||
"resolver.reject( maybeWrapAsError( e ) );" + | ||
"}" + | ||
"return resolver.promise;" + | ||
"" + | ||
"}; ret.__isPromisified__ = true; return ret;" | ||
)(Promise, callback, receiver, withAppended, | ||
maybeWrapAsError, nodebackForResolver); | ||
} | ||
function makeNodePromisifiedClosure( callback, receiver ) { | ||
function promisified() { | ||
var _receiver = receiver; | ||
if( receiver === THIS ) _receiver = this; | ||
if( typeof callback === "string" ) { | ||
callback = _receiver[callback]; | ||
} | ||
promisified.__isPromisified__ = true; | ||
return promisified; | ||
var resolver = Promise.pending( promisified ); | ||
var fn = nodebackForResolver( resolver ); | ||
try { | ||
callback.apply( _receiver, withAppended( arguments, fn ) ); | ||
} | ||
catch(e) { | ||
resolver.reject( maybeWrapAsError( e ) ); | ||
} | ||
return resolver.promise; | ||
} | ||
promisified.__isPromisified__ = true; | ||
return promisified; | ||
} | ||
var makeNodePromisified = canEvaluate | ||
? makeNodePromisifiedEval | ||
: makeNodePromisifiedClosure; | ||
var makeNodePromisified = canEvaluate | ||
? makeNodePromisifiedEval | ||
: makeNodePromisifiedClosure; | ||
function f(){} | ||
function isPromisified( fn ) { | ||
return fn.__isPromisified__ === true; | ||
} | ||
var hasProp = {}.hasOwnProperty; | ||
var roriginal = new RegExp( "__beforePromisified__" + "$" ); | ||
function _promisify( callback, receiver, isAll ) { | ||
if( isAll ) { | ||
var changed = 0; | ||
var o = {}; | ||
for( var key in callback ) { | ||
if( !roriginal.test( key ) && | ||
!hasProp.call( callback, | ||
( key + "__beforePromisified__" ) ) && | ||
typeof callback[ key ] === "function" ) { | ||
var fn = callback[key]; | ||
if( !isPromisified( fn ) ) { | ||
changed++; | ||
var originalKey = key + "__beforePromisified__"; | ||
var promisifiedKey = key + "Async"; | ||
notEnumerableProp( callback, originalKey, fn ); | ||
o[ promisifiedKey ] = | ||
makeNodePromisified( originalKey, THIS, key ); | ||
} | ||
function f(){} | ||
function isPromisified( fn ) { | ||
return fn.__isPromisified__ === true; | ||
} | ||
var hasProp = {}.hasOwnProperty; | ||
var roriginal = new RegExp( "__beforePromisified__" + "$" ); | ||
function _promisify( callback, receiver, isAll ) { | ||
if( isAll ) { | ||
var changed = 0; | ||
var o = {}; | ||
for( var key in callback ) { | ||
if( !roriginal.test( key ) && | ||
!hasProp.call( callback, | ||
( key + "__beforePromisified__" ) ) && | ||
typeof callback[ key ] === "function" ) { | ||
var fn = callback[key]; | ||
if( !isPromisified( fn ) ) { | ||
changed++; | ||
var originalKey = key + "__beforePromisified__"; | ||
var promisifiedKey = key + "Async"; | ||
notEnumerableProp( callback, originalKey, fn ); | ||
o[ promisifiedKey ] = | ||
makeNodePromisified( originalKey, THIS, key ); | ||
} | ||
} | ||
if( changed > 0 ) { | ||
for( var key in o ) { | ||
if( hasProp.call( o, key ) ) { | ||
callback[key] = o[key]; | ||
} | ||
} | ||
if( changed > 0 ) { | ||
for( var key in o ) { | ||
if( hasProp.call( o, key ) ) { | ||
callback[key] = o[key]; | ||
} | ||
f.prototype = callback; | ||
} | ||
f.prototype = callback; | ||
} | ||
return callback; | ||
} | ||
else { | ||
return makeNodePromisified( callback, receiver, void 0 ); | ||
} | ||
return callback; | ||
} | ||
else { | ||
return makeNodePromisified( callback, receiver, void 0 ); | ||
} | ||
} | ||
Promise.promisify = function Promise$Promisify( callback, receiver ) { | ||
if( typeof callback === "object" && callback !== null ) { | ||
deprecated( "Promise.promisify for promisifying entire objects " + | ||
"is deprecated. Use Promise.promisifyAll instead." ); | ||
return _promisify( callback, receiver, true ); | ||
} | ||
if( typeof callback !== "function" ) { | ||
throw new TypeError( "callback must be a function" ); | ||
} | ||
if( isPromisified( callback ) ) { | ||
return callback; | ||
} | ||
return _promisify( | ||
callback, | ||
arguments.length < 2 ? THIS : receiver, | ||
false ); | ||
}; | ||
Promise.promisify = function Promise$Promisify( callback, receiver ) { | ||
if( typeof callback === "object" && callback !== null ) { | ||
deprecated( "Promise.promisify for promisifying entire objects " + | ||
"is deprecated. Use Promise.promisifyAll instead." ); | ||
return _promisify( callback, receiver, true ); | ||
} | ||
if( typeof callback !== "function" ) { | ||
throw new TypeError( "callback must be a function" ); | ||
} | ||
if( isPromisified( callback ) ) { | ||
return callback; | ||
} | ||
return _promisify( | ||
callback, | ||
arguments.length < 2 ? THIS : receiver, | ||
false ); | ||
}; | ||
Promise.promisifyAll = function Promise$PromisifyAll( target ) { | ||
if( typeof target !== "function" && typeof target !== "object" ) { | ||
throw new TypeError( "Cannot promisify " + typeof target ); | ||
} | ||
return _promisify( target, void 0, true ); | ||
}; | ||
Promise.promisifyAll = function Promise$PromisifyAll( target ) { | ||
if( typeof target !== "function" && typeof target !== "object" ) { | ||
throw new TypeError( "Cannot promisify " + typeof target ); | ||
} | ||
return _promisify( target, void 0, true ); | ||
}; | ||
}; | ||
@@ -157,23 +157,2 @@ /** | ||
function nodebackForResolver( resolver ) { | ||
function PromiseResolver$_callback( err, value ) { | ||
if( err ) { | ||
resolver.reject( maybeWrapAsError( err ) ); | ||
} | ||
else { | ||
if( arguments.length > 2 ) { | ||
var len = arguments.length; | ||
var val = new Array( len - 1 ); | ||
for( var i = 1; i < len; ++i ) { | ||
val[ i - 1 ] = arguments[ i ]; | ||
} | ||
value = val; | ||
} | ||
resolver.fulfill( value ); | ||
} | ||
} | ||
return PromiseResolver$_callback; | ||
} | ||
function withAppended( target, appendee ) { | ||
@@ -218,4 +197,3 @@ var len = target.length; | ||
asString: asString, | ||
maybeWrapAsError: maybeWrapAsError, | ||
nodebackForResolver: nodebackForResolver | ||
maybeWrapAsError: maybeWrapAsError | ||
}; |
{ | ||
"name": "bluebird", | ||
"description": "Full featured Promises/A+ implementation with exceptionally good performance", | ||
"version": "0.9.5-0", | ||
"version": "0.9.6-0", | ||
"keywords": [ | ||
@@ -6,0 +6,0 @@ "promise", |
302
README.md
@@ -8,19 +8,7 @@ <a href="http://promisesaplus.com/"> | ||
Bluebird is a full featured [promise](#what-are-promises-and-why-should-i-use-them) library with unmatched performance. | ||
Bluebird is a fully featured [promise](#what-are-promises-and-why-should-i-use-them) library with focus on innovative features and performance. | ||
Features: | ||
- [Promises A+ 3.x.x](https://github.com/promises-aplus/promises-spec) | ||
- [Promises A+ 2.x.x](https://github.com/domenic/promises-unwrapping) | ||
- [Cancellation](https://github.com/promises-aplus) | ||
- [Progression](https://github.com/promises-aplus/progress-spec) | ||
- [Synchronous inspection](https://github.com/promises-aplus/synchronous-inspection-spec) | ||
- All, any, some, settle, map, reduce, spread, join... | ||
- [Unhandled rejections and long, relevant stack traces](#error-handling) | ||
- [Sick performance](https://github.com/petkaantonov/bluebird/tree/master/benchmark/stats) | ||
Passes [AP2](https://github.com/petkaantonov/bluebird/tree/master/test/mocha), [AP3](https://github.com/petkaantonov/bluebird/tree/master/test/mocha), [Cancellation](https://github.com/petkaantonov/bluebird/blob/master/test/mocha/cancel.js), [Progress](https://github.com/petkaantonov/bluebird/blob/master/test/mocha/q_progress.js), [promises_unwrapping](https://github.com/petkaantonov/bluebird/blob/master/test/mocha/promises_unwrapping.js) (Just in time thenables), [Q](https://github.com/petkaantonov/bluebird/tree/master/test/mocha) and [When.js](https://github.com/petkaantonov/bluebird/tree/master/test) tests. See [testing](#testing). | ||
#Topics | ||
- [Features](#features) | ||
- [Quick start](#quick-start) | ||
@@ -39,2 +27,19 @@ - [API Reference and examples](https://github.com/petkaantonov/bluebird/blob/master/API.md) | ||
#Features: | ||
- [Promises A+ 3.x.x](https://github.com/promises-aplus/promises-spec) | ||
- [Promises A+ 2.x.x](https://github.com/domenic/promises-unwrapping) | ||
- [Cancellation](https://github.com/promises-aplus) | ||
- [Progression](https://github.com/promises-aplus/progress-spec) | ||
- [Synchronous inspection](https://github.com/promises-aplus/synchronous-inspection-spec) | ||
- [`.bind`](https://github.com/petkaantonov/bluebird/blob/master/API.md#binddynamic-thisarg---promise) | ||
- [Complete parallel for C# 5.0 async and await](https://github.com/petkaantonov/bluebird/blob/master/API.md#promisecoroutinegeneratorfunction-generatorfunction---function) | ||
- [Collection methods](https://github.com/petkaantonov/bluebird/blob/master/API.md#collections) such as All, any, some, settle, map, filter, reduce, spread, join... | ||
- [Practical debugging solutions](#error-handling) such as unhandled rejection reporting, typed catches, catching only what you expect and very long, relevant stack traces without losing perf | ||
- [Sick performance](https://github.com/petkaantonov/bluebird/tree/master/benchmark/stats) | ||
Passes [AP2](https://github.com/petkaantonov/bluebird/tree/master/test/mocha), [AP3](https://github.com/petkaantonov/bluebird/tree/master/test/mocha), [Cancellation](https://github.com/petkaantonov/bluebird/blob/master/test/mocha/cancel.js), [Progress](https://github.com/petkaantonov/bluebird/blob/master/test/mocha/q_progress.js), [promises_unwrapping](https://github.com/petkaantonov/bluebird/blob/master/test/mocha/promises_unwrapping.js) (Just in time thenables), [Q](https://github.com/petkaantonov/bluebird/tree/master/test/mocha) and [When.js](https://github.com/petkaantonov/bluebird/tree/master/test) tests. See [testing](#testing). | ||
<hr> | ||
#Quick start | ||
@@ -52,2 +57,10 @@ | ||
``` | ||
If you want to ensure you get your own fresh copy of bluebird, do instead: | ||
```js | ||
//Note the extra function call | ||
var Promise = require("bluebird/js/main/promise")(); | ||
``` | ||
##Browsers | ||
@@ -73,8 +86,123 @@ | ||
You should use promises to make robust asynchronous programming a joy. | ||
You should use promises to turn this: | ||
More info: | ||
```js | ||
readFile("file.json", function(err, val) { | ||
if( err ) { | ||
console.error("unable to read file"); | ||
} | ||
else { | ||
try { | ||
val = JSON.parse(val); | ||
console.log(val.success); | ||
} | ||
catch( e ) { | ||
console.error("invalid json in file"); | ||
} | ||
} | ||
}); | ||
``` | ||
- [You're missing the point of promises](http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/). | ||
Into this: | ||
```js | ||
readFile("file.json").then(JSON.parse).then(function(val) { | ||
console.log(val.success); | ||
}) | ||
.catch(SyntaxError, function(e) { | ||
console.error("invalid json in file"); | ||
}) | ||
.catch(function(e){ | ||
console.error("unable to read file") | ||
}); | ||
``` | ||
Actually you might notice the latter has a lot in common with code that would do the same using synchronous I/O: | ||
```js | ||
try { | ||
var val = JSON.parse(readFile("file.json")); | ||
console.log(val.success); | ||
} | ||
//Syntax actually not supported in JS but drives the point | ||
catch(SyntaxError e) { | ||
console.error("invalid json in file"); | ||
} | ||
catch(Error e) { | ||
console.error("unable to read file") | ||
} | ||
``` | ||
And that is the point - being able to have something that is a lot like `return` and `throw` in synchronous code. | ||
You can also use promises to improve code that was written with callback helpers: | ||
```js | ||
//Copyright Plato http://stackoverflow.com/a/19385911/995876 | ||
//CC BY-SA 2.5 | ||
mapSeries(URLs, function (URL, done) { | ||
var options = {}; | ||
needle.get(URL, options, function (error, response, body) { | ||
if (error) { | ||
return done(error) | ||
} | ||
try { | ||
var ret = JSON.parse(body); | ||
return done(null, ret); | ||
} | ||
catch (e) { | ||
done(e); | ||
} | ||
}); | ||
}, function (err, results) { | ||
if (err) { | ||
console.log(err) | ||
} else { | ||
console.log('All Needle requests successful'); | ||
// results is a 1 to 1 mapping in order of URLs > needle.body | ||
processAndSaveAllInDB(results, function (err) { | ||
if (err) { | ||
return done(err) | ||
} | ||
console.log('All Needle requests saved'); | ||
done(null); | ||
}); | ||
} | ||
}); | ||
``` | ||
Is more pleasing to the eye when done with promises: | ||
```js | ||
Promise.promisifyAll(needle); | ||
var options = {}; | ||
var current = Promise.fulfilled(); | ||
Promise.map(URLs, function(URL) { | ||
current = current.then(function () { | ||
return needle.getAsync(URL, options); | ||
}); | ||
return current; | ||
}).map(function(responseAndBody){ | ||
return JSON.parse(responseAndBody[1]); | ||
}).then(function (results) { | ||
return processAndSaveAllInDB(results); | ||
}).then(function(){ | ||
console.log('All Needle requests saved'); | ||
}).catch(function (e) { | ||
console.log(e); | ||
}); | ||
``` | ||
Also promises don't just give you correspondences for synchronous features but can also be used as limited event emitters or callback aggregators. | ||
More reading: | ||
- [Promise nuggets](http://spion.github.io/promise-nuggets/) | ||
- [Why I am switching to promises](http://spion.github.io/posts/why-i-am-switching-to-promises.html) | ||
- [What is the the point of promises](http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/#toc_1) | ||
- [Snippets for common problems](https://github.com/petkaantonov/bluebird/wiki/Snippets) | ||
- [Promise anti-patterns](https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns) | ||
#Error handling | ||
@@ -126,2 +254,73 @@ | ||
####Expected and unexpected errors | ||
A practical problem with Promises/A+ is that it models Javascript `try-catch` too closely for its own good. Therefore by default promises inherit `try-catch` warts such as the inability to specify the error types that the catch block is eligible for. It is an anti-pattern in every other language to use catch-all handlers because they swallow exceptions that you might not know about. | ||
Now, Javascript does have a perfectly fine and working way of creating error type hierarchies. It is still quite awkward to use them with the built-in `try-catch` however: | ||
```js | ||
try { | ||
//code | ||
} | ||
catch(e) { | ||
if( e instanceof WhatIWantError) { | ||
//handle | ||
} | ||
else { | ||
throw e; | ||
} | ||
} | ||
``` | ||
Without such checking, unexpected errors would be silently swallowed. However, with promises, bluebird brings the future (hopefully) here now and extends the `.catch` to [accept potential error type eligibility](https://github.com/petkaantonov/bluebird/blob/master/API.md#catchfunction-errorclass-function-handler---promise). | ||
For instance here it is expected that some evil or incompetent entity will try to crash our server from `SyntaxError` by providing syntactically invalid JSON: | ||
```js | ||
getJSONFromSomewhere().then(function(jsonString) { | ||
return JSON.parse(jsonString); | ||
}).then(function(object) { | ||
console.log("it was valid json: ", object); | ||
}).catch(SyntaxError, function(e){ | ||
console.log("don't be evil"); | ||
}); | ||
``` | ||
Here any kind of unexpected error will automatically reported on stderr along with a stack trace because we only register a handler for the expected `SyntaxError`. | ||
Ok, so, that's pretty neat. But actually not many libraries define error types and it is in fact a complete ghetto out there with ad hoc strings being attached as some arbitrary property name like `.name`, `.type`, `.code`, not having any property at all or even throwing strings as errors and so on. So how can we still listen for expected errors? | ||
Bluebird defines a special error type `RejectionError` (you can get a reference from `Promise.RejectionError`). This type of error is given as rejection reason by promisified methods when | ||
their underlying library gives an untyped, but expected error. Primitives such as strings, and error objects that are directly created like `new Error("database didn't respond")` are considered untyped. | ||
Example of such library is the node core library `fs`. So if we promisify it, we can catch just the errors we want pretty easily and have programmer errors be redirected to unhandled rejection handler so that we notice them: | ||
```js | ||
//Read more about promisification in the API Reference: | ||
//https://github.com/petkaantonov/bluebird/blob/master/API.md | ||
var fs = Promise.promisifyAll(require("fs")); | ||
fs.readFileAsync("myfile.json").then(JSON.parse).then(function (json) { | ||
console.log("Successful json") | ||
}).catch(SyntaxError, function (e) { | ||
console.error("file contains invalid json"); | ||
}).catch(Promise.RejectionError, function (e) { | ||
console.error("unable to read file, because: ", e.message); | ||
}); | ||
``` | ||
The last `catch` handler is only invoked when the `fs` module explicitly used the `err` argument convention of async callbacks to inform of an expected error. The `RejectionError` instance will contain the original error in its `.cause` property but it does have a direct copy of the `.message` and `.stack` too. In this code any unexpected error - be it in our code or the `fs` module - would not be caught by these handlers and therefore not swallowed. | ||
Since a `catch` handler typed to `Promise.RejectionError` is expected to be used very often, it has a neat shorthand: | ||
```js | ||
.error(function (e) { | ||
console.error("unable to read file, because: ", e.message); | ||
}); | ||
``` | ||
See [API documentation for `.error()`](https://github.com/petkaantonov/bluebird/blob/master/API.md#error-rejectedhandler----promise) | ||
<hr> | ||
####How do long stack traces differ from e.g. Q? | ||
@@ -181,4 +380,71 @@ | ||
A better and more practical example of the differences can be seen in gorgikosev's [debuggability competition](https://github.com/spion/async-compare#debuggability). (for `--error` and `--throw`, promises don't actually need to handle `--athrow` since that is something someone using a promises would never do) | ||
A better and more practical example of the differences can be seen in gorgikosev's [debuggability competition](https://github.com/spion/async-compare#debuggability). | ||
<hr> | ||
####Can I use long stack traces in production? | ||
Probably yes. Bluebird uses multiple innovative techniques to optimize long stack traces. Even with long stack traces, it is still way faster than similarly featured implementations that don't have long stack traces enabled and about same speed as minimal implementations. A slowdown of 4-5x is expected, not 50x. | ||
What techniques are used? | ||
#####V8 API second argument | ||
This technique utilizes the [slightly under-documented](https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi#Stack_trace_collection_for_custom_exceptions) second argument of V8 `Error.captureStackTrace`. It turns out you can that the second argument can actually be used to make V8 skip all library internal stack frames [for free](https://github.com/v8/v8/blob/b5fabb9225e1eb1c20fd527b037e3f877296e52a/src/isolate.cc#L665). It only requires propagation of callers manually in library internals but this is not visible to you as user at all. | ||
Without this technique, every promise (well not every, see second technique) created would have to waste time creating and collecting library internal frames which will just be thrown away anyway. It also allows one to use smaller stack trace limits because skipped frames are not counted towards the limit whereas with collecting everything upfront and filtering afterwards would likely have to use higher limits to get more user stack frames in. | ||
#####Sharing stack traces | ||
Consider: | ||
```js | ||
function getSomethingAsync(fileName) { | ||
return readFileAsync(fileName).then(function(){ | ||
//... | ||
}).then(function() { | ||
//... | ||
}).then(function() { | ||
//... | ||
}); | ||
} | ||
``` | ||
Everytime you call this function it creates 4 promises and in a straight-forward long stack traces implementation it would collect 4 almost identical stack traces. Bluebird has a light weight internal data-structure (kcnown as context stack in the source code) to help tracking when traces can be re-used and this example would only collect one trace. | ||
#####Lazy formatting | ||
After a stack trace has been collected on an object, one must be careful not to reference the `.stack` property until necessary. Referencing the property causes | ||
an expensive format call and the stack property is turned into a string which uses much more memory. | ||
What about [Q #111](https://github.com/kriskowal/q/issues/111)? | ||
Long stack traces is not inherently the problem. For example with latest Q with stack traces disabled: | ||
```js | ||
var Q = require("q"); | ||
function test(i){ | ||
if (i <= 0){ | ||
return Q.when('done') | ||
} else { | ||
return Q.when(i-1).then(test) | ||
} | ||
} | ||
test(1000000000).then(function(output){console.log(output) }); | ||
``` | ||
After 2 minutes of running this, it will give: | ||
```js | ||
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory | ||
``` | ||
So the problem with this is how much absolute memory is used per promise - not whether long traces are enabled or not. | ||
For some purpose, let's say 100000 parallel pending promises in memory at the same time is the maximum. You would then roughly use 100MB for them instead of 10MB with stack traces disabled.For comparison, just creating 100000 functions alone will use 14MB if they're closures. All numbers can be halved for 32-bit node. | ||
<hr> | ||
#Development | ||
@@ -185,0 +451,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses eval() which is a dangerous function. This prevents the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses eval() which is a dangerous function. This prevents the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
471047
10464
580