├── .codecov.yml ├── .eslintignore ├── .eslintrc.yml ├── .gitattributes ├── .gitignore ├── .npmrc ├── .nycrc ├── .travis.yml ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── browser.js ├── browser.mjs ├── dist ├── abort-controller.d.ts ├── abort-controller.js ├── abort-controller.js.map ├── abort-controller.mjs ├── abort-controller.mjs.map ├── abort-controller.umd.js └── abort-controller.umd.js.map ├── karma.conf.js ├── package.json ├── polyfill.js ├── polyfill.mjs ├── rollup.config.js ├── scripts └── fix-dts.ts ├── src ├── abort-controller.ts └── abort-signal.ts ├── test ├── fixtures │ └── types.ts ├── index.ts ├── polyfill.ts └── types.ts └── tsconfig.json /.codecov.yml: -------------------------------------------------------------------------------- 1 | comment: off 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /.nyc_output 2 | /coverage 3 | /dist 4 | /node_modules 5 | /test/fixtures 6 | 7 | !.eslintrc.js 8 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | root: true 2 | 3 | extends: 4 | - plugin:@mysticatea/es2018 5 | - plugin:@mysticatea/+node 6 | 7 | overrides: 8 | - files: test/** 9 | rules: 10 | new-cap: "off" 11 | 12 | # To reduce size for babel-translation. 13 | - files: "*" 14 | rules: 15 | no-restricted-syntax: 16 | - error 17 | - ForOfStatement 18 | - BinaryExpression[left.operator='typeof'][right.value='object'] 19 | prefer-rest-params: "off" 20 | prefer-spread: "off" 21 | "@mysticatea/prefer-for-of": "off" 22 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.nyc_output 2 | /coverage 3 | /node_modules 4 | /npm-debug.log 5 | /test.* 6 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "src/**/*.ts" 4 | ], 5 | "extension": [ 6 | ".ts" 7 | ], 8 | "require": [ 9 | "ts-node/register" 10 | ], 11 | "reporter": [ 12 | "lcov", 13 | "text" 14 | ], 15 | "sourceMap": true 16 | } 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6" 4 | - "8" 5 | - "10" 6 | - "11" 7 | 8 | script: 9 | - npm run -s test:mocha 10 | 11 | after_success: 12 | - npm run codecov 13 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.validate": [ 3 | "javascript", 4 | {"language": "typescript", "autoFix": true} 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Toru Nagashima 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # abort-controller 2 | 3 | [![npm version](https://img.shields.io/npm/v/abort-controller.svg)](https://www.npmjs.com/package/abort-controller) 4 | [![Downloads/month](https://img.shields.io/npm/dm/abort-controller.svg)](http://www.npmtrends.com/abort-controller) 5 | [![Build Status](https://travis-ci.org/mysticatea/abort-controller.svg?branch=master)](https://travis-ci.org/mysticatea/abort-controller) 6 | [![Coverage Status](https://codecov.io/gh/mysticatea/abort-controller/branch/master/graph/badge.svg)](https://codecov.io/gh/mysticatea/abort-controller) 7 | [![Dependency Status](https://david-dm.org/mysticatea/abort-controller.svg)](https://david-dm.org/mysticatea/abort-controller) 8 | 9 | An implementation of [WHATWG AbortController interface](https://dom.spec.whatwg.org/#interface-abortcontroller). 10 | 11 | ```js 12 | import AbortController from "abort-controller" 13 | 14 | const controller = new AbortController() 15 | const signal = controller.signal 16 | 17 | signal.addEventListener("abort", () => { 18 | console.log("aborted!") 19 | }) 20 | 21 | controller.abort() 22 | ``` 23 | 24 | > https://jsfiddle.net/1r2994qp/1/ 25 | 26 | ## 💿 Installation 27 | 28 | Use [npm](https://www.npmjs.com/) to install then use a bundler. 29 | 30 | ``` 31 | npm install abort-controller 32 | ``` 33 | 34 | Or download from [`dist` directory](./dist). 35 | 36 | - [dist/abort-controller.mjs](dist/abort-controller.mjs) ... ES modules version. 37 | - [dist/abort-controller.js](dist/abort-controller.js) ... Common JS version. 38 | - [dist/abort-controller.umd.js](dist/abort-controller.umd.js) ... UMD (Universal Module Definition) version. This is transpiled by [Babel](https://babeljs.io/) for IE 11. 39 | 40 | ## 📖 Usage 41 | 42 | ### Basic 43 | 44 | ```js 45 | import AbortController from "abort-controller" 46 | // or 47 | const AbortController = require("abort-controller") 48 | 49 | // or UMD version defines a global variable: 50 | const AbortController = window.AbortControllerShim 51 | ``` 52 | 53 | If your bundler recognizes `browser` field of `package.json`, the imported `AbortController` is the native one and it doesn't contain shim (even if the native implementation was nothing). 54 | If you wanted to polyfill `AbortController` for IE, use `abort-controller/polyfill`. 55 | 56 | ### Polyfilling 57 | 58 | Importing `abort-controller/polyfill` assigns the `AbortController` shim to the `AbortController` global variable if the native implementation was nothing. 59 | 60 | ```js 61 | import "abort-controller/polyfill" 62 | // or 63 | require("abort-controller/polyfill") 64 | ``` 65 | 66 | ### API 67 | 68 | #### AbortController 69 | 70 | > https://dom.spec.whatwg.org/#interface-abortcontroller 71 | 72 | ##### controller.signal 73 | 74 | The [AbortSignal](https://dom.spec.whatwg.org/#interface-AbortSignal) object which is associated to this controller. 75 | 76 | ##### controller.abort() 77 | 78 | Notify `abort` event to listeners that the `signal` has. 79 | 80 | ## 📰 Changelog 81 | 82 | - See [GitHub releases](https://github.com/mysticatea/abort-controller/releases). 83 | 84 | ## 🍻 Contributing 85 | 86 | Contributing is welcome ❤️ 87 | 88 | Please use GitHub issues/PRs. 89 | 90 | ### Development tools 91 | 92 | - `npm install` installs dependencies for development. 93 | - `npm test` runs tests and measures code coverage. 94 | - `npm run clean` removes temporary files of tests. 95 | - `npm run coverage` opens code coverage of the previous test with your default browser. 96 | - `npm run lint` runs ESLint. 97 | - `npm run build` generates `dist` codes. 98 | - `npm run watch` runs tests on each file change. 99 | -------------------------------------------------------------------------------- /browser.js: -------------------------------------------------------------------------------- 1 | /*globals self, window */ 2 | "use strict" 3 | 4 | /*eslint-disable @mysticatea/prettier */ 5 | const { AbortController, AbortSignal } = 6 | typeof self !== "undefined" ? self : 7 | typeof window !== "undefined" ? window : 8 | /* otherwise */ undefined 9 | /*eslint-enable @mysticatea/prettier */ 10 | 11 | module.exports = AbortController 12 | module.exports.AbortSignal = AbortSignal 13 | module.exports.default = AbortController 14 | -------------------------------------------------------------------------------- /browser.mjs: -------------------------------------------------------------------------------- 1 | /*globals self, window */ 2 | 3 | /*eslint-disable @mysticatea/prettier */ 4 | const { AbortController, AbortSignal } = 5 | typeof self !== "undefined" ? self : 6 | typeof window !== "undefined" ? window : 7 | /* otherwise */ undefined 8 | /*eslint-enable @mysticatea/prettier */ 9 | 10 | export default AbortController 11 | export { AbortController, AbortSignal } 12 | -------------------------------------------------------------------------------- /dist/abort-controller.d.ts: -------------------------------------------------------------------------------- 1 | import { EventTarget } from "event-target-shim" 2 | 3 | type Events = { 4 | abort: any 5 | } 6 | type EventAttributes = { 7 | onabort: any 8 | } 9 | /** 10 | * The signal class. 11 | * @see https://dom.spec.whatwg.org/#abortsignal 12 | */ 13 | declare class AbortSignal extends EventTarget { 14 | /** 15 | * AbortSignal cannot be constructed directly. 16 | */ 17 | constructor() 18 | /** 19 | * Returns `true` if this `AbortSignal`"s `AbortController` has signaled to abort, and `false` otherwise. 20 | */ 21 | readonly aborted: boolean 22 | } 23 | /** 24 | * The AbortController. 25 | * @see https://dom.spec.whatwg.org/#abortcontroller 26 | */ 27 | declare class AbortController { 28 | /** 29 | * Initialize this controller. 30 | */ 31 | constructor() 32 | /** 33 | * Returns the `AbortSignal` object associated with this object. 34 | */ 35 | readonly signal: AbortSignal 36 | /** 37 | * Abort and signal to any observers that the associated activity is to be aborted. 38 | */ 39 | abort(): void 40 | } 41 | 42 | export default AbortController 43 | export { AbortController, AbortSignal } 44 | -------------------------------------------------------------------------------- /dist/abort-controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 3 | * See LICENSE file in root directory for full license. 4 | */ 5 | 'use strict'; 6 | 7 | Object.defineProperty(exports, '__esModule', { value: true }); 8 | 9 | var eventTargetShim = require('event-target-shim'); 10 | 11 | /** 12 | * The signal class. 13 | * @see https://dom.spec.whatwg.org/#abortsignal 14 | */ 15 | class AbortSignal extends eventTargetShim.EventTarget { 16 | /** 17 | * AbortSignal cannot be constructed directly. 18 | */ 19 | constructor() { 20 | super(); 21 | throw new TypeError("AbortSignal cannot be constructed directly"); 22 | } 23 | /** 24 | * Returns `true` if this `AbortSignal`'s `AbortController` has signaled to abort, and `false` otherwise. 25 | */ 26 | get aborted() { 27 | const aborted = abortedFlags.get(this); 28 | if (typeof aborted !== "boolean") { 29 | throw new TypeError(`Expected 'this' to be an 'AbortSignal' object, but got ${this === null ? "null" : typeof this}`); 30 | } 31 | return aborted; 32 | } 33 | } 34 | eventTargetShim.defineEventAttribute(AbortSignal.prototype, "abort"); 35 | /** 36 | * Create an AbortSignal object. 37 | */ 38 | function createAbortSignal() { 39 | const signal = Object.create(AbortSignal.prototype); 40 | eventTargetShim.EventTarget.call(signal); 41 | abortedFlags.set(signal, false); 42 | return signal; 43 | } 44 | /** 45 | * Abort a given signal. 46 | */ 47 | function abortSignal(signal) { 48 | if (abortedFlags.get(signal) !== false) { 49 | return; 50 | } 51 | abortedFlags.set(signal, true); 52 | signal.dispatchEvent({ type: "abort" }); 53 | } 54 | /** 55 | * Aborted flag for each instances. 56 | */ 57 | const abortedFlags = new WeakMap(); 58 | // Properties should be enumerable. 59 | Object.defineProperties(AbortSignal.prototype, { 60 | aborted: { enumerable: true }, 61 | }); 62 | // `toString()` should return `"[object AbortSignal]"` 63 | if (typeof Symbol === "function" && typeof Symbol.toStringTag === "symbol") { 64 | Object.defineProperty(AbortSignal.prototype, Symbol.toStringTag, { 65 | configurable: true, 66 | value: "AbortSignal", 67 | }); 68 | } 69 | 70 | /** 71 | * The AbortController. 72 | * @see https://dom.spec.whatwg.org/#abortcontroller 73 | */ 74 | class AbortController { 75 | /** 76 | * Initialize this controller. 77 | */ 78 | constructor() { 79 | signals.set(this, createAbortSignal()); 80 | } 81 | /** 82 | * Returns the `AbortSignal` object associated with this object. 83 | */ 84 | get signal() { 85 | return getSignal(this); 86 | } 87 | /** 88 | * Abort and signal to any observers that the associated activity is to be aborted. 89 | */ 90 | abort() { 91 | abortSignal(getSignal(this)); 92 | } 93 | } 94 | /** 95 | * Associated signals. 96 | */ 97 | const signals = new WeakMap(); 98 | /** 99 | * Get the associated signal of a given controller. 100 | */ 101 | function getSignal(controller) { 102 | const signal = signals.get(controller); 103 | if (signal == null) { 104 | throw new TypeError(`Expected 'this' to be an 'AbortController' object, but got ${controller === null ? "null" : typeof controller}`); 105 | } 106 | return signal; 107 | } 108 | // Properties should be enumerable. 109 | Object.defineProperties(AbortController.prototype, { 110 | signal: { enumerable: true }, 111 | abort: { enumerable: true }, 112 | }); 113 | if (typeof Symbol === "function" && typeof Symbol.toStringTag === "symbol") { 114 | Object.defineProperty(AbortController.prototype, Symbol.toStringTag, { 115 | configurable: true, 116 | value: "AbortController", 117 | }); 118 | } 119 | 120 | exports.AbortController = AbortController; 121 | exports.AbortSignal = AbortSignal; 122 | exports.default = AbortController; 123 | 124 | module.exports = AbortController 125 | module.exports.AbortController = module.exports["default"] = AbortController 126 | module.exports.AbortSignal = AbortSignal 127 | //# sourceMappingURL=abort-controller.js.map 128 | -------------------------------------------------------------------------------- /dist/abort-controller.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"abort-controller.js","sources":["../src/abort-signal.ts","../src/abort-controller.ts"],"sourcesContent":["import {\n // Event,\n EventTarget,\n // Type,\n defineEventAttribute,\n} from \"event-target-shim\"\n\n// Known Limitation\n// Use `any` because the type of `AbortSignal` in `lib.dom.d.ts` is wrong and\n// to make assignable our `AbortSignal` into that.\n// https://github.com/Microsoft/TSJS-lib-generator/pull/623\ntype Events = {\n abort: any // Event & Type<\"abort\">\n}\ntype EventAttributes = {\n onabort: any // Event & Type<\"abort\">\n}\n\n/**\n * The signal class.\n * @see https://dom.spec.whatwg.org/#abortsignal\n */\nexport default class AbortSignal extends EventTarget {\n /**\n * AbortSignal cannot be constructed directly.\n */\n public constructor() {\n super()\n throw new TypeError(\"AbortSignal cannot be constructed directly\")\n }\n\n /**\n * Returns `true` if this `AbortSignal`'s `AbortController` has signaled to abort, and `false` otherwise.\n */\n public get aborted(): boolean {\n const aborted = abortedFlags.get(this)\n if (typeof aborted !== \"boolean\") {\n throw new TypeError(\n `Expected 'this' to be an 'AbortSignal' object, but got ${\n this === null ? \"null\" : typeof this\n }`,\n )\n }\n return aborted\n }\n}\ndefineEventAttribute(AbortSignal.prototype, \"abort\")\n\n/**\n * Create an AbortSignal object.\n */\nexport function createAbortSignal(): AbortSignal {\n const signal = Object.create(AbortSignal.prototype)\n EventTarget.call(signal)\n abortedFlags.set(signal, false)\n return signal\n}\n\n/**\n * Abort a given signal.\n */\nexport function abortSignal(signal: AbortSignal): void {\n if (abortedFlags.get(signal) !== false) {\n return\n }\n\n abortedFlags.set(signal, true)\n signal.dispatchEvent<\"abort\">({ type: \"abort\" })\n}\n\n/**\n * Aborted flag for each instances.\n */\nconst abortedFlags = new WeakMap()\n\n// Properties should be enumerable.\nObject.defineProperties(AbortSignal.prototype, {\n aborted: { enumerable: true },\n})\n\n// `toString()` should return `\"[object AbortSignal]\"`\nif (typeof Symbol === \"function\" && typeof Symbol.toStringTag === \"symbol\") {\n Object.defineProperty(AbortSignal.prototype, Symbol.toStringTag, {\n configurable: true,\n value: \"AbortSignal\",\n })\n}\n","import AbortSignal, { abortSignal, createAbortSignal } from \"./abort-signal\"\n\n/**\n * The AbortController.\n * @see https://dom.spec.whatwg.org/#abortcontroller\n */\nexport default class AbortController {\n /**\n * Initialize this controller.\n */\n public constructor() {\n signals.set(this, createAbortSignal())\n }\n\n /**\n * Returns the `AbortSignal` object associated with this object.\n */\n public get signal(): AbortSignal {\n return getSignal(this)\n }\n\n /**\n * Abort and signal to any observers that the associated activity is to be aborted.\n */\n public abort(): void {\n abortSignal(getSignal(this))\n }\n}\n\n/**\n * Associated signals.\n */\nconst signals = new WeakMap()\n\n/**\n * Get the associated signal of a given controller.\n */\nfunction getSignal(controller: AbortController): AbortSignal {\n const signal = signals.get(controller)\n if (signal == null) {\n throw new TypeError(\n `Expected 'this' to be an 'AbortController' object, but got ${\n controller === null ? \"null\" : typeof controller\n }`,\n )\n }\n return signal\n}\n\n// Properties should be enumerable.\nObject.defineProperties(AbortController.prototype, {\n signal: { enumerable: true },\n abort: { enumerable: true },\n})\n\nif (typeof Symbol === \"function\" && typeof Symbol.toStringTag === \"symbol\") {\n Object.defineProperty(AbortController.prototype, Symbol.toStringTag, {\n configurable: true,\n value: \"AbortController\",\n })\n}\n\nexport { AbortController, AbortSignal }\n"],"names":["EventTarget","defineEventAttribute"],"mappings":"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"} -------------------------------------------------------------------------------- /dist/abort-controller.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 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 119 | -------------------------------------------------------------------------------- /dist/abort-controller.mjs.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"abort-controller.mjs","sources":["../src/abort-signal.ts","../src/abort-controller.ts"],"sourcesContent":["import {\n // Event,\n EventTarget,\n // Type,\n defineEventAttribute,\n} from \"event-target-shim\"\n\n// Known Limitation\n// Use `any` because the type of `AbortSignal` in `lib.dom.d.ts` is wrong and\n// to make assignable our `AbortSignal` into that.\n// https://github.com/Microsoft/TSJS-lib-generator/pull/623\ntype Events = {\n abort: any // Event & Type<\"abort\">\n}\ntype EventAttributes = {\n onabort: any // Event & Type<\"abort\">\n}\n\n/**\n * The signal class.\n * @see https://dom.spec.whatwg.org/#abortsignal\n */\nexport default class AbortSignal extends EventTarget {\n /**\n * AbortSignal cannot be constructed directly.\n */\n public constructor() {\n super()\n throw new TypeError(\"AbortSignal cannot be constructed directly\")\n }\n\n /**\n * Returns `true` if this `AbortSignal`'s `AbortController` has signaled to abort, and `false` otherwise.\n */\n public get aborted(): boolean {\n const aborted = abortedFlags.get(this)\n if (typeof aborted !== \"boolean\") {\n throw new TypeError(\n `Expected 'this' to be an 'AbortSignal' object, but got ${\n this === null ? \"null\" : typeof this\n }`,\n )\n }\n return aborted\n }\n}\ndefineEventAttribute(AbortSignal.prototype, \"abort\")\n\n/**\n * Create an AbortSignal object.\n */\nexport function createAbortSignal(): AbortSignal {\n const signal = Object.create(AbortSignal.prototype)\n EventTarget.call(signal)\n abortedFlags.set(signal, false)\n return signal\n}\n\n/**\n * Abort a given signal.\n */\nexport function abortSignal(signal: AbortSignal): void {\n if (abortedFlags.get(signal) !== false) {\n return\n }\n\n abortedFlags.set(signal, true)\n signal.dispatchEvent<\"abort\">({ type: \"abort\" })\n}\n\n/**\n * Aborted flag for each instances.\n */\nconst abortedFlags = new WeakMap()\n\n// Properties should be enumerable.\nObject.defineProperties(AbortSignal.prototype, {\n aborted: { enumerable: true },\n})\n\n// `toString()` should return `\"[object AbortSignal]\"`\nif (typeof Symbol === \"function\" && typeof Symbol.toStringTag === \"symbol\") {\n Object.defineProperty(AbortSignal.prototype, Symbol.toStringTag, {\n configurable: true,\n value: \"AbortSignal\",\n })\n}\n","import AbortSignal, { abortSignal, createAbortSignal } from \"./abort-signal\"\n\n/**\n * The AbortController.\n * @see https://dom.spec.whatwg.org/#abortcontroller\n */\nexport default class AbortController {\n /**\n * Initialize this controller.\n */\n public constructor() {\n signals.set(this, createAbortSignal())\n }\n\n /**\n * Returns the `AbortSignal` object associated with this object.\n */\n public get signal(): AbortSignal {\n return getSignal(this)\n }\n\n /**\n * Abort and signal to any observers that the associated activity is to be aborted.\n */\n public abort(): void {\n abortSignal(getSignal(this))\n }\n}\n\n/**\n * Associated signals.\n */\nconst signals = new WeakMap()\n\n/**\n * Get the associated signal of a given controller.\n */\nfunction getSignal(controller: AbortController): AbortSignal {\n const signal = signals.get(controller)\n if (signal == null) {\n throw new TypeError(\n `Expected 'this' to be an 'AbortController' object, but got ${\n controller === null ? \"null\" : typeof controller\n }`,\n )\n }\n return signal\n}\n\n// Properties should be enumerable.\nObject.defineProperties(AbortController.prototype, {\n signal: { enumerable: true },\n abort: { enumerable: true },\n})\n\nif (typeof Symbol === \"function\" && typeof Symbol.toStringTag === \"symbol\") {\n Object.defineProperty(AbortController.prototype, Symbol.toStringTag, {\n configurable: true,\n value: \"AbortController\",\n })\n}\n\nexport { AbortController, AbortSignal }\n"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/abort-controller.umd.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 3 | * See LICENSE file in root directory for full license. 4 | */(function(a,b){"object"==typeof exports&&"undefined"!=typeof module?b(exports):"function"==typeof define&&define.amd?define(["exports"],b):(a=a||self,b(a.AbortControllerShim={}))})(this,function(a){'use strict';function b(a){return b="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},b(a)}function c(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function d(a,b){for(var c,d=0;d\n * @copyright 2015 Toru Nagashima. All rights reserved.\n * See LICENSE file in root directory for full license.\n */\n/**\n * @typedef {object} PrivateData\n * @property {EventTarget} eventTarget The event target.\n * @property {{type:string}} event The original event object.\n * @property {number} eventPhase The current event phase.\n * @property {EventTarget|null} currentTarget The current event target.\n * @property {boolean} canceled The flag to prevent default.\n * @property {boolean} stopped The flag to stop propagation.\n * @property {boolean} immediateStopped The flag to stop propagation immediately.\n * @property {Function|null} passiveListener The listener if the current listener is passive. Otherwise this is null.\n * @property {number} timeStamp The unix time.\n * @private\n */\n\n/**\n * Private data for event wrappers.\n * @type {WeakMap}\n * @private\n */\nconst privateData = new WeakMap();\n\n/**\n * Cache for wrapper classes.\n * @type {WeakMap}\n * @private\n */\nconst wrappers = new WeakMap();\n\n/**\n * Get private data.\n * @param {Event} event The event object to get private data.\n * @returns {PrivateData} The private data of the event.\n * @private\n */\nfunction pd(event) {\n const retv = privateData.get(event);\n console.assert(\n retv != null,\n \"'this' is expected an Event object, but got\",\n event\n );\n return retv\n}\n\n/**\n * https://dom.spec.whatwg.org/#set-the-canceled-flag\n * @param data {PrivateData} private data.\n */\nfunction setCancelFlag(data) {\n if (data.passiveListener != null) {\n if (\n typeof console !== \"undefined\" &&\n typeof console.error === \"function\"\n ) {\n console.error(\n \"Unable to preventDefault inside passive event listener invocation.\",\n data.passiveListener\n );\n }\n return\n }\n if (!data.event.cancelable) {\n return\n }\n\n data.canceled = true;\n if (typeof data.event.preventDefault === \"function\") {\n data.event.preventDefault();\n }\n}\n\n/**\n * @see https://dom.spec.whatwg.org/#interface-event\n * @private\n */\n/**\n * The event wrapper.\n * @constructor\n * @param {EventTarget} eventTarget The event target of this dispatching.\n * @param {Event|{type:string}} event The original event to wrap.\n */\nfunction Event(eventTarget, event) {\n privateData.set(this, {\n eventTarget,\n event,\n eventPhase: 2,\n currentTarget: eventTarget,\n canceled: false,\n stopped: false,\n immediateStopped: false,\n passiveListener: null,\n timeStamp: event.timeStamp || Date.now(),\n });\n\n // https://heycam.github.io/webidl/#Unforgeable\n Object.defineProperty(this, \"isTrusted\", { value: false, enumerable: true });\n\n // Define accessors\n const keys = Object.keys(event);\n for (let i = 0; i < keys.length; ++i) {\n const key = keys[i];\n if (!(key in this)) {\n Object.defineProperty(this, key, defineRedirectDescriptor(key));\n }\n }\n}\n\n// Should be enumerable, but class methods are not enumerable.\nEvent.prototype = {\n /**\n * The type of this event.\n * @type {string}\n */\n get type() {\n return pd(this).event.type\n },\n\n /**\n * The target of this event.\n * @type {EventTarget}\n */\n get target() {\n return pd(this).eventTarget\n },\n\n /**\n * The target of this event.\n * @type {EventTarget}\n */\n get currentTarget() {\n return pd(this).currentTarget\n },\n\n /**\n * @returns {EventTarget[]} The composed path of this event.\n */\n composedPath() {\n const currentTarget = pd(this).currentTarget;\n if (currentTarget == null) {\n return []\n }\n return [currentTarget]\n },\n\n /**\n * Constant of NONE.\n * @type {number}\n */\n get NONE() {\n return 0\n },\n\n /**\n * Constant of CAPTURING_PHASE.\n * @type {number}\n */\n get CAPTURING_PHASE() {\n return 1\n },\n\n /**\n * Constant of AT_TARGET.\n * @type {number}\n */\n get AT_TARGET() {\n return 2\n },\n\n /**\n * Constant of BUBBLING_PHASE.\n * @type {number}\n */\n get BUBBLING_PHASE() {\n return 3\n },\n\n /**\n * The target of this event.\n * @type {number}\n */\n get eventPhase() {\n return pd(this).eventPhase\n },\n\n /**\n * Stop event bubbling.\n * @returns {void}\n */\n stopPropagation() {\n const data = pd(this);\n\n data.stopped = true;\n if (typeof data.event.stopPropagation === \"function\") {\n data.event.stopPropagation();\n }\n },\n\n /**\n * Stop event bubbling.\n * @returns {void}\n */\n stopImmediatePropagation() {\n const data = pd(this);\n\n data.stopped = true;\n data.immediateStopped = true;\n if (typeof data.event.stopImmediatePropagation === \"function\") {\n data.event.stopImmediatePropagation();\n }\n },\n\n /**\n * The flag to be bubbling.\n * @type {boolean}\n */\n get bubbles() {\n return Boolean(pd(this).event.bubbles)\n },\n\n /**\n * The flag to be cancelable.\n * @type {boolean}\n */\n get cancelable() {\n return Boolean(pd(this).event.cancelable)\n },\n\n /**\n * Cancel this event.\n * @returns {void}\n */\n preventDefault() {\n setCancelFlag(pd(this));\n },\n\n /**\n * The flag to indicate cancellation state.\n * @type {boolean}\n */\n get defaultPrevented() {\n return pd(this).canceled\n },\n\n /**\n * The flag to be composed.\n * @type {boolean}\n */\n get composed() {\n return Boolean(pd(this).event.composed)\n },\n\n /**\n * The unix time of this event.\n * @type {number}\n */\n get timeStamp() {\n return pd(this).timeStamp\n },\n\n /**\n * The target of this event.\n * @type {EventTarget}\n * @deprecated\n */\n get srcElement() {\n return pd(this).eventTarget\n },\n\n /**\n * The flag to stop event bubbling.\n * @type {boolean}\n * @deprecated\n */\n get cancelBubble() {\n return pd(this).stopped\n },\n set cancelBubble(value) {\n if (!value) {\n return\n }\n const data = pd(this);\n\n data.stopped = true;\n if (typeof data.event.cancelBubble === \"boolean\") {\n data.event.cancelBubble = true;\n }\n },\n\n /**\n * The flag to indicate cancellation state.\n * @type {boolean}\n * @deprecated\n */\n get returnValue() {\n return !pd(this).canceled\n },\n set returnValue(value) {\n if (!value) {\n setCancelFlag(pd(this));\n }\n },\n\n /**\n * Initialize this event object. But do nothing under event dispatching.\n * @param {string} type The event type.\n * @param {boolean} [bubbles=false] The flag to be possible to bubble up.\n * @param {boolean} [cancelable=false] The flag to be possible to cancel.\n * @deprecated\n */\n initEvent() {\n // Do nothing.\n },\n};\n\n// `constructor` is not enumerable.\nObject.defineProperty(Event.prototype, \"constructor\", {\n value: Event,\n configurable: true,\n writable: true,\n});\n\n// Ensure `event instanceof window.Event` is `true`.\nif (typeof window !== \"undefined\" && typeof window.Event !== \"undefined\") {\n Object.setPrototypeOf(Event.prototype, window.Event.prototype);\n\n // Make association for wrappers.\n wrappers.set(window.Event.prototype, Event);\n}\n\n/**\n * Get the property descriptor to redirect a given property.\n * @param {string} key Property name to define property descriptor.\n * @returns {PropertyDescriptor} The property descriptor to redirect the property.\n * @private\n */\nfunction defineRedirectDescriptor(key) {\n return {\n get() {\n return pd(this).event[key]\n },\n set(value) {\n pd(this).event[key] = value;\n },\n configurable: true,\n enumerable: true,\n }\n}\n\n/**\n * Get the property descriptor to call a given method property.\n * @param {string} key Property name to define property descriptor.\n * @returns {PropertyDescriptor} The property descriptor to call the method property.\n * @private\n */\nfunction defineCallDescriptor(key) {\n return {\n value() {\n const event = pd(this).event;\n return event[key].apply(event, arguments)\n },\n configurable: true,\n enumerable: true,\n }\n}\n\n/**\n * Define new wrapper class.\n * @param {Function} BaseEvent The base wrapper class.\n * @param {Object} proto The prototype of the original event.\n * @returns {Function} The defined wrapper class.\n * @private\n */\nfunction defineWrapper(BaseEvent, proto) {\n const keys = Object.keys(proto);\n if (keys.length === 0) {\n return BaseEvent\n }\n\n /** CustomEvent */\n function CustomEvent(eventTarget, event) {\n BaseEvent.call(this, eventTarget, event);\n }\n\n CustomEvent.prototype = Object.create(BaseEvent.prototype, {\n constructor: { value: CustomEvent, configurable: true, writable: true },\n });\n\n // Define accessors.\n for (let i = 0; i < keys.length; ++i) {\n const key = keys[i];\n if (!(key in BaseEvent.prototype)) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, key);\n const isFunc = typeof descriptor.value === \"function\";\n Object.defineProperty(\n CustomEvent.prototype,\n key,\n isFunc\n ? defineCallDescriptor(key)\n : defineRedirectDescriptor(key)\n );\n }\n }\n\n return CustomEvent\n}\n\n/**\n * Get the wrapper class of a given prototype.\n * @param {Object} proto The prototype of the original event to get its wrapper.\n * @returns {Function} The wrapper class.\n * @private\n */\nfunction getWrapper(proto) {\n if (proto == null || proto === Object.prototype) {\n return Event\n }\n\n let wrapper = wrappers.get(proto);\n if (wrapper == null) {\n wrapper = defineWrapper(getWrapper(Object.getPrototypeOf(proto)), proto);\n wrappers.set(proto, wrapper);\n }\n return wrapper\n}\n\n/**\n * Wrap a given event to management a dispatching.\n * @param {EventTarget} eventTarget The event target of this dispatching.\n * @param {Object} event The event to wrap.\n * @returns {Event} The wrapper instance.\n * @private\n */\nfunction wrapEvent(eventTarget, event) {\n const Wrapper = getWrapper(Object.getPrototypeOf(event));\n return new Wrapper(eventTarget, event)\n}\n\n/**\n * Get the immediateStopped flag of a given event.\n * @param {Event} event The event to get.\n * @returns {boolean} The flag to stop propagation immediately.\n * @private\n */\nfunction isStopped(event) {\n return pd(event).immediateStopped\n}\n\n/**\n * Set the current event phase of a given event.\n * @param {Event} event The event to set current target.\n * @param {number} eventPhase New event phase.\n * @returns {void}\n * @private\n */\nfunction setEventPhase(event, eventPhase) {\n pd(event).eventPhase = eventPhase;\n}\n\n/**\n * Set the current target of a given event.\n * @param {Event} event The event to set current target.\n * @param {EventTarget|null} currentTarget New current target.\n * @returns {void}\n * @private\n */\nfunction setCurrentTarget(event, currentTarget) {\n pd(event).currentTarget = currentTarget;\n}\n\n/**\n * Set a passive listener of a given event.\n * @param {Event} event The event to set current target.\n * @param {Function|null} passiveListener New passive listener.\n * @returns {void}\n * @private\n */\nfunction setPassiveListener(event, passiveListener) {\n pd(event).passiveListener = passiveListener;\n}\n\n/**\n * @typedef {object} ListenerNode\n * @property {Function} listener\n * @property {1|2|3} listenerType\n * @property {boolean} passive\n * @property {boolean} once\n * @property {ListenerNode|null} next\n * @private\n */\n\n/**\n * @type {WeakMap>}\n * @private\n */\nconst listenersMap = new WeakMap();\n\n// Listener types\nconst CAPTURE = 1;\nconst BUBBLE = 2;\nconst ATTRIBUTE = 3;\n\n/**\n * Check whether a given value is an object or not.\n * @param {any} x The value to check.\n * @returns {boolean} `true` if the value is an object.\n */\nfunction isObject(x) {\n return x !== null && typeof x === \"object\" //eslint-disable-line no-restricted-syntax\n}\n\n/**\n * Get listeners.\n * @param {EventTarget} eventTarget The event target to get.\n * @returns {Map} The listeners.\n * @private\n */\nfunction getListeners(eventTarget) {\n const listeners = listenersMap.get(eventTarget);\n if (listeners == null) {\n throw new TypeError(\n \"'this' is expected an EventTarget object, but got another value.\"\n )\n }\n return listeners\n}\n\n/**\n * Get the property descriptor for the event attribute of a given event.\n * @param {string} eventName The event name to get property descriptor.\n * @returns {PropertyDescriptor} The property descriptor.\n * @private\n */\nfunction defineEventAttributeDescriptor(eventName) {\n return {\n get() {\n const listeners = getListeners(this);\n let node = listeners.get(eventName);\n while (node != null) {\n if (node.listenerType === ATTRIBUTE) {\n return node.listener\n }\n node = node.next;\n }\n return null\n },\n\n set(listener) {\n if (typeof listener !== \"function\" && !isObject(listener)) {\n listener = null; // eslint-disable-line no-param-reassign\n }\n const listeners = getListeners(this);\n\n // Traverse to the tail while removing old value.\n let prev = null;\n let node = listeners.get(eventName);\n while (node != null) {\n if (node.listenerType === ATTRIBUTE) {\n // Remove old value.\n if (prev !== null) {\n prev.next = node.next;\n } else if (node.next !== null) {\n listeners.set(eventName, node.next);\n } else {\n listeners.delete(eventName);\n }\n } else {\n prev = node;\n }\n\n node = node.next;\n }\n\n // Add new value.\n if (listener !== null) {\n const newNode = {\n listener,\n listenerType: ATTRIBUTE,\n passive: false,\n once: false,\n next: null,\n };\n if (prev === null) {\n listeners.set(eventName, newNode);\n } else {\n prev.next = newNode;\n }\n }\n },\n configurable: true,\n enumerable: true,\n }\n}\n\n/**\n * Define an event attribute (e.g. `eventTarget.onclick`).\n * @param {Object} eventTargetPrototype The event target prototype to define an event attrbite.\n * @param {string} eventName The event name to define.\n * @returns {void}\n */\nfunction defineEventAttribute(eventTargetPrototype, eventName) {\n Object.defineProperty(\n eventTargetPrototype,\n `on${eventName}`,\n defineEventAttributeDescriptor(eventName)\n );\n}\n\n/**\n * Define a custom EventTarget with event attributes.\n * @param {string[]} eventNames Event names for event attributes.\n * @returns {EventTarget} The custom EventTarget.\n * @private\n */\nfunction defineCustomEventTarget(eventNames) {\n /** CustomEventTarget */\n function CustomEventTarget() {\n EventTarget.call(this);\n }\n\n CustomEventTarget.prototype = Object.create(EventTarget.prototype, {\n constructor: {\n value: CustomEventTarget,\n configurable: true,\n writable: true,\n },\n });\n\n for (let i = 0; i < eventNames.length; ++i) {\n defineEventAttribute(CustomEventTarget.prototype, eventNames[i]);\n }\n\n return CustomEventTarget\n}\n\n/**\n * EventTarget.\n *\n * - This is constructor if no arguments.\n * - This is a function which returns a CustomEventTarget constructor if there are arguments.\n *\n * For example:\n *\n * class A extends EventTarget {}\n * class B extends EventTarget(\"message\") {}\n * class C extends EventTarget(\"message\", \"error\") {}\n * class D extends EventTarget([\"message\", \"error\"]) {}\n */\nfunction EventTarget() {\n /*eslint-disable consistent-return */\n if (this instanceof EventTarget) {\n listenersMap.set(this, new Map());\n return\n }\n if (arguments.length === 1 && Array.isArray(arguments[0])) {\n return defineCustomEventTarget(arguments[0])\n }\n if (arguments.length > 0) {\n const types = new Array(arguments.length);\n for (let i = 0; i < arguments.length; ++i) {\n types[i] = arguments[i];\n }\n return defineCustomEventTarget(types)\n }\n throw new TypeError(\"Cannot call a class as a function\")\n /*eslint-enable consistent-return */\n}\n\n// Should be enumerable, but class methods are not enumerable.\nEventTarget.prototype = {\n /**\n * Add a given listener to this event target.\n * @param {string} eventName The event name to add.\n * @param {Function} listener The listener to add.\n * @param {boolean|{capture?:boolean,passive?:boolean,once?:boolean}} [options] The options for this listener.\n * @returns {void}\n */\n addEventListener(eventName, listener, options) {\n if (listener == null) {\n return\n }\n if (typeof listener !== \"function\" && !isObject(listener)) {\n throw new TypeError(\"'listener' should be a function or an object.\")\n }\n\n const listeners = getListeners(this);\n const optionsIsObj = isObject(options);\n const capture = optionsIsObj\n ? Boolean(options.capture)\n : Boolean(options);\n const listenerType = capture ? CAPTURE : BUBBLE;\n const newNode = {\n listener,\n listenerType,\n passive: optionsIsObj && Boolean(options.passive),\n once: optionsIsObj && Boolean(options.once),\n next: null,\n };\n\n // Set it as the first node if the first node is null.\n let node = listeners.get(eventName);\n if (node === undefined) {\n listeners.set(eventName, newNode);\n return\n }\n\n // Traverse to the tail while checking duplication..\n let prev = null;\n while (node != null) {\n if (\n node.listener === listener &&\n node.listenerType === listenerType\n ) {\n // Should ignore duplication.\n return\n }\n prev = node;\n node = node.next;\n }\n\n // Add it.\n prev.next = newNode;\n },\n\n /**\n * Remove a given listener from this event target.\n * @param {string} eventName The event name to remove.\n * @param {Function} listener The listener to remove.\n * @param {boolean|{capture?:boolean,passive?:boolean,once?:boolean}} [options] The options for this listener.\n * @returns {void}\n */\n removeEventListener(eventName, listener, options) {\n if (listener == null) {\n return\n }\n\n const listeners = getListeners(this);\n const capture = isObject(options)\n ? Boolean(options.capture)\n : Boolean(options);\n const listenerType = capture ? CAPTURE : BUBBLE;\n\n let prev = null;\n let node = listeners.get(eventName);\n while (node != null) {\n if (\n node.listener === listener &&\n node.listenerType === listenerType\n ) {\n if (prev !== null) {\n prev.next = node.next;\n } else if (node.next !== null) {\n listeners.set(eventName, node.next);\n } else {\n listeners.delete(eventName);\n }\n return\n }\n\n prev = node;\n node = node.next;\n }\n },\n\n /**\n * Dispatch a given event.\n * @param {Event|{type:string}} event The event to dispatch.\n * @returns {boolean} `false` if canceled.\n */\n dispatchEvent(event) {\n if (event == null || typeof event.type !== \"string\") {\n throw new TypeError('\"event.type\" should be a string.')\n }\n\n // If listeners aren't registered, terminate.\n const listeners = getListeners(this);\n const eventName = event.type;\n let node = listeners.get(eventName);\n if (node == null) {\n return true\n }\n\n // Since we cannot rewrite several properties, so wrap object.\n const wrappedEvent = wrapEvent(this, event);\n\n // This doesn't process capturing phase and bubbling phase.\n // This isn't participating in a tree.\n let prev = null;\n while (node != null) {\n // Remove this listener if it's once\n if (node.once) {\n if (prev !== null) {\n prev.next = node.next;\n } else if (node.next !== null) {\n listeners.set(eventName, node.next);\n } else {\n listeners.delete(eventName);\n }\n } else {\n prev = node;\n }\n\n // Call this listener\n setPassiveListener(\n wrappedEvent,\n node.passive ? node.listener : null\n );\n if (typeof node.listener === \"function\") {\n try {\n node.listener.call(this, wrappedEvent);\n } catch (err) {\n if (\n typeof console !== \"undefined\" &&\n typeof console.error === \"function\"\n ) {\n console.error(err);\n }\n }\n } else if (\n node.listenerType !== ATTRIBUTE &&\n typeof node.listener.handleEvent === \"function\"\n ) {\n node.listener.handleEvent(wrappedEvent);\n }\n\n // Break if `event.stopImmediatePropagation` was called.\n if (isStopped(wrappedEvent)) {\n break\n }\n\n node = node.next;\n }\n setPassiveListener(wrappedEvent, null);\n setEventPhase(wrappedEvent, 0);\n setCurrentTarget(wrappedEvent, null);\n\n return !wrappedEvent.defaultPrevented\n },\n};\n\n// `constructor` is not enumerable.\nObject.defineProperty(EventTarget.prototype, \"constructor\", {\n value: EventTarget,\n configurable: true,\n writable: true,\n});\n\n// Ensure `eventTarget instanceof window.EventTarget` is `true`.\nif (\n typeof window !== \"undefined\" &&\n typeof window.EventTarget !== \"undefined\"\n) {\n Object.setPrototypeOf(EventTarget.prototype, window.EventTarget.prototype);\n}\n\nexport default EventTarget;\nexport { defineEventAttribute, EventTarget };\n//# sourceMappingURL=event-target-shim.mjs.map\n","import {\n // Event,\n EventTarget,\n // Type,\n defineEventAttribute,\n} from \"event-target-shim\"\n\n// Known Limitation\n// Use `any` because the type of `AbortSignal` in `lib.dom.d.ts` is wrong and\n// to make assignable our `AbortSignal` into that.\n// https://github.com/Microsoft/TSJS-lib-generator/pull/623\ntype Events = {\n abort: any // Event & Type<\"abort\">\n}\ntype EventAttributes = {\n onabort: any // Event & Type<\"abort\">\n}\n\n/**\n * The signal class.\n * @see https://dom.spec.whatwg.org/#abortsignal\n */\nexport default class AbortSignal extends EventTarget {\n /**\n * AbortSignal cannot be constructed directly.\n */\n public constructor() {\n super()\n throw new TypeError(\"AbortSignal cannot be constructed directly\")\n }\n\n /**\n * Returns `true` if this `AbortSignal`'s `AbortController` has signaled to abort, and `false` otherwise.\n */\n public get aborted(): boolean {\n const aborted = abortedFlags.get(this)\n if (typeof aborted !== \"boolean\") {\n throw new TypeError(\n `Expected 'this' to be an 'AbortSignal' object, but got ${\n this === null ? \"null\" : typeof this\n }`,\n )\n }\n return aborted\n }\n}\ndefineEventAttribute(AbortSignal.prototype, \"abort\")\n\n/**\n * Create an AbortSignal object.\n */\nexport function createAbortSignal(): AbortSignal {\n const signal = Object.create(AbortSignal.prototype)\n EventTarget.call(signal)\n abortedFlags.set(signal, false)\n return signal\n}\n\n/**\n * Abort a given signal.\n */\nexport function abortSignal(signal: AbortSignal): void {\n if (abortedFlags.get(signal) !== false) {\n return\n }\n\n abortedFlags.set(signal, true)\n signal.dispatchEvent<\"abort\">({ type: \"abort\" })\n}\n\n/**\n * Aborted flag for each instances.\n */\nconst abortedFlags = new WeakMap()\n\n// Properties should be enumerable.\nObject.defineProperties(AbortSignal.prototype, {\n aborted: { enumerable: true },\n})\n\n// `toString()` should return `\"[object AbortSignal]\"`\nif (typeof Symbol === \"function\" && typeof Symbol.toStringTag === \"symbol\") {\n Object.defineProperty(AbortSignal.prototype, Symbol.toStringTag, {\n configurable: true,\n value: \"AbortSignal\",\n })\n}\n","import AbortSignal, { abortSignal, createAbortSignal } from \"./abort-signal\"\n\n/**\n * The AbortController.\n * @see https://dom.spec.whatwg.org/#abortcontroller\n */\nexport default class AbortController {\n /**\n * Initialize this controller.\n */\n public constructor() {\n signals.set(this, createAbortSignal())\n }\n\n /**\n * Returns the `AbortSignal` object associated with this object.\n */\n public get signal(): AbortSignal {\n return getSignal(this)\n }\n\n /**\n * Abort and signal to any observers that the associated activity is to be aborted.\n */\n public abort(): void {\n abortSignal(getSignal(this))\n }\n}\n\n/**\n * Associated signals.\n */\nconst signals = new WeakMap()\n\n/**\n * Get the associated signal of a given controller.\n */\nfunction getSignal(controller: AbortController): AbortSignal {\n const signal = signals.get(controller)\n if (signal == null) {\n throw new TypeError(\n `Expected 'this' to be an 'AbortController' object, but got ${\n controller === null ? \"null\" : typeof controller\n }`,\n )\n }\n return signal\n}\n\n// Properties should be enumerable.\nObject.defineProperties(AbortController.prototype, {\n signal: { enumerable: true },\n abort: { enumerable: true },\n})\n\nif (typeof Symbol === \"function\" && typeof Symbol.toStringTag === \"symbol\") {\n Object.defineProperty(AbortController.prototype, Symbol.toStringTag, {\n configurable: true,\n value: \"AbortController\",\n })\n}\n\nexport { AbortController, AbortSignal }\n"],"names":["pd","event","retv","privateData","get","console","assert","setCancelFlag","data","passiveListener","cancelable","canceled","preventDefault","error","Event","eventTarget","set","eventPhase","currentTarget","stopped","immediateStopped","timeStamp","Date","now","Object","defineProperty","value","enumerable","key","keys","i","length","defineRedirectDescriptor","configurable","defineCallDescriptor","apply","arguments","defineWrapper","BaseEvent","proto","CustomEvent","call","prototype","create","constructor","writable","descriptor","getOwnPropertyDescriptor","isFunc","getWrapper","wrapper","wrappers","getPrototypeOf","wrapEvent","Wrapper","isStopped","setEventPhase","setCurrentTarget","setPassiveListener","createAbortSignal","signal","AbortSignal","EventTarget","abortedFlags","abortSignal","dispatchEvent","type","getSignal","controller","signals","TypeError","WeakMap","target","composedPath","NONE","CAPTURING_PHASE","AT_TARGET","BUBBLING_PHASE","stopPropagation","stopImmediatePropagation","bubbles","defaultPrevented","composed","srcElement","cancelBubble","returnValue","initEvent","window","setPrototypeOf","aborted","defineEventAttribute","defineProperties","Symbol","_typeof","toStringTag","AbortController","abort"],"mappings":"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"} -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | const babel = require("rollup-plugin-babel") 4 | const commonjs = require("rollup-plugin-commonjs") 5 | // const json = require("rollup-plugin-json") 6 | const resolve = require("rollup-plugin-node-resolve") 7 | const sourcemaps = require("rollup-plugin-sourcemaps") 8 | const typescript = require("rollup-plugin-typescript") 9 | 10 | module.exports = function(config) { 11 | config.set({ 12 | browsers: ["Chrome", "Firefox", "IE"], 13 | files: ["test/index.ts", "test/polyfill.ts"], 14 | frameworks: ["mocha"], 15 | mime: { 16 | "text/javascript": ["ts"], 17 | }, 18 | reporters: ["progress", "growl"], 19 | preprocessors: { 20 | "test/*.ts": ["rollup"], 21 | }, 22 | rollupPreprocessor: { 23 | output: { 24 | format: "iife", 25 | name: "AbortControllerShim", 26 | sourcemap: "inline", 27 | }, 28 | plugins: [ 29 | resolve({ browser: true, preferBuiltins: false }), 30 | sourcemaps(), 31 | commonjs(), 32 | typescript({ module: "es2015" }), 33 | babel({ 34 | babelrc: false, 35 | extensions: [".js", ".mjs", ".ts"], 36 | include: ["**/*.mjs", "**/*.ts"], 37 | presets: [ 38 | [ 39 | "@babel/env", 40 | { 41 | modules: false, 42 | targets: { ie: "11" }, 43 | }, 44 | ], 45 | ], 46 | sourceMaps: true, 47 | }), 48 | ], 49 | }, 50 | }) 51 | } 52 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "abort-controller", 3 | "version": "3.0.0", 4 | "description": "An implementation of WHATWG AbortController interface.", 5 | "main": "dist/abort-controller", 6 | "files": [ 7 | "dist", 8 | "polyfill.*", 9 | "browser.*" 10 | ], 11 | "engines": { 12 | "node": ">=6.5" 13 | }, 14 | "dependencies": { 15 | "event-target-shim": "^5.0.0" 16 | }, 17 | "browser": "./browser.js", 18 | "devDependencies": { 19 | "@babel/core": "^7.2.2", 20 | "@babel/plugin-transform-modules-commonjs": "^7.2.0", 21 | "@babel/preset-env": "^7.3.0", 22 | "@babel/register": "^7.0.0", 23 | "@mysticatea/eslint-plugin": "^8.0.1", 24 | "@mysticatea/spy": "^0.1.2", 25 | "@types/mocha": "^5.2.5", 26 | "@types/node": "^10.12.18", 27 | "assert": "^1.4.1", 28 | "codecov": "^3.1.0", 29 | "dts-bundle-generator": "^2.0.0", 30 | "eslint": "^5.12.1", 31 | "karma": "^3.1.4", 32 | "karma-chrome-launcher": "^2.2.0", 33 | "karma-coverage": "^1.1.2", 34 | "karma-firefox-launcher": "^1.1.0", 35 | "karma-growl-reporter": "^1.0.0", 36 | "karma-ie-launcher": "^1.0.0", 37 | "karma-mocha": "^1.3.0", 38 | "karma-rollup-preprocessor": "^7.0.0-rc.2", 39 | "mocha": "^5.2.0", 40 | "npm-run-all": "^4.1.5", 41 | "nyc": "^13.1.0", 42 | "opener": "^1.5.1", 43 | "rimraf": "^2.6.3", 44 | "rollup": "^1.1.2", 45 | "rollup-plugin-babel": "^4.3.2", 46 | "rollup-plugin-babel-minify": "^7.0.0", 47 | "rollup-plugin-commonjs": "^9.2.0", 48 | "rollup-plugin-node-resolve": "^4.0.0", 49 | "rollup-plugin-sourcemaps": "^0.4.2", 50 | "rollup-plugin-typescript": "^1.0.0", 51 | "rollup-watch": "^4.3.1", 52 | "ts-node": "^8.0.1", 53 | "type-tester": "^1.0.0", 54 | "typescript": "^3.2.4" 55 | }, 56 | "scripts": { 57 | "preversion": "npm test", 58 | "version": "npm run -s build && git add dist/*", 59 | "postversion": "git push && git push --tags", 60 | "clean": "rimraf .nyc_output coverage", 61 | "coverage": "opener coverage/lcov-report/index.html", 62 | "lint": "eslint . --ext .ts", 63 | "build": "run-s -s build:*", 64 | "build:rollup": "rollup -c", 65 | "build:dts": "dts-bundle-generator -o dist/abort-controller.d.ts src/abort-controller.ts && ts-node scripts/fix-dts", 66 | "test": "run-s -s lint test:*", 67 | "test:mocha": "nyc mocha test/*.ts", 68 | "test:karma": "karma start --single-run", 69 | "watch": "run-p -s watch:*", 70 | "watch:mocha": "mocha test/*.ts --require ts-node/register --watch-extensions ts --watch --growl", 71 | "watch:karma": "karma start --watch", 72 | "codecov": "codecov" 73 | }, 74 | "repository": { 75 | "type": "git", 76 | "url": "git+https://github.com/mysticatea/abort-controller.git" 77 | }, 78 | "keywords": [ 79 | "w3c", 80 | "whatwg", 81 | "event", 82 | "events", 83 | "abort", 84 | "cancel", 85 | "abortcontroller", 86 | "abortsignal", 87 | "controller", 88 | "signal", 89 | "shim" 90 | ], 91 | "author": "Toru Nagashima (https://github.com/mysticatea)", 92 | "license": "MIT", 93 | "bugs": { 94 | "url": "https://github.com/mysticatea/abort-controller/issues" 95 | }, 96 | "homepage": "https://github.com/mysticatea/abort-controller#readme" 97 | } 98 | -------------------------------------------------------------------------------- /polyfill.js: -------------------------------------------------------------------------------- 1 | /*globals require, self, window */ 2 | "use strict" 3 | 4 | const ac = require("./dist/abort-controller") 5 | 6 | /*eslint-disable @mysticatea/prettier */ 7 | const g = 8 | typeof self !== "undefined" ? self : 9 | typeof window !== "undefined" ? window : 10 | typeof global !== "undefined" ? global : 11 | /* otherwise */ undefined 12 | /*eslint-enable @mysticatea/prettier */ 13 | 14 | if (g) { 15 | if (typeof g.AbortController === "undefined") { 16 | g.AbortController = ac.AbortController 17 | } 18 | if (typeof g.AbortSignal === "undefined") { 19 | g.AbortSignal = ac.AbortSignal 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /polyfill.mjs: -------------------------------------------------------------------------------- 1 | /*globals self, window */ 2 | import * as ac from "./dist/abort-controller" 3 | 4 | /*eslint-disable @mysticatea/prettier */ 5 | const g = 6 | typeof self !== "undefined" ? self : 7 | typeof window !== "undefined" ? window : 8 | typeof global !== "undefined" ? global : 9 | /* otherwise */ undefined 10 | /*eslint-enable @mysticatea/prettier */ 11 | 12 | if (g) { 13 | if (typeof g.AbortController === "undefined") { 14 | g.AbortController = ac.AbortController 15 | } 16 | if (typeof g.AbortSignal === "undefined") { 17 | g.AbortSignal = ac.AbortSignal 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import babel from "rollup-plugin-babel" 2 | import minify from "rollup-plugin-babel-minify" 3 | import resolve from "rollup-plugin-node-resolve" 4 | import typescript from "rollup-plugin-typescript" 5 | 6 | const banner = `/** 7 | * @author Toru Nagashima 8 | * See LICENSE file in root directory for full license. 9 | */` 10 | const cjsOutro = `module.exports = AbortController 11 | module.exports.AbortController = module.exports["default"] = AbortController 12 | module.exports.AbortSignal = AbortSignal 13 | ` 14 | const umdOutro = `if (typeof module === "undefined" && typeof define === "undefined") { 15 | var global = Function("return this")() 16 | if (typeof global.AbortController === "undefined") { 17 | global.AbortController = AbortController 18 | global.AbortSignal = AbortSignal 19 | } 20 | } 21 | ` 22 | 23 | export default [ 24 | { 25 | external: ["event-target-shim"], 26 | input: "src/abort-controller.ts", 27 | output: { 28 | banner, 29 | file: "dist/abort-controller.mjs", 30 | format: "es", 31 | sourcemap: true, 32 | }, 33 | plugins: [typescript({ module: "es2015" })], 34 | }, 35 | { 36 | external: ["event-target-shim"], 37 | input: "src/abort-controller.ts", 38 | output: { 39 | banner, 40 | file: "dist/abort-controller.js", 41 | format: "cjs", 42 | outro: cjsOutro, 43 | sourcemap: true, 44 | }, 45 | plugins: [typescript({ module: "es2015" })], 46 | }, 47 | { 48 | input: "src/abort-controller.ts", 49 | output: { 50 | file: "dist/abort-controller.umd.js", 51 | format: "umd", 52 | name: "AbortControllerShim", 53 | outro: umdOutro, 54 | sourcemap: true, 55 | }, 56 | plugins: [ 57 | resolve(), 58 | typescript({ module: "es2015" }), 59 | babel({ 60 | babelrc: false, 61 | extensions: [".mjs", ".ts"], 62 | include: ["**/*.mjs", "**/*.ts"], 63 | presets: [ 64 | [ 65 | "@babel/env", 66 | { 67 | modules: false, 68 | targets: { ie: "11" }, 69 | }, 70 | ], 71 | ], 72 | sourceMaps: true, 73 | }), 74 | minify({ 75 | comments: false, 76 | banner, 77 | sourceMap: true, 78 | }), 79 | ], 80 | }, 81 | ] 82 | -------------------------------------------------------------------------------- /scripts/fix-dts.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs" 2 | 3 | fs.writeFileSync( 4 | "dist/abort-controller.d.ts", 5 | [ 6 | fs 7 | .readFileSync("dist/abort-controller.d.ts", "utf8") 8 | .replace(/export declare type/gu, "type") 9 | .replace(/export (?:declare|default) class/gu, "declare class") 10 | .replace(/\t/gu, " ") 11 | .replace(/'/gu, '"') 12 | .replace(/;\n/gu, "\n"), 13 | "", 14 | "export default AbortController", 15 | "export { AbortController, AbortSignal }", 16 | "", 17 | ].join("\n"), 18 | ) 19 | -------------------------------------------------------------------------------- /src/abort-controller.ts: -------------------------------------------------------------------------------- 1 | import AbortSignal, { abortSignal, createAbortSignal } from "./abort-signal" 2 | 3 | /** 4 | * The AbortController. 5 | * @see https://dom.spec.whatwg.org/#abortcontroller 6 | */ 7 | export default class AbortController { 8 | /** 9 | * Initialize this controller. 10 | */ 11 | public constructor() { 12 | signals.set(this, createAbortSignal()) 13 | } 14 | 15 | /** 16 | * Returns the `AbortSignal` object associated with this object. 17 | */ 18 | public get signal(): AbortSignal { 19 | return getSignal(this) 20 | } 21 | 22 | /** 23 | * Abort and signal to any observers that the associated activity is to be aborted. 24 | */ 25 | public abort(): void { 26 | abortSignal(getSignal(this)) 27 | } 28 | } 29 | 30 | /** 31 | * Associated signals. 32 | */ 33 | const signals = new WeakMap() 34 | 35 | /** 36 | * Get the associated signal of a given controller. 37 | */ 38 | function getSignal(controller: AbortController): AbortSignal { 39 | const signal = signals.get(controller) 40 | if (signal == null) { 41 | throw new TypeError( 42 | `Expected 'this' to be an 'AbortController' object, but got ${ 43 | controller === null ? "null" : typeof controller 44 | }`, 45 | ) 46 | } 47 | return signal 48 | } 49 | 50 | // Properties should be enumerable. 51 | Object.defineProperties(AbortController.prototype, { 52 | signal: { enumerable: true }, 53 | abort: { enumerable: true }, 54 | }) 55 | 56 | if (typeof Symbol === "function" && typeof Symbol.toStringTag === "symbol") { 57 | Object.defineProperty(AbortController.prototype, Symbol.toStringTag, { 58 | configurable: true, 59 | value: "AbortController", 60 | }) 61 | } 62 | 63 | export { AbortController, AbortSignal } 64 | -------------------------------------------------------------------------------- /src/abort-signal.ts: -------------------------------------------------------------------------------- 1 | import { 2 | // Event, 3 | EventTarget, 4 | // Type, 5 | defineEventAttribute, 6 | } from "event-target-shim" 7 | 8 | // Known Limitation 9 | // Use `any` because the type of `AbortSignal` in `lib.dom.d.ts` is wrong and 10 | // to make assignable our `AbortSignal` into that. 11 | // https://github.com/Microsoft/TSJS-lib-generator/pull/623 12 | type Events = { 13 | abort: any // Event & Type<"abort"> 14 | } 15 | type EventAttributes = { 16 | onabort: any // Event & Type<"abort"> 17 | } 18 | 19 | /** 20 | * The signal class. 21 | * @see https://dom.spec.whatwg.org/#abortsignal 22 | */ 23 | export default class AbortSignal extends EventTarget { 24 | /** 25 | * AbortSignal cannot be constructed directly. 26 | */ 27 | public constructor() { 28 | super() 29 | throw new TypeError("AbortSignal cannot be constructed directly") 30 | } 31 | 32 | /** 33 | * Returns `true` if this `AbortSignal`'s `AbortController` has signaled to abort, and `false` otherwise. 34 | */ 35 | public get aborted(): boolean { 36 | const aborted = abortedFlags.get(this) 37 | if (typeof aborted !== "boolean") { 38 | throw new TypeError( 39 | `Expected 'this' to be an 'AbortSignal' object, but got ${ 40 | this === null ? "null" : typeof this 41 | }`, 42 | ) 43 | } 44 | return aborted 45 | } 46 | } 47 | defineEventAttribute(AbortSignal.prototype, "abort") 48 | 49 | /** 50 | * Create an AbortSignal object. 51 | */ 52 | export function createAbortSignal(): AbortSignal { 53 | const signal = Object.create(AbortSignal.prototype) 54 | EventTarget.call(signal) 55 | abortedFlags.set(signal, false) 56 | return signal 57 | } 58 | 59 | /** 60 | * Abort a given signal. 61 | */ 62 | export function abortSignal(signal: AbortSignal): void { 63 | if (abortedFlags.get(signal) !== false) { 64 | return 65 | } 66 | 67 | abortedFlags.set(signal, true) 68 | signal.dispatchEvent<"abort">({ type: "abort" }) 69 | } 70 | 71 | /** 72 | * Aborted flag for each instances. 73 | */ 74 | const abortedFlags = new WeakMap() 75 | 76 | // Properties should be enumerable. 77 | Object.defineProperties(AbortSignal.prototype, { 78 | aborted: { enumerable: true }, 79 | }) 80 | 81 | // `toString()` should return `"[object AbortSignal]"` 82 | if (typeof Symbol === "function" && typeof Symbol.toStringTag === "symbol") { 83 | Object.defineProperty(AbortSignal.prototype, Symbol.toStringTag, { 84 | configurable: true, 85 | value: "AbortSignal", 86 | }) 87 | } 88 | -------------------------------------------------------------------------------- /test/fixtures/types.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AbortController as AbortControllerShim, 3 | AbortSignal as AbortSignalShim, 4 | } from "../../src/abort-controller" 5 | 6 | function signalCallback(as: AbortSignal) {} 7 | function signalShimCallback(as: AbortSignalShim) {} 8 | function controllerCallback(ac: AbortController) {} 9 | function controllerShimCallback(ac: AbortControllerShim) {} 10 | function abortCallback(this: AbortSignal, ev: Event) {} 11 | 12 | const controller = new AbortController() 13 | const controllerShim = new AbortControllerShim() 14 | const signal = controller.signal 15 | const signalShim = controllerShim.signal 16 | 17 | signalCallback(signal) 18 | signalCallback(signalShim) 19 | 20 | signalShimCallback(signalShim) 21 | 22 | controllerCallback(controller) 23 | controllerCallback(controllerShim) 24 | 25 | controllerShimCallback(controllerShim) 26 | 27 | if (signalShim.aborted === false) { 28 | signalShim.addEventListener("abort", abortCallback) 29 | signalShim.removeEventListener("abort", abortCallback) 30 | signalShim.onabort = null 31 | signalShim.onabort = abortCallback 32 | } 33 | controllerShim.abort() 34 | -------------------------------------------------------------------------------- /test/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 3 | * See LICENSE file in root directory for full license. 4 | */ 5 | import assert from "assert" 6 | import { AbortController, AbortSignal } from "../src/abort-controller" 7 | import { spy } from "@mysticatea/spy" 8 | 9 | /*globals EventTarget */ 10 | const HAS_EVENT_TARGET_INTERFACE = typeof EventTarget !== "undefined" 11 | const SUPPORTS_TOSTRINGTAG = 12 | typeof Symbol === "function" && typeof Symbol.toStringTag === "symbol" 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | describe("AbortController", () => { 19 | let controller: AbortController 20 | 21 | beforeEach(() => { 22 | controller = new AbortController() 23 | }) 24 | 25 | it("should not be callable", () => { 26 | assert.throws(() => (AbortController as any)(), TypeError) 27 | }) 28 | 29 | it("should have 2 properties", () => { 30 | // IE does not support Set constructor. 31 | const keys = new Set() 32 | keys.add("signal") 33 | keys.add("abort") 34 | 35 | for (const key in controller) { 36 | assert(keys.has(key), `'${key}' found, but should not have it`) 37 | keys.delete(key) 38 | } 39 | 40 | keys.forEach(key => { 41 | assert(false, `'${key}' not found`) 42 | }) 43 | }) 44 | 45 | // 46 | ;(SUPPORTS_TOSTRINGTAG ? it : xit)( 47 | "should be stringified as [object AbortController]", 48 | () => { 49 | assert(controller.toString() === "[object AbortController]") 50 | }, 51 | ) 52 | 53 | describe("'signal' property", () => { 54 | let signal: AbortSignal 55 | 56 | beforeEach(() => { 57 | signal = controller.signal 58 | }) 59 | 60 | it("should return the same instance always", () => { 61 | assert(signal === controller.signal) 62 | }) 63 | 64 | it("should be a AbortSignal object", () => { 65 | assert(signal instanceof AbortSignal) 66 | }) 67 | ;(HAS_EVENT_TARGET_INTERFACE ? it : xit)( 68 | "should be a EventTarget object", 69 | () => { 70 | assert(signal instanceof EventTarget) 71 | }, 72 | ) 73 | 74 | it("should have 5 properties", () => { 75 | // IE does not support Set constructor. 76 | const keys = new Set() 77 | keys.add("addEventListener") 78 | keys.add("removeEventListener") 79 | keys.add("dispatchEvent") 80 | keys.add("aborted") 81 | keys.add("onabort") 82 | 83 | for (const key in signal) { 84 | assert(keys.has(key), `'${key}' found, but should not have it`) 85 | keys.delete(key) 86 | } 87 | 88 | keys.forEach(key => { 89 | assert(false, `'${key}' not found`) 90 | }) 91 | }) 92 | 93 | it("should have 'aborted' property which is false by default", () => { 94 | assert(signal.aborted === false) 95 | }) 96 | 97 | it("should have 'onabort' property which is null by default", () => { 98 | assert(signal.onabort === null) 99 | }) 100 | 101 | it("should throw a TypeError if 'signal.aborted' getter is called with non AbortSignal object", () => { 102 | const getAborted = Object.getOwnPropertyDescriptor( 103 | (signal as any).__proto__, 104 | "aborted", 105 | )!.get 106 | assert.throws(() => getAborted!.call({}), TypeError) 107 | }) 108 | ;(SUPPORTS_TOSTRINGTAG ? it : xit)( 109 | "should be stringified as [object AbortSignal]", 110 | () => { 111 | assert(signal.toString() === "[object AbortSignal]") 112 | }, 113 | ) 114 | }) 115 | 116 | describe("'abort' method", () => { 117 | it("should set true to 'signal.aborted' property", () => { 118 | controller.abort() 119 | assert(controller.signal.aborted) 120 | }) 121 | 122 | it("should fire 'abort' event on 'signal' (addEventListener)", () => { 123 | const listener = spy() 124 | controller.signal.addEventListener("abort", listener) 125 | controller.abort() 126 | 127 | assert(listener.calls.length === 1) 128 | }) 129 | 130 | it("should fire 'abort' event on 'signal' (onabort)", () => { 131 | const listener = spy() 132 | controller.signal.onabort = listener 133 | controller.abort() 134 | 135 | assert(listener.calls.length === 1) 136 | }) 137 | 138 | it("should not fire 'abort' event twice", () => { 139 | const listener = spy() 140 | controller.signal.addEventListener("abort", listener) 141 | controller.abort() 142 | controller.abort() 143 | controller.abort() 144 | 145 | assert(listener.calls.length === 1) 146 | }) 147 | 148 | it("should throw a TypeError if 'this' is not an AbortController object", () => { 149 | assert.throws(() => controller.abort.call({}), TypeError) 150 | }) 151 | }) 152 | }) 153 | 154 | describe("AbortSignal", () => { 155 | it("should not be callable", () => { 156 | assert.throws(() => (AbortSignal as any)(), TypeError) 157 | }) 158 | 159 | it("should throw a TypeError when it's constructed directly", () => { 160 | assert.throws(() => new AbortSignal(), TypeError) 161 | }) 162 | }) 163 | -------------------------------------------------------------------------------- /test/polyfill.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Toru Nagashima 3 | * See LICENSE file in root directory for full license. 4 | */ 5 | import assert from "assert" 6 | import "../polyfill" 7 | 8 | const IN_BROWSER = typeof window !== "undefined" || typeof self !== "undefined" 9 | 10 | // 11 | ;(IN_BROWSER ? describe : xdescribe)("abort-controller/polyfill", () => { 12 | describe("window.AbortController", () => { 13 | it("should not be undefined.", () => { 14 | assert(typeof AbortController !== "undefined") 15 | }) 16 | }) 17 | 18 | describe("window.AbortSignal", () => { 19 | it("should not be undefined.", () => { 20 | assert(typeof AbortSignal !== "undefined") 21 | }) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /test/types.ts: -------------------------------------------------------------------------------- 1 | import path from "path" 2 | import { TypeTester } from "type-tester" 3 | import ts from "typescript" 4 | 5 | const tester = new TypeTester(ts) 6 | 7 | describe("TypeScript type definitions", () => { 8 | describe("'abort-controller.ts' should have no error even if it was compiled without 'lib.dom.d.ts'.", () => { 9 | tester.verify([path.resolve(__dirname, "../src/abort-controller.ts")], { 10 | lib: ["lib.es2015.d.ts"], 11 | moduleResolution: ts.ModuleResolutionKind.NodeJs, 12 | strict: true, 13 | target: ts.ScriptTarget.ES2015, 14 | }) 15 | }) 16 | 17 | tester.verify([path.resolve(__dirname, "fixtures/types.ts")], { 18 | lib: ["lib.es2015.d.ts", "lib.dom.d.ts"], 19 | moduleResolution: ts.ModuleResolutionKind.NodeJs, 20 | strict: true, 21 | target: ts.ScriptTarget.ES2015, 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": true, 5 | "esModuleInterop": true, 6 | "lib": ["es2015", "dom"], 7 | "module": "commonjs", 8 | "moduleResolution": "node", 9 | "newLine": "LF", 10 | "noFallthroughCasesInSwitch": true, 11 | "noImplicitReturns": true, 12 | "noUnusedLocals": true, 13 | "noUnusedParameters": true, 14 | "sourceMap": true, 15 | "strict": true, 16 | "target": "es2015" 17 | }, 18 | "include": [ 19 | "scripts/*.ts", 20 | "src/*.ts", 21 | "test/*.ts" 22 | ] 23 | } 24 | --------------------------------------------------------------------------------