@darkobits/adeiu
Advanced tools
Comparing version 0.4.2 to 0.4.3
@@ -1,3 +0,1 @@ | ||
import chalk from "chalk"; | ||
import ow from "ow"; | ||
const SIGNALS = [ | ||
@@ -11,8 +9,15 @@ "SIGINT", | ||
const signalCallbacks = /* @__PURE__ */ new Map(); | ||
function getCallbackSetForSignal(signal) { | ||
if (!signalCallbacks.has(signal)) | ||
signalCallbacks.set(signal, /* @__PURE__ */ new Set()); | ||
return signalCallbacks.get(signal); | ||
} | ||
function writeErrorToStderr(cb, signal, err) { | ||
if (err == null ? void 0 : err.stack) { | ||
const supportsColor = Boolean(process.stdout.isTTY && !process.env.NO_COLOR || process.env.FORCE_COLOR); | ||
const red = (text) => supportsColor ? `\x1B[31m${text}\x1B[0m` : text; | ||
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.red(`Error: [adeiu] ${cbName} threw:`)} ${errType}: ${err.message}`; | ||
stackLines[0] = `${red(`Error: [adeiu] ${cbName} threw:`)} ${errType}: ${err.message}`; | ||
process.stderr.write(`${stackLines.join("\n")} | ||
@@ -23,16 +28,15 @@ `); | ||
async function handler(signal) { | ||
const callbacksForSignal = signalCallbacks.get(signal); | ||
if (!callbacksForSignal || callbacksForSignal.length === 0) { | ||
const callbackSetForSignal = getCallbackSetForSignal(signal); | ||
if (callbackSetForSignal.size === 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) => { | ||
let anyFailed = false; | ||
await Promise.all([...callbackSetForSignal].map(async (cb) => { | ||
try { | ||
await cb(signal); | ||
return true; | ||
} catch (err) { | ||
anyFailed = true; | ||
writeErrorToStderr(cb, signal, err); | ||
return false; | ||
} | ||
})); | ||
if (results.includes(false)) { | ||
if (anyFailed) { | ||
process.exit(1); | ||
@@ -44,26 +48,24 @@ } else { | ||
function adeiu(cb, { signals = [] } = {}) { | ||
ow(signals, "signals", ow.array.ofType(ow.string)); | ||
const finalSignals = signals.length > 0 ? signals : SIGNALS; | ||
finalSignals.forEach((signal) => { | ||
const callbacksForSignal = signalCallbacks.get(signal); | ||
if (!callbacksForSignal || callbacksForSignal.length === 0) { | ||
signalCallbacks.set(signal, [cb]); | ||
signals.forEach((signal) => { | ||
if (typeof signal !== "string") | ||
throw new TypeError(`Expected signal to be of type "string", got "${typeof signal}".`); | ||
if (!signal.startsWith("SIG")) | ||
throw new Error(`Invalid signal: ${signal}`); | ||
}); | ||
const resolvedSignals = signals.length > 0 ? signals : SIGNALS; | ||
resolvedSignals.forEach((signal) => { | ||
const callbackSetForSignal = getCallbackSetForSignal(signal); | ||
if (callbackSetForSignal.size === 0) { | ||
process.prependListener(signal, handler); | ||
} else { | ||
signalCallbacks.set(signal, [...callbacksForSignal, cb]); | ||
} | ||
callbackSetForSignal.add(cb); | ||
}); | ||
return () => { | ||
finalSignals.forEach((signal) => { | ||
const callbacksForSignal = signalCallbacks.get(signal); | ||
if (!callbacksForSignal || callbacksForSignal.length === 0) { | ||
return; | ||
} | ||
if (callbacksForSignal.length === 1 && callbacksForSignal[0] === cb) { | ||
signalCallbacks.set(signal, []); | ||
for (const signal of resolvedSignals) { | ||
const callbackSetForSignal = getCallbackSetForSignal(signal); | ||
callbackSetForSignal.delete(cb); | ||
if (callbackSetForSignal.size === 0) { | ||
process.removeListener(signal, handler); | ||
} else { | ||
signalCallbacks.set(signal, callbacksForSignal.filter((curCallback) => curCallback !== cb)); | ||
} | ||
}); | ||
} | ||
}; | ||
@@ -70,0 +72,0 @@ } |
{ | ||
"name": "@darkobits/adeiu", | ||
"version": "0.4.2", | ||
"version": "0.4.3", | ||
"description": "Yet another POSIX signal handler.", | ||
@@ -10,3 +10,3 @@ "license": "Hippocratic", | ||
"type": "git", | ||
"url": "https://github.com/darkobits/adeiu.git" | ||
"url": "git+https://github.com/darkobits/adeiu.git" | ||
}, | ||
@@ -23,7 +23,2 @@ "engines": { | ||
}, | ||
"dependencies": { | ||
"@darkobits/interop-import-default": "^1.0.0", | ||
"chalk": "^5.4.1", | ||
"ow": "^1.1.1" | ||
}, | ||
"devDependencies": { | ||
@@ -30,0 +25,0 @@ "@darkobits/ts": "0.24.0", |
@@ -46,9 +46,8 @@ <p align="center"> | ||
* Ensures provided functions are called before any other event listeners and are run concurrently, | ||
* Ensures provided handlers are called before any other event listeners and are run concurrently, | ||
minimizing shutdown time. | ||
* Works with any combination of synchronous and asynchronous functions. | ||
* Ensures a clean exit if all functions resolve/return. | ||
* Exits with an error if any functions reject/throw. | ||
* Ensures processes exit cleanly, even when they have asynchronous shut-down functions and the Node | ||
debugger is in use. (See [this issue](https://github.com/nodejs/node/issues/7742)) | ||
* Exits with code `0` if all handlers resolve/return. | ||
* Exits with an `AggregateError` if any handler rejects/throws. | ||
* Supports edge cases related to the Node debugger being attached to a process. (See [this issue](https://github.com/nodejs/node/issues/7742)) | ||
@@ -55,0 +54,0 @@ ## Install |
Sorry, the diff of this file is not supported yet
28901
0
100
125
- Removedchalk@^5.4.1
- Removedow@^1.1.1
- Removed@darkobits/interop-import-default@1.0.0(transitive)
- Removed@sindresorhus/is@5.6.0(transitive)
- Removedcallsites@4.2.0(transitive)
- Removedchalk@5.4.1(transitive)
- Removeddot-prop@7.2.0(transitive)
- Removedlodash.isequal@4.5.0(transitive)
- Removedow@1.1.1(transitive)
- Removedtype-fest@2.19.0(transitive)
- Removedvali-date@1.0.0(transitive)