This is an overview of the helper functions available in the package. These utilities are designed to simplify working with AbortSignal, debouncing, timeouts, and time conversions.
The functions below are based on the AbortError class. It is used to provide consistent and informative error objects when an operation is aborted.
import { isAbortError, debounce } from 'saborter/lib';A type guard function that determines whether a given error is an AbortError. It uses multiple heuristics to identify abort errors, including checking the error's type, its name property, its message content, and recursively examining the error's cause chain.
Parameters:
error: any- The value to check.
Returns:
error is Error - type guard.
Returns true if the value is identified as an AbortError, otherwise false. When true, TypeScript narrows the type to Error.
Description:
The function performs the following checks in order:
- Instance check: If
erroris an instance ofAbortError, it returnstrue. - Name property check: If
erroris an object and has anameproperty equal to'AbortError', it returnstrue. - Message substring check: If
errorhas amessageproperty that contains the substring'abort', it returnstrue. This matches common error messages like "The operation was aborted". - Cause chain check: It recursively checks the error's
causeproperty (if any). If any error in the cause chain satisfies one of the above conditions, it returnstrue.
If none of these checks pass, it returns false.
This lenient approach ensures that various representations of abort errors (e.g., standard AbortError instances, plain objects, or errors with a nested cause) are correctly identified, making it useful in environments where the exact error class may not be available or where errors are wrapped.
Important
- The method will return
trueeven if it receives a native AbortError that is thrown by theDOMExceptionitself, or finds a hint of a request abort in the error message. - To exclusively verify that the error is an
AbortErrorfrom thesaborterpackage, it is better to use:error instance AbortError
Examples:
const abortError = new AbortError('Aborted');
isAbortError(abortError); // trueconst fakeAbort = { name: 'AbortError', message: 'Cancelled' };
isAbortError(fakeAbort); // trueconst error = new Error('The operation was aborted');
isAbortError(error); // trueconst inner = new AbortError('Inner abort');
const outer = new Error('Wrapper', { cause: inner });
isAbortError(outer); // trueconst regularError = new Error('Something went wrong');
isAbortError(regularError); // false
const nullValue = null;
isAbortError(nullValue); // falseThis function catches errors that are AbortError's and ignores them, while re‑throwing any other error. It is useful in scenarios where you want to handle abort errors silently (e.g., because they are expected and you don't need to act on them) but still propagate genuine errors.
Parameters:
error: any- The error object to inspect.options?: Object- Configuration options.strict?: boolean(Defaultfalse) - Iftrue, the function useserror instanceof AbortErrorto identify an abort error. Iffalse, it uses the more lenientisAbortErrorcheck (which may also recognize custom abort errors).
Returns:
void | never
voidif the error is anAbortError(the function does nothing, effectively silencing it).never– throws the original error if it is not anAbortError.
Example:
try {
await fetchWithTimeout(url, { signal });
} catch (error) {
catchAbortError(error); // Non‑abort errors are re‑thrown; abort errors are ignored.
// If execution reaches this point, it means the error was an AbortError and we can ignore it.
}Creates a debounced function that delays invoking the provided handler until after a specified timeout has elapsed since the last call. This is a leading‑edge debounce – the first call in a burst schedules the execution, and subsequent calls reset the timer. The debounced function accepts an AbortSignal and returns a promise that resolves with the handler's result or rejects if the handler throws or the signal is aborted.
Parameters:
handler: <R>(signal: AbortSignal) => R | Promise<R>- A function that takes anAbortSignaland returns a value or aPromise. This is the function to debounce.delay?: number- The debounce delay in milliseconds. If not provided, the handler may be invoked immediately (depending on the underlyingsetTimeoutAsync).
Returns:
(signal: AbortSignal) => R | Promise<R>
A function that accepts an AbortSignal and returns a Promise<R>, where R is the return type of the handler.
Error handling:
- If the underlying
setTimeoutAsyncthrows anAbortError, the error is enriched with a cause (a newAbortErrorcontaining the original error) and itsinitiatorproperty is set to'debounce'before being re‑thrown. - Any other error is re‑thrown unchanged.
Examples:
const debouncedFetch = debounce((signal) => fetch('/api/search', { signal }), 300);
const controller = new AbortController();
debouncedFetch(controller.signal)
.then((response) => response.json())
.catch((err) => {
if (err instanceof AbortError) {
console.log('Debounced call aborted by:', err.initiator); // 'debounce'
}
});const data = await aborter.try(debounce((signal) => fetch('/api/data', { signal }), 300));A type guard that checks whether a given value is an instance of AbortSignal.
Parameters:
value: any- The value to test.
Returns:
boolean – true if the value is an AbortSignal, false otherwise.
Example:
const controller = new AbortController();
console.log(isAbortSignal(controller.signal)); // true
console.log(isAbortSignal({})); // falseThis function is the complement of catchAbortError. It re‑throws the error only if it is an AbortError; otherwise, it does nothing. This is useful in error‑handling patterns where you want to let abort errors propagate (so they can be caught elsewhere) while handling other errors locally.
Parameters:
error: any- The error to inspect.options?: Object:strict?: boolean(defaultfalse) - Iftrue, useserror instanceof AbortError. Iffalse, uses the more lenientisAbortErrorcheck.
Returns:
void | never
voidif the error is not anAbortError.never– throws the original error if it is anAbortError.
Example:
try {
await someOperation(signal);
} catch (error) {
rethrowAbortError(error); // Only re‑throws if it's an abort error.
// Handle other errors here.
}Schedules the execution of a handler after a specified delay. The operation can be cancelled using an AbortSignal. This function returns a promise that resolves with the handler's result or rejects if the timeout is aborted or if the handler throws an error.
Parameters:
handler: ((signal: AbortSignal) => T | Promise<T>):- A function that accepts an
AbortSignaland returns a value or aPromise. This function will be called with the signal to allow cleanup on abort.
- A function that accepts an
delay?: number- The time in milliseconds to wait before executing the handler. If omitted, the handler is scheduled without a delay (i.e., as soon as possible).options?: Object:signal?: AbortSignal- AnAbortSignalthat can be used to cancel the timeout. If not provided, a newAbortControlleris created internally.args?: any[]- Arguments to pass to the handler.
Returns:
Promise<T> – resolves with the handler's result, or rejects with an AbortError if the operation was aborted, or with any error thrown by the handler.
Behavior:
- If the provided signal is already aborted when
setTimeoutAsyncis called, it immediately rejects with anAbortError. - When the
handleris a function, it is called with the signal. If the function returns a promise, the promise is chained; otherwise, the return value is used directly. - If the
signalisabortedafter the timeout has been set, the timeout is cleared and the promise rejects with anAbortError. The error includes the original signal reason and the initiator is set to'setTimeoutAsync'.
Examples:
const controller = new AbortController();
setTimeoutAsync(
(signal) => {
return fetch('/api/data', { signal }).then((res) => res.json());
},
5000,
{
signal: controller.signal
}
)
.then((data) => console.log(data))
.catch((error) => console.log(error.name)); // 'AbortError' if abortedconst controller = new AbortController();
try {
const data = await setTimeoutAsync(
async (signal) => {
const response = await fetch('/api/data', { signal });
return await response.json();
},
5000,
{ signal: controller.signal }
);
} catch (error) {
console.log(error.name); // 'AbortError' if aborted
}const delay = (ms: number) => setTimeoutAsync(() => null, ms);
console.log('Hello');
await delay(2000);
console.log('World');The setTimeoutAsync function can be used like a regular native setTimeout function, but instead of returning an ID for deletion from the EventLoop, it returns the values you returned from the callback:
// Getting a token from local storage in 5 seconds
const token = await setTimeoutAsync(() => localStorage.getItem('token'), 5000); // string | nullconst controller = new AbortController();
// Or you can use an ReusableAborter
try {
const token = await setTimeoutAsync(
() => {
return localStorage.getItem('token');
},
5000,
{ signal: controller.signal }
);
} catch (error) {
if (isAbortError(error)) {
console.log(error.name); // 'AbortError'
}
}A utility that checks whether an AbortSignal has been aborted. If the signal is aborted, it throws an AbortError. This is useful for manual abortion checks inside long‑running operations that do not automatically handle the signal.
Parameters:
signal: AbortSignal- The signal to check.
Returns:
void | never
voidif the signal is not aborted.never– throws anAbortErrorif the signal is aborted.
Behavior:
- If the signal's
reasonis already an instance ofAbortError, that exact error is thrown (preserving its cause and initiator). - Otherwise, a new AbortError is created with a default message and the original reason attached. The initiator is set to
'throwIfAborted'.
Example:
const processItems = (items: unknown[], signal: AbortSignal) => {
try {
for (const item of items) {
throwIfAborted(signal); // Check before each iteration
// Process item...
}
} catch (error) {
// Handle error
}
};Converts a configuration object containing time components (hours, minutes, seconds, milliseconds) into a total number of milliseconds. All components are optional and default to 0 if not provided.
Parameters:
timeMsConfig: Object- An object with the following optional numeric properties:hours?: number- hours to add.minutes?: number- minutes to add.seconds?: number- seconds to add.milliseconds?: number- milliseconds to add.
Returns:
number - the total time in milliseconds.
Throws:
TypeError– if any of the provided values is not a number orundefined.
Example:
timeInMilliseconds({ seconds: 1 }); // Returns 1000
timeInMilliseconds({ minutes: 1, seconds: 30 }); // Returns 90000
timeInMilliseconds({ hours: 1, minutes: 30, seconds: 45, milliseconds: 500 }); // Returns 5,445,500A function that allows you to clear an object's data, if the object supports this feature.
Parameters:
object: any- an object that supports resource cleaning.
Returns:
void - The function does not return anything.
Throws:
ReferenceError– if the object does not support resource cleanup.