magic-aborter
Version:
An magic util to control everything abortable
168 lines • 5.65 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.toAbortable = exports.MagicAborter = void 0;
exports.createMagicAborter = createMagicAborter;
const mitt_1 = __importDefault(require("mitt"));
/**
* MagicAborter is a utility class that manages multiple abortable operations.
* It can collect various types of abortable objects (like Promises, fetch requests, or native AbortControllers)
* and abort them all at once.
*
* Features:
* - Collect multiple abortable objects
* - Create parent-child relationships between aborters
* - Event-driven architecture with abort events
* - TypeScript support
*
* @implements {Abortable}
*/
class MagicAborter {
/**
* Converts any object into an abortable object by adding an abort method.
*
* @template T - The type of object to make abortable
* @param {T} target - The object to make abortable
* @param {() => void} abort - The abort function to be called
* @returns {Abortable<T>} The original object with an abort method
*/
static toAbortable(target, abort) {
target.abort = abort;
return target;
}
/**
* Creates a new MagicAborter instance.
*
* @param {AborterOptions} [options] - Configuration options
* @param {Array<MagicAborter>} [options.children] - Child aborters to be managed
*/
constructor(options) {
this._aborted = false;
this.children = [];
this.collections = [];
this.emitter = (0, mitt_1.default)();
const { children = [] } = options || {};
this.children = children;
}
/**
* Gets the current abort state.
* Returns true only if this aborter and all its children are aborted.
*/
get aborted() {
return this._aborted && this.children.every((i) => i.aborted);
}
/**
* Sets the abort state of this aborter.
*/
set aborted(value) {
this._aborted = value;
}
/**
* Collects an abortable object to be managed by this aborter.
* The object must implement the Abortable interface (have an abort method).
*
* @param {Abortable} abortable - The abortable object to collect
*/
collect(abortable) {
if (!this.collections.includes(abortable))
this.collections.push(abortable);
this.aborted = false;
}
/**
* Aborts all collected operations and child aborters.
* This will:
* 1. Emit the 'abort' event
* 2. Abort all collected operations
* 3. Abort all child aborters
* 4. Set the aborted state to true
* 5. Emit the 'aborted' event
*/
abort() {
if (this.aborted)
return;
this.emitter.emit("abort");
while (this.collections.length) {
this.collections.shift().abort();
}
this.children.forEach((i) => i.abort());
this.aborted = true;
this.emitter.emit("aborted");
}
/**
* Registers an event listener for the specified event type.
*
* @param {EventType} event - The event type to listen for ('abort' or 'aborted')
* @param {() => void} listener - The callback function to execute when the event occurs
*/
on(event, listener) {
this.emitter.on(event, listener);
}
/**
* Removes an event listener for the specified event type.
*
* @param {EventType} event - The event type to remove the listener from
* @param {() => void} listener - The callback function to remove
*/
off(event, listener) {
this.emitter.off(event, listener);
}
/**
* Registers a listener for the 'abort' event.
* This event is emitted before the abort operation begins.
*
* @param {() => void} listener - The callback function to execute
*/
onAbort(listener) {
this.on("abort", listener);
}
/**
* Registers a listener for the 'aborted' event.
* This event is emitted after all operations have been aborted.
*
* @param {() => void} listener - The callback function to execute
*/
onAborted(listener) {
this.on("aborted", listener);
}
/**
* Adds a child aborter to this aborter.
* When this aborter is aborted, all child aborters will also be aborted.
*
* @param {MagicAborter} child - The child aborter to add
*/
addChildAborter(child) {
this.children.push(child);
}
/**
* Removes a child aborter from this aborter.
*
* @param {MagicAborter} child - The child aborter to remove
*/
removeChildAborter(child) {
this.children.splice(this.children.indexOf(child), 1);
}
}
exports.MagicAborter = MagicAborter;
/**
* Creates a new MagicAborter instance with the specified options.
* This is a convenience function for creating a new aborter.
*
* @param {AborterOptions} [options] - Configuration options for the aborter
* @returns {MagicAborter} A new MagicAborter instance
*/
function createMagicAborter(options) {
return new MagicAborter(options);
}
/**
* A convenience export of the static toAbortable method.
* Converts any object into an abortable object.
*
* @template T - The type of object to make abortable
* @param {T} target - The object to make abortable
* @param {() => void} abort - The abort function to be called
* @returns {Abortable<T>} The original object with an abort method
*/
exports.toAbortable = MagicAborter.toAbortable;
//# sourceMappingURL=index.js.map