isotropic-cancel
v0.1.0
Published
Manage the cancellation of an asynchronous task with reasons, abort signals, and standardized errors
Maintainers
Readme
isotropic-cancel
A utility that manages the cancellation of an asynchronous task with reasons, abort signals, and standardized errors.
Why Use This?
- One Cancellation Contract: The same reusable
cancel({ reason, signal, silent })semantics implemented in one place - AbortSignal Integration: Bind any number of
AbortSignalinstances before or after creation, with automatic listener cleanup - Standardized Errors: Generates consistent
AbortErrorandCanceledErrorobjects with configurable subjects and details - Silent Cancellation: Cancel a task's side effects without delivering an error
- Resource Management: Supports
usingdeclarations viaSymbol.dispose
Installation
npm install isotropic-cancelOverview
A Cancel instance represents the cancelable phase of a pending task. It begins pending. It ends in exactly one of two ways:
cancel()- the task should stop. Signal listeners are removed and theonCancelfunction is executed with a standardized error describing why.complete()- the task completed on its own. Signal listeners are removed and nothing else happens.
Once canceled or completed, all further cancel and complete calls are ignored. The onCancel function defines what cancellation means for the specific task: reject a promise, remove a queued callback, abort a controller, clear a timer, or anything else.
Usage
import _Cancel from 'isotropic-cancel';
const _somethingAsync = ({
signal
} = {}) => {
const {
promise,
reject,
resolve
} = Promise.withResolvers(),
cancel = _Cancel({
onCancel: ({
error
}) => {
// Stop the task however is appropriate, then deliver the error.
if (error) {
reject(error);
}
},
signal,
subject: 'Something async'
});
beginTheTask(result => {
if (!cancel.completed) {
cancel.complete();
resolve(result);
}
});
promise.cancel = config => {
cancel.cancel(config);
return promise;
};
return promise;
};API
Constructor
_Cancel(config)Creates a new cancel instance. Cancel is created with isotropic-make, so it can be called with or without new.
Parameters
config(Object, optional):details(Object, optional): Included as thedetailsof generated errorsonCancel(Function, optional): Executed exactly once when the instance is canceled, with a config object:error(Error): The cancellation error, orundefinedwhen canceled silentlysilent(Boolean): Whether the cancellation was silent
signal(AbortSignal, optional): A signal to bind immediately. If it is already aborted, the instance cancels synchronously during construction.subject(String, optional): The subject of generated error messages, as in${subject} abortedand${subject} canceled. Default:'Task'
cancel(config)
Requests cancellation.
Parameters
config(Object, optional):reason(Error, optional): A custom error to deliver instead of the generatedCanceledErrorsignal(AbortSignal, optional): When given a signal that has not yet aborted, the instance is not canceled; instead the signal is bound so that its abort cancels the instance later. When given a signal that has already aborted, the instance cancels immediately with anAbortErrorwrappingsignal.reason.silent(Boolean, optional): Cancel without delivering an error.onCancelis still executed so the task can stop, but itserrorisundefined. When registering a signal, thesilentvalue is remembered and applied when the signal aborts. Default:false
Returns
- (Cancel): The instance, for chaining
The same signal can be bound multiple times without duplicate listeners, and multiple different signals can each be bound. When the instance settles or cancels, all listeners are removed.
complete()
Marks the task as complete. Signal listeners are removed and any pending cancellation sources are ignored from this point on. Returns the instance.
canceled
A read-only Boolean property indicating whether the instance was canceled.
completed
A read-only Boolean property indicating whether the instance has ended, either by cancel() or by complete().
Symbol.dispose()
Completes the instance, enabling using declarations.
Cancel.abortError(config)
A static factory for the standardized AbortError.
Parameters
config(Object, optional):details(Object, optional): Error detailssignal(AbortSignal, optional): The aborted signal; itsreasonbecomes the error'serrorpropertysubject(String, optional): Default:'Task'
Returns
- (Error): An isotropic-error with
name'AbortError'and message${subject} aborted
Cancel.canceledError(config)
A static factory for the standardized CanceledError.
Parameters
config(Object, optional):details(Object, optional): Error detailssubject(String, optional): Default:'Task'
Returns
- (Error): An isotropic-error with
name'CanceledError'and message${subject} canceled
Errors
| Name | Cause | error property |
| --------------- | ----------------------------- | ---------------- |
| AbortError | Canceled via an AbortSignal | signal.reason |
| CanceledError | Canceled without a reason | - |
When cancel is called with a reason, that reason is delivered as-is instead of a generated error.
Related Packages
- isotropic-timeout-cancel: This class extended with a time limit
- isotropic-later: Cancelable timers built on this class
- isotropic-error: The error objects generated by this class
Contributing
Please refer to CONTRIBUTING.md for contribution guidelines.
Issues
If you encounter any issues, please file them at https://github.com/ibi-group/isotropic-cancel/issues
