UNPKG

@oxog/delay

Version:

A comprehensive, zero-dependency delay/timeout utility library with advanced timing features

70 lines 2.06 kB
import { DelayError, DelayErrorCode } from '../types/index.js'; import { createBasicDelay } from './delay.js'; export function createCancellableDelay(ms, options = {}) { const controller = new AbortController(); let isCancelled = false; const delayPromise = createBasicDelay(ms, { ...options, signal: controller.signal, }); const cancellablePromise = Object.assign(delayPromise, { cancel() { if (!isCancelled) { isCancelled = true; controller.abort(); } }, isCancelled() { return isCancelled; }, }); // Handle the case where the original signal is already aborted if (options.signal?.aborted) { isCancelled = true; controller.abort(); } // Listen for abort on the original signal options.signal?.addEventListener('abort', () => { isCancelled = true; controller.abort(); }); return cancellablePromise; } export class CancellationToken { constructor() { this._isCancelled = false; this._callbacks = []; } get isCancelled() { return this._isCancelled; } cancel() { if (!this._isCancelled) { this._isCancelled = true; this._callbacks.forEach(callback => { try { callback(); } catch (error) { // Ignore callback errors to prevent one bad callback from affecting others console.error('Error in cancellation callback:', error); } }); this._callbacks.length = 0; } } onCancel(callback) { if (this._isCancelled) { callback(); } else { this._callbacks.push(callback); } } throwIfCancelled() { if (this._isCancelled) { throw new DelayError('Operation was cancelled', DelayErrorCode.CANCELLED); } } } //# sourceMappingURL=cancellable.js.map