@ylcnfrht/enhanced-abort-controller is an AbortController with the parts of .NET’s CancellationTokenSource that the platform doesn’t have: a deadline you can move, callbacks you can unregister, linked controllers that clean up after themselves, and a TimeSpan type.
The key design rule of 2.0: controller.signal is a real AbortSignal. EnhancedAbortController extends AbortController, so every API that takes a signal (fetch, fs/promises, streams, timers/promises, AbortSignal.any, database drivers) accepts it unchanged.
import {
classEnhancedAbortController
An AbortController with .NET CancellationTokenSource features. It is an AbortController,
and controller.signal is a real AbortSignal: pass it to fetch, AbortSignal.any, streams,
timers and any other API that takes a signal.
True for every way an aborted operation fails: this library's
AbortError
, and any error
named AbortError or TimeoutError (the DOMExceptions that fetch, AbortSignal.timeout,
abortAfter and throwIfAborted produce).
@example
try {
awaitfetch(url, { signal: controller.signal });
} catch (error) {
if (isAbortError(error)) return; // cancelled or timed out
throw error;
}
isAbortError,
functionisTimeoutError(error:unknown):boolean
True if error is a timeout: a TimeoutError from abortAfter, timeout() or AbortSignal.timeout,
also when wrapped: Node core APIs (fs/promises, timers/promises, streams, events.once) reject with an
AbortError whose cause is the signal's reason.
An AbortController with .NET CancellationTokenSource features. It is an AbortController,
and controller.signal is a real AbortSignal: pass it to fetch, AbortSignal.any, streams,
timers and any other API that takes a signal.
Aborts after delay, like .NET's CancelAfter: calling it again replaces the previous schedule,
and Infinity / -1 / TimeSpan.infinite cancel it. The reason is a DOMException named
TimeoutError, as with AbortSignal.timeout. The timer never keeps the process alive, and delays
longer than 24.8 days work. Does nothing once aborted. Returns the controller, for chaining.
@throws ― RangeError for NaN, negative (other than -1) or non-numeric delays.
@throws ― Error if the controller was disposed.
abortAfter(
classTimeSpan
An immutable time interval, stored in milliseconds. Modeled on .NET's TimeSpan.
The controller's signal: a real AbortSignal, always the same object.
signal });
var console:Console
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(newError('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
True for every way an aborted operation fails: this library's
AbortError
, and any error
named AbortError or TimeoutError (the DOMExceptions that fetch, AbortSignal.timeout,
abortAfter and throwIfAborted produce).
@example
try {
awaitfetch(url, { signal: controller.signal });
} catch (error) {
if (isAbortError(error)) return; // cancelled or timed out
throw error;
}
isAbortError(
var error:unknown
error)) throw
var error:unknown
error;
var console:Console
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(newError('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
True if error is a timeout: a TimeoutError from abortAfter, timeout() or AbortSignal.timeout,
also when wrapped: Node core APIs (fs/promises, timers/promises, streams, events.once) reject with an
AbortError whose cause is the signal's reason.
abortAfter(delay): like .NET’s CancelAfter. Calling it again replaces the deadline, Infinity cancels it. The reason is a TimeoutError, as with AbortSignal.timeout.
Linked controllers: createLinkedController(request.signal) aborts with the parent’s reason and removes its listener from the parent when it aborts or is disposed.
register(signal, cb) and whenAborted(signal) for any AbortSignal, with a disposable handle and the reason passed in.
dispose() / using: release the timer and links without aborting.
isAbortError / isTimeoutError: classify what fetch and friends reject with.
TimeSpan: TimeSpan.fromMinutes(2) instead of 120000, validated.
Zero dependencies, ESM and CommonJS, Node 20 or later, Bun, Deno and modern browsers.
If one fixed timeout per operation is all you need, AbortSignal.timeout(ms) is built in. If you only combine signals, AbortSignal.any() is built in. Why this library compares them honestly.
Quick startFive minutes from install to a fetch with a resettable deadline.