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

parley

Package Overview
Dependencies
Maintainers
2
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

parley - npm Package Compare versions

Comparing version 3.4.4 to 3.5.0-0

1

lib/parley.js

@@ -260,2 +260,3 @@ /**

methodName === '_hasFinishedExecuting' ||
methodName === '_hasStartedButNotFinishedAfterExecLC' ||
methodName === '_hasAlreadyWaitedAtLeastOneTick' ||

@@ -262,0 +263,0 @@ methodName === '_skipImplSpinlockWarning' ||

510

lib/private/Deferred.js

@@ -227,3 +227,3 @@ /**

console.warn(
'WARNING: Consistency violation: Trying to trigger timeout, but after execution has\n'+
'WARNING: Consistency violation: Trying to trigger timeout, but execution has\n'+
'already finished! This should not be possible, and the fact that you\'re seeing\n'+

@@ -243,6 +243,6 @@ 'this message indicates that there is probably a bug somewhere in the tools -- or\n'+

return;
}
}//•
if (self._hasTimedOut) {
console.warn(
'WARNING: Consistency violation: Trying to trigger timeout again, after it has already\n'+
'WARNING: Consistency violation: Trying to trigger timeout again after it has already\n'+
'been triggered! This should not be possible, and the fact that you\'re seeing\n'+

@@ -262,3 +262,3 @@ 'this message indicates that there is probably a bug somewhere in the tools -- or\n'+

return;
}
}//•
self._hasTimedOut = true;

@@ -406,6 +406,9 @@ var err = flaverr({

// Use `self._hasAlreadyWaitedAtLeastOneTick` to track whether or not this logic is asynchronous.
if (self._hasFinishedExecuting) {
// IWMIH and we've already finished running `handleExec`, then we know
// Use `self._hasAlreadyWaitedAtLeastOneTick` to track whether or not this
// Deferred's logic is holistically asynchronous.
if (self._hasFinishedExecuting && !self._hasStartedButNotFinishedAfterExecLC) {
// IWMIH then we've already finished running `handleExec`, and we know
// it must have been composed purely of blocking (i.e. synchronous) logic.
// We also know there isn't an actively-running asynchronous afterExec LC
// gumming up the works.
self._hasAlreadyWaitedAtLeastOneTick = false;

@@ -417,2 +420,4 @@ }

// (Or possibly a bug where the callback isn't getting called -_-)
// OR possibly a long-running, asynchronous afterExec LC that hasn't finished
// yet.
self._hasAlreadyWaitedAtLeastOneTick = true;

@@ -542,3 +547,37 @@ }

/**
* .retry()
*
* Attach an exponential backoff and retry strategy for this invocation.
*
* > See `bindUserlandAfterExecLC` utility for details on how this works.
*
* > WARNING: Please be sure that the function being wrapped is idempotent, or
* > at least that you very, very clearly understand what you're doing before
* > using this function!
*
* @throws {Error} If already begun executing
*/
Deferred.prototype.retry = function (negotiationRuleOrWildcardHandler){
if (this._hasBegunExecuting) {
throw flaverr({
name:
'UsageError',
message:
'Could not attach exponential backoff & retry strategy with `.retry()` because\n'+
'this invocation has already '+(this._hasTimedOut?'timed out':this._hasFinishedExecuting?'finished executing':'begun executing')+'.'
}, this._omen);
}
this._errorsThatCausedRetries = [];
this._retryDelaySeries = [100, 200, 400];
bindUserlandAfterExecLC('retry', negotiationRuleOrWildcardHandler, undefined, this);
return this;
};
/**
* .toPromise()

@@ -689,72 +728,39 @@ *

// /**
// * .timeout()
// *
// * Set a timeout for this invocation (i.e. from userland).
// *
// * > Note: This works by reusing/overriding the implementor-land `_timeout` property.
// *
// * @param {Number} ms [number of milliseconds to wait for execution to finish before considering this timed out]
// * @throws {Error} If already begun executing
// */
// Deferred.prototype.timeout = function (ms){
// if (!_.isNumber(ms)) {
// throw flaverr({
// name:
// 'UsageError',
// message:
// 'Invalid usage for `.timeout()`. Please provide a number of milliseconds\n'+
// 'as the first argument, or use 0 to eliminate the timeout for this invocation.'
// }, this._omen);
// }
/**
* .timeout()
*
* Set a timeout for this invocation (i.e. from userland).
*
* > Note: This works by reusing/overriding the implementor-land `_timeout` property.
*
* @param {Number} ms [number of milliseconds to wait for execution to finish before considering this timed out]
* @throws {Error} If already begun executing
*/
Deferred.prototype.timeout = function (ms){
if (!_.isNumber(ms)) {
throw flaverr({
name:
'UsageError',
message:
'Invalid usage for `.timeout()`. Please provide a number of milliseconds\n'+
'as the first argument, or use 0 to eliminate the timeout for this invocation.'
}, this._omen);
}
// if (this._hasBegunExecuting) {
// throw flaverr({
// name:
// 'UsageError',
// message:
// 'Could not attach max milliseconds with `.timeout()` because this invocation\n'+
// 'has already '+(this._hasTimedOut?'timed out':this._hasFinishedExecuting?'finished executing':'begun executing')+'.'
// }, this._omen);
// }
if (this._hasBegunExecuting) {
throw flaverr({
name:
'UsageError',
message:
'Could not attach max milliseconds with `.timeout()` because this invocation\n'+
'has already '+(this._hasTimedOut?'timed out':this._hasFinishedExecuting?'finished executing':'begun executing')+'.'
}, this._omen);
}
// this._timeout = ms;
this._timeout = ms;
// return this;
// };
return this;
};
// /**
// * .retry()
// *
// * Attach an exponential backoff and retry strategy for this invocation.
// *
// * > See `bindUserlandAfterExecLC` utility for details on how this works.
// *
// * > WARNING: Please be sure that the function being wrapped is idempotent, or
// * > at least that you very, very clearly understand what you're doing before
// * > using this function!
// *
// * @throws {Error} If already begun executing
// */
// Deferred.prototype.retry = function (negotiationRuleOrWildcardHandler){
// if (this._hasBegunExecuting) {
// throw flaverr({
// name:
// 'UsageError',
// message:
// 'Could not attach exponential backoff & retry strategy with `.retry()` because\n'+
// 'this invocation has already '+(this._hasTimedOut?'timed out':this._hasFinishedExecuting?'finished executing':'begun executing')+'.'
// }, this._omen);
// }
// this._errorsThatCausedRetries = [];
// this._retryDelaySeries = [100, 200, 400];
// bindUserlandAfterExecLC('retry', negotiationRuleOrWildcardHandler, undefined, this);
// return this;
// };
// Attach `inspect`, `toString`, and `toJSON` functions

