Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

when

Package Overview
Dependencies
Maintainers
1
Versions
63
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

when - npm Package Compare versions

Comparing version 1.5.0 to 1.5.1

269

debug.js

@@ -46,7 +46,8 @@ /** @license MIT License (c) copyright B Cavalier & J Hann */

var promiseId, freeze, pending, exceptionsToRethrow, undef;
var promiseId, pending, exceptionsToRethrow, own, debugProp, undef;
promiseId = 0;
freeze = Object.freeze || function(o) { return o; };
pending = {};
own = Object.prototype.hasOwnProperty;
debugProp = 'whendebug';

@@ -61,99 +62,74 @@ exceptionsToRethrow = {

/**
* Replacement for when() that sets up debug logging on the
* returned promise.
*/
function whenDebug() {
return debugPromise(when.apply(null, wrapCallbacks(arguments)));
}
/**
* Setup debug output handlers for the supplied promise.
* @param p {Promise} A trusted (when.js) promise
* @return p
* @return {Promise} a new promise that outputs debug info and
* has a useful toString
*/
function debugPromise(p) {
// TODO: Need to find a way for promises returned by .then()
// to also be debug promises.
p.then(
undef,
function(err) {
if(p.id) {
console.error(p.toString());
} else {
console.error('[object Promise] REJECTED:', err);
}
function debugPromise(p, parent) {
var id, origThen, newPromise, logReject;
return when.reject(err);
}
);
if(own.call(p, debugProp)) {
return p;
}
return p;
}
promiseId++;
id = (parent && 'id' in parent) ? (parent.id + '.' + promiseId) : promiseId;
function wrapCallback(cb) {
if(typeof cb != 'function') {
return cb;
}
origThen = p.then;
newPromise = beget(p);
newPromise.id = id;
newPromise.parent = parent;
newPromise[debugProp] = true;
return function(v) {
try {
return cb(v);
} catch(err) {
if(err) {
if (err.name in exceptionsToRethrow) {
setTimeout(function() {
throw err;
}, 0);
} else if (err.stack) {
console.error(err.stack);
}
}
newPromise.toString = function() {
return toString('Promise', id);
};
throw err;
newPromise.then = function(cb, eb) {
if(typeof eb === 'function') {
var promise = newPromise;
do {
promise.handled = true;
} while((promise = promise.parent) && !promise.handled);
}
return debugPromise(origThen.apply(p, wrapCallbacks(arguments)), newPromise);
};
}
function wrapCallbacks(callbacks) {
var cb, args, len, i;
logReject = function() {
console.error(newPromise.toString());
};
args = [];
p.then(
function(val) {
newPromise.toString = function() {
return toString('Promise', id, 'resolved', val);
};
return val;
},
wrapCallback(function(err) {
newPromise.toString = function() {
return toString('Promise', id, 'REJECTED', err);
};
for(i = 0, len = callbacks.length; i < len; i++) {
args[i] = typeof (cb = callbacks[i]) == 'function'
? wrapCallback(cb)
: cb;
}
if(!newPromise.handled) {
logReject();
}
return args;
}
throw err;
})
);
/**
* Helper to form debug string for promises depending on their
* current state
* @param name
* @param id
* @param status
* @param value
*/
function toString(name, id, status, value) {
var s = '[object ' + name + ' ' + id + '] ' + status;
if(value !== pending) {
s += ': ' + value;
}
return s;
return newPromise;
}
function F() {}
function beget(o) {
F.prototype = o;
o = new F();
F.prototype = undef;
return o;
}
/**
* Replacement for when() that sets up debug logging on the
* returned promise.
*/
function whenDebug() {
return debugPromise(when.apply(null, wrapCallbacks(arguments)));
}
/**
* Replacement for when.defer() that sets up debug logging

@@ -184,6 +160,5 @@ * on the created Deferred, its resolver, and its promise.

// and deferred
d.promise = beget(d.promise);
d.promise.toString = function() {
return toString('Promise', id, status, value);
};
origThen = d.promise.then;
d.id = id;
d.promise = debugPromise(d.promise, d);

@@ -201,3 +176,3 @@ d.resolver = beget(d.resolver);

return origProgress.apply(undef, arguments);
return origProgress(update);
};

@@ -237,36 +212,11 @@

// Experimenting with setting up ways to also debug promises returned
// by .then(). Also need to find a way to extend the id in a way that
// makes it obvious the returned promise is NOT the original, but is
// related to it--it's downstream in the promise chain.
origThen = d.promise.then;
d.then = d.promise.then = function(cb, eb, pb) {
d.then = d.promise.then;
var id = d.id + '>' + (++promiseId);
var p = origThen.apply(null, wrapCallbacks(arguments));
p.id = id;
p = beget(p);
p.toString = function() {
return toString('Promise', p.id, status, value);
};
// See below. Not sure if debug promises should be frozen
return freeze(p);
};
// Add an id to all directly created promises. It'd be great
// to find a way to propagate this id to promise created by .then()
d.id = d.promise.id = d.resolver.id = id;
d.resolver.id = id;
// Attach debug handlers after the substitute promise
// has been setup, so the id can be logged.
//debugPromise(d.promise);
// TODO: Should we still freeze these?
// Seems safer for now to err on the side of caution and freeze them,
// but it could be useful to all them to be modified during debugging.
freeze(d.promise);
freeze(d.resolver);
// freeze(d.promise);
// freeze(d.resolver);

@@ -276,15 +226,5 @@ return d;

function alreadyResolved() {
throw new Error('already completed');
}
whenDebug.defer = deferDebug;
whenDebug.isPromise = when.isPromise;
function makeDebug(name, func) {
whenDebug[name] = function() {
return debugPromise(func.apply(when, arguments));
};
}
// For each method we haven't already replaced, replace it with

@@ -300,2 +240,81 @@ // one that sets up debug logging on the returned promise

// Wrap result of when[name] in a debug promise
function makeDebug(name, func) {
whenDebug[name] = function() {
return debugPromise(func.apply(when, arguments));
};
}
// Wrap a promise callback to catch exceptions and log or
// rethrow as uncatchable
function wrapCallback(cb) {
if(typeof cb != 'function') {
return cb;
}
return function(v) {
try {
return cb(v);
} catch(err) {
throwUncatchableIfNecessary(err);
throw err;
}
};
}
// Wrap a callback, errback, progressback tuple
function wrapCallbacks(callbacks) {
var cb, args, len, i;
args = [];
for(i = 0, len = callbacks.length; i < len; i++) {
args[i] = typeof (cb = callbacks[i]) == 'function'
? wrapCallback(cb)
: cb;
}
return args;
}
// Stringify a promise, deferred, or resolver
function toString(name, id, status, value) {
var s = '[object ' + name + ' ' + id + ']';
if(arguments.length > 2) {
s += ' ' + status;
if(value !== pending) {
s += ': ' + value;
}
}
return s;
}
function throwUncatchableIfNecessary(err) {
if (err && err.name in exceptionsToRethrow) {
setTimeout(function() {
throw err;
}, 0);
}
}
// Helper to invoke when resolve/reject/progress is called on
// an already-resolved deferred or resolver
function alreadyResolved() {
throw new Error('already completed');
}
// The usual Crockford
function F() {}
function beget(o) {
F.prototype = o;
o = new F();
F.prototype = undef;
return o;
}
});

@@ -302,0 +321,0 @@ })(typeof define == 'function'

{
"name": "when",
"version": "1.5.0",
"version": "1.5.1",
"description": "A lightweight Promise and when() implementation, plus other async goodies.",
"keywords": ["promises", "when", "async", "cujo"],
"keywords": ["promise", "promises", "deferred", "deferreds", "when", "async", "asynchronous", "cujo"],
"licenses": [

@@ -7,0 +7,0 @@ {

@@ -12,2 +12,7 @@ # when.js [![Build Status](https://secure.travis-ci.org/cujojs/when.png)](http://travis-ci.org/cujojs/when)

### 1.5.1
* Performance optimization for [when.defer](when/blob/master/docs/api.md#whendefer), up to 1.5x in some cases.
* [when/debug](when/blob/master/docs/api.md#whendebug) can now log exceptions and rejections in deeper promise chains, in some cases, even when the promises involved aren't when.js promises.
### 1.5.0

@@ -14,0 +19,0 @@

@@ -10,7 +10,7 @@ /** @license MIT License (c) copyright B Cavalier & J Hann */

*
* @version 1.5.0
* @version 1.5.1
*/
(function(define, global) {
define(['module'], function(module) { "use strict";
(function(define, global) { 'use strict';
define(['module'], function(module) {
var freeze, reduceArray, slice, envFreeze, falseRx, undef;

@@ -109,3 +109,3 @@

// See: https://github.com/kriskowal/q/issues/106
if (promiseOrValue != null && typeof promiseOrValue.valueOf === "function") {
if (promiseOrValue != null && typeof promiseOrValue.valueOf === 'function') {
promiseOrValue = promiseOrValue.valueOf();

@@ -157,3 +157,5 @@ }

*/
function Promise() {}
function Promise(then) {
this.then = then;
}

@@ -193,6 +195,3 @@ Promise.prototype = freeze({

function resolved(value) {
var p = new Promise();
p.then = function(callback) {
var p = new Promise(function(callback) {
try {

@@ -203,3 +202,3 @@ return resolve(callback ? callback(value) : value);

}
};
});

@@ -218,6 +217,3 @@ return freeze(p);

function rejected(reason) {
var p = new Promise();
p.then = function(callback, errback) {
var p = new Promise(function(callback, errback) {
try {

@@ -228,4 +224,4 @@ return errback ? resolve(errback(reason)) : rejected(reason);

}
};
});
return freeze(p);

@@ -246,7 +242,10 @@ }

function defer() {
var deferred, promise, resolver, listeners, progressHandlers,
var deferred, promise, listeners, progressHandlers,
_then, _progress, _resolve;
listeners = [];
progressHandlers = [];
/**
* The promise for the new deferred
* @type {Promise}
*/
promise = new Promise(then);

@@ -258,75 +257,21 @@ /**

*/
deferred = {};
deferred = {
then: then,
resolve: promiseResolve,
reject: promiseReject,
progress: promiseProgress,
promise: freeze(promise),
/**
* The {@link Resolver} for this {@link Deferred}
* @memberOf Deferred
* @name resolver
* @class Resolver
*/
resolver = {};
/**
* The {@link Promise} for this {@link Deferred}
* @memberOf Deferred
* @name promise
* @type {Promise}
*/
promise = new Promise();
/**
* Registers a handler for this {@link Deferred}'s {@link Promise}. Even though all arguments
* are optional, each argument that *is* supplied must be null, undefined, or a Function.
* Any other value will cause an Error to be thrown.
* @memberOf Promise
* @name then
* @param [callback] {Function} resolution handler
* @param [errback] {Function} rejection handler
* @param [progback] {Function} progress handler
* @throw {Error} if any argument is not null, undefined, or a Function
*/
promise.then = deferred.then = function then(callback, errback, progback) {
return _then(callback, errback, progback);
resolver: freeze({
resolve: promiseResolve,
reject: promiseReject,
progress: promiseProgress
})
};
deferred.promise = freeze(promise);
listeners = [];
progressHandlers = [];
/**
* Resolves this {@link Deferred}'s {@link Promise} with val as the
* resolution value.
* @memberOf Resolver
* @param val {*|Promise} If val is anything but a Promise, resolves this
* Deferred's Promise with val. If val is a Promise, puts this Deferred's
* Promise into the same state as val. For example, if val is a rejected
* promise, this Deferred will become rejected.
* @return {Promise} a promise for the resolution value
*/
resolver.resolve = deferred.resolve = function promiseResolve(val) {
return _resolve(val);
};
/**
* Rejects this {@link Deferred}'s {@link Promise} with err as the
* reason.
* @memberOf Resolver
* @param err anything
* @return {Promise} a promise for the rejection value
*/
resolver.reject = deferred.reject = function promiseReject(err) {
return _resolve(rejected(err));
};
/**
* Emits a progress update to all progress observers registered with
* this {@link Deferred}'s {@link Promise}
* @memberOf Resolver
* @param update anything
*/
resolver.progress = deferred.progress = function promiseProgress(update) {
_progress(update);
};
deferred.resolver = freeze(resolver);
/**
* Pre-resolution then() that adds the supplied callback, errback, and progback

@@ -399,2 +344,36 @@ * functions to the registered listeners

return deferred;
/**
* Wrapper to allow _then to be replaced safely
* @param [callback] {Function} resolution handler
* @param [errback] {Function} rejection handler
* @param [progback] {Function} progress handler
* @return {Promise} new Promise
* @throws {Error} if any argument is not null, undefined, or a Function
*/
function then(callback, errback, progback) {
return _then(callback, errback, progback);
}
/**
* Wrapper to allow _resolve to be replaced
*/
function promiseResolve(val) {
return _resolve(val);
}
/**
* Wrapper to allow _resolve to be replaced
*/
function promiseReject(err) {
return _resolve(rejected(err));
}
/**
* Wrapper to allow _progress to be replaced
* @param {*} update progress update
*/
function promiseProgress(update) {
_progress(update);
}
}

@@ -672,2 +651,4 @@

function(reduceFunc /*, initialValue */) {
/*jshint maxcomplexity: 7*/
// ES5 dictates that reduce.length === 1

@@ -684,3 +665,2 @@

// See https://github.com/jshint/jshint/issues/392
/*jshint newcap: false */
arr = Object(this);

@@ -687,0 +667,0 @@ len = arr.length >>> 0;

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc