abort-controller.mjs (3311B)
1 /** 2 * @author Toru Nagashima <https://github.com/mysticatea> 3 * See LICENSE file in root directory for full license. 4 */ 5 import { EventTarget, defineEventAttribute } from 'event-target-shim'; 6 7 /** 8 * The signal class. 9 * @see https://dom.spec.whatwg.org/#abortsignal 10 */ 11 class AbortSignal extends EventTarget { 12 /** 13 * AbortSignal cannot be constructed directly. 14 */ 15 constructor() { 16 super(); 17 throw new TypeError("AbortSignal cannot be constructed directly"); 18 } 19 /** 20 * Returns `true` if this `AbortSignal`'s `AbortController` has signaled to abort, and `false` otherwise. 21 */ 22 get aborted() { 23 const aborted = abortedFlags.get(this); 24 if (typeof aborted !== "boolean") { 25 throw new TypeError(`Expected 'this' to be an 'AbortSignal' object, but got ${this === null ? "null" : typeof this}`); 26 } 27 return aborted; 28 } 29 } 30 defineEventAttribute(AbortSignal.prototype, "abort"); 31 /** 32 * Create an AbortSignal object. 33 */ 34 function createAbortSignal() { 35 const signal = Object.create(AbortSignal.prototype); 36 EventTarget.call(signal); 37 abortedFlags.set(signal, false); 38 return signal; 39 } 40 /** 41 * Abort a given signal. 42 */ 43 function abortSignal(signal) { 44 if (abortedFlags.get(signal) !== false) { 45 return; 46 } 47 abortedFlags.set(signal, true); 48 signal.dispatchEvent({ type: "abort" }); 49 } 50 /** 51 * Aborted flag for each instances. 52 */ 53 const abortedFlags = new WeakMap(); 54 // Properties should be enumerable. 55 Object.defineProperties(AbortSignal.prototype, { 56 aborted: { enumerable: true }, 57 }); 58 // `toString()` should return `"[object AbortSignal]"` 59 if (typeof Symbol === "function" && typeof Symbol.toStringTag === "symbol") { 60 Object.defineProperty(AbortSignal.prototype, Symbol.toStringTag, { 61 configurable: true, 62 value: "AbortSignal", 63 }); 64 } 65 66 /** 67 * The AbortController. 68 * @see https://dom.spec.whatwg.org/#abortcontroller 69 */ 70 class AbortController { 71 /** 72 * Initialize this controller. 73 */ 74 constructor() { 75 signals.set(this, createAbortSignal()); 76 } 77 /** 78 * Returns the `AbortSignal` object associated with this object. 79 */ 80 get signal() { 81 return getSignal(this); 82 } 83 /** 84 * Abort and signal to any observers that the associated activity is to be aborted. 85 */ 86 abort() { 87 abortSignal(getSignal(this)); 88 } 89 } 90 /** 91 * Associated signals. 92 */ 93 const signals = new WeakMap(); 94 /** 95 * Get the associated signal of a given controller. 96 */ 97 function getSignal(controller) { 98 const signal = signals.get(controller); 99 if (signal == null) { 100 throw new TypeError(`Expected 'this' to be an 'AbortController' object, but got ${controller === null ? "null" : typeof controller}`); 101 } 102 return signal; 103 } 104 // Properties should be enumerable. 105 Object.defineProperties(AbortController.prototype, { 106 signal: { enumerable: true }, 107 abort: { enumerable: true }, 108 }); 109 if (typeof Symbol === "function" && typeof Symbol.toStringTag === "symbol") { 110 Object.defineProperty(AbortController.prototype, Symbol.toStringTag, { 111 configurable: true, 112 value: "AbortController", 113 }); 114 } 115 116 export default AbortController; 117 export { AbortController, AbortSignal }; 118 //# sourceMappingURL=abort-controller.mjs.map