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

@darkobits/adeiu

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@darkobits/adeiu - npm Package Compare versions

Comparing version 0.2.2 to 0.2.3

4

CHANGELOG.md

@@ -5,2 +5,6 @@ # Changelog

### [0.2.3](https://github.com/darkobits/adeiu/compare/v0.2.2...v0.2.3) (2019-06-29)
### [0.2.2](https://github.com/darkobits/adeiu/compare/v0.2.1...v0.2.2) (2019-06-07)

@@ -7,0 +11,0 @@

189

dist/adeiu.js
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = adeiu;
exports.SIGNALS = void 0;
var _chalk = _interopRequireDefault(require("chalk"));
var _ow = _interopRequireDefault(require("ow"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const SIGNALS = ['SIGINT', 'SIGQUIT', 'SIGTERM', 'SIGUSR2'];
exports.SIGNALS = SIGNALS;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const chalk_1 = __importDefault(require("chalk"));
const ow_1 = __importDefault(require("ow"));
/**
* List of default POSIX signals to register handlers for.
*/
exports.SIGNALS = [
'SIGINT',
'SIGQUIT',
'SIGTERM',
'SIGUSR2'
];
/**
* Tracks which signals we have registered process listeners for, and which user
* callbacks should be invoked for each signal.
*/
const signalCallbacks = new Map();
/**
* Provided an `adeiu` callback and an error it threw, logs the error to
* stderr.
*
* @example
*
* const myCallback = () => {
* throw new TypeError('Oh noes!');
* };
*
* ```
* Error: [adeiu] SIGINT handler `myCallback` threw: TypeError: Oh noes!
* at myCallback (foo.js:42:3)
* ```
*/
function writeErrorToStderr(cb, signal, err) {
if (err && err.stack) {
const errType = err.constructor ? err.constructor.name : 'Error';
const cbName = cb.name ? `${signal} handler \`${cb.name}\`` : 'Anonymous callback';
const stackLines = err.stack.split('\n');
stackLines[0] = `${_chalk.default.red(`Error: [adeiu] ${cbName} threw:`)} ${errType}: ${err.message}`;
process.stderr.write(`${stackLines.join('\n')}\n`);
}
if (err && err.stack) {
const errType = err.constructor ? err.constructor.name : 'Error';
const cbName = cb.name ? `${signal} handler \`${cb.name}\`` : 'Anonymous callback';
const stackLines = err.stack.split('\n');
stackLines[0] = `${chalk_1.default.red(`Error: [adeiu] ${cbName} threw:`)} ${errType}: ${err.message}`;
process.stderr.write(`${stackLines.join('\n')}\n`);
}
}
/**
* Common signal handler; concurrently calls each callback registered for the
* provided signal. If any callbacks throw or reject, the process will exit with
* code 1.
*/
async function handler(signal) {
const callbacksForSignal = signalCallbacks.get(signal);
if (!callbacksForSignal || callbacksForSignal.length === 0) {
throw new Error(`Unexpected error: Expected at least 1 callback for signal ${signal}, but found none.`);
}
const results = await Promise.all(callbacksForSignal.map(async cb => {
try {
await cb(signal);
return true;
} catch (err) {
writeErrorToStderr(cb, signal, err);
return false;
}
}));
if (results.includes(false)) {
process.exit(1);
} else {
process.kill(process.pid, signal);
}
}
function adeiu(cb, {
signals = []
} = {}) {
(0, _ow.default)(signals, 'signals', _ow.default.array);
const finalSignals = signals.length > 0 ? signals : SIGNALS;
finalSignals.forEach(signal => {
// Get an array of user callbacks we need to invoke for the provided signal.
const callbacksForSignal = signalCallbacks.get(signal);
// If this occurs, it means there is an error in our handler (un)installation
// logic.
if (!callbacksForSignal || callbacksForSignal.length === 0) {
signalCallbacks.set(signal, [cb]);
process.prependOnceListener(signal, handler);
} else {
signalCallbacks.set(signal, [...callbacksForSignal, cb]);
throw new Error(`Unexpected error: Expected at least 1 callback for signal ${signal}, but found none.`);
}
});
return () => {
// Map our array of functions into an array of promises that will resolve with
// `true` if the function returns/resolves and `false` if the function throws
// or rejects.
const results = await Promise.all(callbacksForSignal.map(async (cb) => {
try {
await cb(signal);
return true;
}
catch (err) {
writeErrorToStderr(cb, signal, err);
return false;
}
}));
if (results.includes(false)) {
// If any functions threw/rejected, exit with code 1.
process.exit(1);
}
else {
// N.B. We use process.kill() here rather than process.exit() because it
// causes any potential Node debuggers that are attached to detach from the
// process so that it can cleanly exit.
process.kill(process.pid, signal);
}
}
/**
* Provided a function, registers a callback with several common POSIX signals
* that will invoke the function upon receipt of any of the signals.
*
* Returns a function that, when invoked, will unregister the callback.
*/
function adeiu(cb, { signals = [] } = {}) {
// Validate options.
ow_1.default(signals, 'signals', ow_1.default.array);
// If the user provided a custom list of signals, use it. Otherwise, use the
// default list.
const finalSignals = signals.length > 0 ? signals : exports.SIGNALS;
finalSignals.forEach(signal => {
const callbacksForSignal = signalCallbacks.get(signal);
if (!callbacksForSignal || callbacksForSignal.length === 0) {
return;
}
if (callbacksForSignal.length === 1 && callbacksForSignal[0] === cb) {
signalCallbacks.set(signal, []);
process.off(signal, handler);
} else {
signalCallbacks.set(signal, callbacksForSignal.filter(curCallback => curCallback !== cb));
}
const callbacksForSignal = signalCallbacks.get(signal);
if (!callbacksForSignal || callbacksForSignal.length === 0) {
signalCallbacks.set(signal, [cb]);
// Since this is the first callback being registered for this signal,
// install our handler for it.
process.prependOnceListener(signal, handler);
}
else {
signalCallbacks.set(signal, [...callbacksForSignal, cb]);
}
});
};
return () => {
finalSignals.forEach(signal => {
const callbacksForSignal = signalCallbacks.get(signal);
if (!callbacksForSignal || callbacksForSignal.length === 0) {
// User may have alreay called this function previously.
return;
}
if (callbacksForSignal.length === 1 && callbacksForSignal[0] === cb) {
signalCallbacks.set(signal, []);
// This means we are un-registering the last remaining callback for this
// signal, so uninstall our handler for it.
process.off(signal, handler);
}
else {
signalCallbacks.set(signal, callbacksForSignal.filter(curCallback => curCallback !== cb));
}
});
};
}
//# sourceMappingURL=adeiu.js.map
exports.default = adeiu;
{
"name": "@darkobits/adeiu",
"version": "0.2.2",
"version": "0.2.3",
"description": "Yet another POSIX signal handler.",

@@ -50,8 +50,8 @@ "license": "WTFPL",

"chalk": "^2.4.2",
"ow": "^0.12.0"
"ow": "^0.13.2"
},
"devDependencies": {
"@darkobits/ts-unified": "^1.6.0",
"@types/jest": "^24.0.13",
"@types/node": "^11.13.13",
"@darkobits/ts-unified": "^2.1.4",
"@types/jest": "^24.0.15",
"@types/node": "^11.13.15",
"emittery": "^0.4.1",

@@ -58,0 +58,0 @@ "p-wait-for": "^3.1.0"

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