@@ -836,3 +842,3 @@ // (This is mainly to hide the `_omen` property, which is pretty scary-looking)

return;
}
}//•

@@ -851,7 +857,4 @@ // Clear timeout, if relevant.

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
self._hasFinishedExecuting = true;
} else {
// IWMIH, there was no error.
self._hasFinishedExecuting = true;
}//fi
self._hasFinishedExecuting = true;
return proceedToInterceptsAndChecks(errCbArg, resultCbArg, extraCbArgs, self, _cb, handleUncaughtException);

@@ -924,195 +927,175 @@ }//ƒ </proceedToAfterExecSpinlocks>

// > Note that this is only relevant if there was an error of some kind.
try {
if (self._userlandAfterExecLCs && errCbArg) {
if (!(self._userlandAfterExecLCs && errCbArg)) {
return proceedToFinalAfterExecLC(errCbArg, resultCbArg, extraCbArgs, self, _cb, handleUncaughtException);
} else {//• </ else there are no userland LCs or we didn't get an error >
// Now before proceeding further, check for a match (if there are any configured).
// > NOTE: We only ever run one of these handlers for any given response!
var matchingUserlandLC;
for (var i = 0; i < self._userlandAfterExecLCs.length; i++) {
var lcDef = self._userlandAfterExecLCs[i];
if (lcDef.rule === undefined) {
matchingUserlandLC = lcDef;
break;
} else if (flaverr.taste(lcDef.rule, errCbArg)) {
matchingUserlandLC = lcDef;
break;
}
}//∞
// Now before proceeding further, check for a match (if there are any configured).
// Unless we have a match, go ahead and bail.
// > NOTE: We only ever run one of these handlers for any given response!
var matchingUserlandLC;
for (var i = 0; i < self._userlandAfterExecLCs.length; i++) {
var lcDef = self._userlandAfterExecLCs[i];
if (lcDef.rule === undefined) {
matchingUserlandLC = lcDef;
break;
} else if (flaverr.taste(lcDef.rule, errCbArg)) {
matchingUserlandLC = lcDef;
break;
}
}//∞
if (!matchingUserlandLC) {
return proceedToFinalAfterExecLC(errCbArg, resultCbArg, extraCbArgs, self, _cb, handleUncaughtException);
}//• </ if there is no matching userland LC >
// Now, if we have a match...
if (matchingUserlandLC) {
(function(proceed){
// Get reasonable default for handler, if no explicit handler function was configured.
if (matchingUserlandLC.handler === undefined && matchingUserlandLC.type === 'tolerate') {
matchingUserlandLC.handler = function(){ return; };
}
else if (matchingUserlandLC.handler === undefined && matchingUserlandLC.type === 'intercept') {
matchingUserlandLC.handler = function(err){ return err; };
}
// Get reasonable default for handler, if no explicit handler function was configured.
if (matchingUserlandLC.handler === undefined && matchingUserlandLC.type === 'tolerate') {
matchingUserlandLC.handler = function(){ return; };
}
else if (matchingUserlandLC.handler === undefined && matchingUserlandLC.type === 'intercept') {
matchingUserlandLC.handler = function(err){ return err; };
}
// Run userland LC.
// Run userland LC.
self._hasStartedButNotFinishedAfterExecLC = true;
if (matchingUserlandLC.handler.constructor.name !== 'AsyncFunction') {
var resultFromHandler;
try {
resultFromHandler = matchingUserlandLC.handler(errCbArg);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// FUTURE: add support for this, beginning with something like the
// following incomplete implementation:
//
// ```
// if (matchingUserlandLC.handler.constructor.name === 'AsyncFunction') {
// var interceptPromise;
// try {
// interceptPromise = matchingLifecycleInstruction.handler();
// } catch (err) {
// if (err === false) { return proceed(undefined, true); }//« special case (`throw false`)
// else { return proceed(err); }
// }
//
// interceptPromise.then(function(_resultFromHandler){
// resultFromHandler = _resultFromHandler;
// proceed(undefined, resultFromHandler);
// });
// interceptPromise.catch(function(err) {
// /* eslint-disable callback-return */
// if (err === false) { proceed(undefined, true); }//« special case (`throw false`)
// else { proceed(err); }
// /* eslint-enable callback-return */
// });
// }
// else {
// resultFromHandler = matchingUserlandLC.handler(errCbArg);
// }
// ```
//
// *** Don't forget to update bindUserlandAfterExecLC to remove the
// check that displays an error message instead of allowing this usage! ***
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
} catch (err) {
} catch (err) { return proceed(err); }
return proceed(undefined, resultFromHandler);
} else {
var lcPromise;
try {
lcPromise = matchingUserlandLC.handler(errCbArg);
} catch (err) { return proceed(err); }
lcPromise.then(function(resultFromHandler){
proceed(undefined, resultFromHandler);
}).catch(function(err){
proceed(err);
});//_∏_
}
})(function(err, resultFromHandler){
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// FUTURE: (Maybe) Specifically for `.tolerate()`, allow throwing special exit signals
// from within the handler.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Clear spinlock.
self._hasStartedButNotFinishedAfterExecLC = false;
// If this is an .intercept() handler, then it's possible the handler threw on purpose,
// perhaps because it was attempting to send a special signal to its caller (e.g. the
// implementation of an action/helper/etc) where it presumably has a special meaning.
// So in this case, we customize the error message to reflect that possibility and to
// suggest an appropriate resolution.
if (matchingUserlandLC.type === 'intercept') {
throw flaverr({
name:
'UsageError',
message:
'Caught unexpected error in `.intercept()` handler, which should not throw:\n'+
flaverr.parseOrBuildError(err).message+'\n'+
'If this was intentional, i.e. to communicate a signal to the caller, then\n'+
'please just return the new or modified error you would like to use instead.\n'+
'The value returned to `.intercept()` will be used as the new Error.\n'+
' [?] See https://sailsjs.com/support for help.',
raw:
err
}, self._omen);
}
else {
// Otherwise, we'll just consider this a standard unexpected error:
throw flaverr({
name:
'UsageError',
message:
'Encountered unexpected error in `.'+matchingUserlandLC.type+'()` handler. '+
flaverr.parseOrBuildError(err).message+'\n'+
' [?] See https://sailsjs.com/support for help.',
raw:
err
}, self._omen);
}
}//ç
if (err) {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// FUTURE: (Maybe) Specifically for `.tolerate()`, allow throwing special exit signals
// from within the handler.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// If this is an .intercept() handler, then it's possible the handler threw on purpose,
// perhaps because it was attempting to send a special signal to its caller (e.g. the
// implementation of an action/helper/etc) where it presumably has a special meaning.
// So in this case, we customize the error message to reflect that possibility and to
// suggest an appropriate resolution.
if (matchingUserlandLC.type === 'intercept') {
return proceedToFinalAfterExecLC(flaverr({
name:
'UsageError',
message:
'Caught unexpected error in `.intercept()` handler, which should not throw:\n'+
flaverr.parseOrBuildError(err).message+'\n'+
'If this was intentional, i.e. to communicate a signal to the caller, then\n'+
'please just return the new or modified error you would like to use instead.\n'+
'The value returned to `.intercept()` will be used as the new Error.\n'+
' [?] See https://sailsjs.com/support for help.',
raw:
err
}, self._omen), resultCbArg, extraCbArgs, self, _cb, handleUncaughtException);
}
else {
// Otherwise, we'll just consider this a standard unexpected error:
return proceedToFinalAfterExecLC(flaverr({
name:
'UsageError',
message:
'Encountered unexpected error in `.'+matchingUserlandLC.type+'()` handler. '+
flaverr.parseOrBuildError(err).message+'\n'+
' [?] See https://sailsjs.com/support for help.',
raw:
err
}, self._omen), resultCbArg, extraCbArgs, self, _cb, handleUncaughtException);
}
}//•
// Now swallow or swap out the error, if instructed to do so.
// Now swallow or swap out the error, if instructed to do so.
// Swallow:
// > i.e. if a matching `.tolerate()` was encountered, then consider
// > this successful no matter what, and use the value returned by the
// > LC as the new result.
if (matchingUserlandLC.type === 'tolerate') {
errCbArg = undefined;
resultCbArg = resultFromHandler;
}
// Swap:
//
// > i.e. if a matching `.intercept()` was encountered, then consider
// > whatever the intercept handler returned to be our new Error.
else if (matchingUserlandLC.type === 'intercept') {
// Swallow:
// > i.e. if a matching `.tolerate()` was encountered, then consider
// > this successful no matter what, and use the value returned by the
// > LC as the new result.
if (matchingUserlandLC.type === 'tolerate') {
errCbArg = undefined;
resultCbArg = resultFromHandler;
}
// Swap:
//
// > i.e. if a matching `.intercept()` was encountered, then consider
// > whatever the intercept handler returned to be our new Error.
else if (matchingUserlandLC.type === 'intercept') {
// If the handler returned `undefined`, then fail with an error.
// (this shouldn't happen, an indicates invalid usage)
if (resultFromHandler === undefined) {
throw flaverr({
name:
'UsageError',
message:
'`.intercept()` handler returned `undefined`, but this should never happen.\n'+
'Regardless, here is a summary of the original underlying error:\n'+
flaverr.parseOrBuildError(errCbArg).message+'\n'+
' [?] See https://sailsjs.com/support for help.',
raw:
errCbArg
}, self._omen);
}
// If the handler returned `undefined`, then fail with an error.
// (this shouldn't happen, an indicates invalid usage)
if (resultFromHandler === undefined) {
return proceedToFinalAfterExecLC(flaverr({
name:
'UsageError',
message:
'`.intercept()` handler returned `undefined`, but this should never happen.\n'+
'Regardless, here is a summary of the original underlying error:\n'+
flaverr.parseOrBuildError(errCbArg).message+'\n'+
' [?] See https://sailsjs.com/support for help.',
raw:
errCbArg
}, self._omen), resultCbArg, extraCbArgs, self, _cb, handleUncaughtException);
}//•
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Normally, these errors must ALWAYS be Error instances already.
// But for this special case, where the original Error value
// is being overridden through the use of `.intercept()`, we'd
// LIKE to make a special exception to the rule (no pun intended.)
//
// There's only one problem: Because of bluebird's "maybeWrapAsError"
// implementation, we can't send certain non-Errors through to it
// (specifically primitives) because they get autowrapped.
//
// > Here's the relevant bit of code:
// > https://github.com/petkaantonov/bluebird/blob/e8d8525a0517280d11d6c77ae6b61df86419232b/src/promisify.js#L182-L184
//
// Again, most of the time, this would be fine. But while bluebird's
// looking out for us here is admirable, there are some situations.
// where this is not welcome -- such as when trying to throw a string.
//
// > Why throw a string?
// > This is useful for throwing special signals-- e.g. from the inside
// > of an actions2 action or a helper in Sails, a machine's fn in a
// > machinepack, or from a commandline script.
//
// So anyway, to work around this, we have to come up with a consistent
// way of wrapping up non-Errors to look like Errors. That's what we
// do next.
//
// ** Note that we also do this in a couple of other places in parley. **
// ** (look for `flaverr.parseOrBuildError()` calls) **
//
// > (If ever we find ourselves wanting to revert this approach, the old
// > code that used to check for non-Errors was removed in parley@376208fd1c0ab70e7a6b9c4ecfa563ec0d77a3a8.
// > But... as mentioned above-- there are some good reasons to keep things
// > the new way that they are now.)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Normally, these errors must ALWAYS be Error instances already.
// But for this special case, where the original Error value
// is being overridden through the use of `.intercept()`, we'd
// LIKE to make a special exception to the rule (no pun intended.)
//
// There's only one problem: Because of bluebird's "maybeWrapAsError"
// implementation, we can't send certain non-Errors through to it
// (specifically primitives) because they get autowrapped.
//
// > Here's the relevant bit of code:
// > https://github.com/petkaantonov/bluebird/blob/e8d8525a0517280d11d6c77ae6b61df86419232b/src/promisify.js#L182-L184
//
// Again, most of the time, this would be fine. But while bluebird's
// looking out for us here is admirable, there are some situations.
// where this is not welcome -- such as when trying to throw a string.
//
// > Why throw a string?
// > This is useful for throwing special signals-- e.g. from the inside
// > of an actions2 action or a helper in Sails, a machine's fn in a
// > machinepack, or from a commandline script.
//
// So anyway, to work around this, we have to come up with a consistent
// way of wrapping up non-Errors to look like Errors. That's what we
// do next.
//
// ** Note that we also do this in a couple of other places in parley. **
// ** (look for `flaverr.parseOrBuildError()` calls) **
//
// > (If ever we find ourselves wanting to revert this approach, the old
// > code that used to check for non-Errors was removed in parley@376208fd1c0ab70e7a6b9c4ecfa563ec0d77a3a8.
// > But... as mentioned above-- there are some good reasons to keep things
// > the new way that they are now.)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var interceptError = flaverr.parseOrBuildError(resultFromHandler, self._omen);
errCbArg = interceptError;
var interceptError = flaverr.parseOrBuildError(resultFromHandler, self._omen);
errCbArg = interceptError;
}//fi </ if this is an .intercept() >
}//fi </ if this is an .intercept() >
}//fi </ if there is a matching userland LC >
}//fi </ if we got an error AND any userland LCs were provided >
} catch (err) {
// If any error was encountered above, then stuff it in `errCbArg` so
// that it can still be handled gracefully-- including getting any final
// treatment from implementorland's `finalAfterExecLC`.
errCbArg = err;
}
return proceedToFinalAfterExecLC(errCbArg, resultCbArg, extraCbArgs, self, _cb, handleUncaughtException);
// Continue to the final bits (note: only reason we didn't use an IIFE here is for performance)
return proceedToFinalAfterExecLC(errCbArg, resultCbArg, extraCbArgs, self, _cb, handleUncaughtException);
});//_∏_ (†)
}//fi
}//ƒ </ definition of `proceedToInterceptsAndChecks` >

@@ -1231,6 +1214,2 @@

} catch (unexpectedErrorFromCallback) {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// FUTURE: expand the "if" conditional that determines synchronousness to
// support the possibility of asynchronous userland after-exec LCs
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
throw flaverr.wrap({

@@ -1276,3 +1255,4 @@ code: 'E_ESCAPE_HATCH',

*
* Used exclusively by `Deferred.prototype.intercept()` & `.tolerate()`, this function is an optimization.
* Used exclusively by `Deferred.prototype.intercept()`, `Deferred.prototype.tolerate()`,
* and `Deferred.prototype.retry()`, this function is an optimization.
* It would be much better to use an IIFE instead of defining this function, but we're

@@ -1314,20 +1294,6 @@ * dealing with a very hot code path, so the performance gain is worth it.

'Invalid usage of `.'+lcType+'()`. Provided handler function is invalid.\n'+
' [?] See https://sailsjs.com/support for help.'
' [?] For advice or assistance, come visit https://sailsjs.com/support'
}, deferred._omen);
}//•
if (handler !== undefined && handler.constructor.name === 'AsyncFunction') {
throw flaverr({
name:
'UsageError',
message:
'`async` functions are not currently supported for `.'+lcType+'()` '+
'handlers, so please stick to synchronous logic for now. In the mean time, if you '+
'need to use asynchronous logic while intercepting or tolerating an error (such as '+
'additional database queries or HTTP requests) you can still accomplish this '+
'by refactoring your code.\n'+
' [?] For advice or assistance, come visit https://sailsjs.com/support'
});
}//•
if (handler === undefined && lcType === 'intercept') {

@@ -1334,0 +1300,0 @@ throw flaverr({

{
"name": "parley",
"version": "3.4.4",
"version": "3.5.0-0",
"description": "Practical, lightweight flow control for Node.js. Supports `await`, callbacks and promises.",

@@ -5,0 +5,0 @@ "main": "lib/parley.js",

Sorry, the diff of this file is not supported yet

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