larry babby and threejs for glsl

This commit is contained in:
Sam
2024-06-24 21:24:00 +12:00
parent 87d5dc634d
commit 907ebae4c0
6474 changed files with 1279596 additions and 8 deletions

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 molsson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,163 @@
# AbortController polyfill for abortable fetch()
[![npm version](https://badge.fury.io/js/abortcontroller-polyfill.svg)](https://badge.fury.io/js/abortcontroller-polyfill)
Minimal stubs so that the AbortController DOM API for terminating ```fetch()``` requests can be used
in browsers that doesn't yet implement it. This "polyfill" doesn't actually close the connection
when the request is aborted, but it will call ```.catch()``` with ```err.name == 'AbortError'```
instead of ```.then()```.
```js
const controller = new AbortController();
const signal = controller.signal;
fetch('/some/url', {signal})
.then(res => res.json())
.then(data => {
// do something with "data"
}).catch(err => {
if (err.name == 'AbortError') {
return;
}
});
// controller.abort(); // can be called at any time
```
You can read about the [AbortController](https://dom.spec.whatwg.org/#aborting-ongoing-activities) API in the DOM specification.
# How to use
```shell
$ npm install --save abortcontroller-polyfill
```
If you're using webpack or similar, you then import it early in your client entrypoint .js file using
```js
import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'
// or:
require('abortcontroller-polyfill/dist/polyfill-patch-fetch')
```
## Using it on browsers without fetch
If you need to support browsers where fetch is not available at all (for example
Internet Explorer 11), you first need to install a fetch polyfill and then
import the ```abortcontroller-polyfill``` afterwards.
The [unfetch](https://www.npmjs.com/package/unfetch) npm package offers a minimal ```fetch()```
implementation (though it does not offer for example a ```Request``` class). If you need a polyfill that
implements the full Fetch specification, use the
[whatwg-fetch](https://www.npmjs.com/package/whatwg-fetch) npm package instead. Typically you will
also need to load a polyfill that implements ES6 promises, for example
[promise-polyfill](https://www.npmjs.com/package/promise-polyfill), and of course you need to avoid
ES6 arrow functions and template literals.
Example projects showing abortable fetch setup so that it works even in Internet Explorer 11, using
both unfetch and GitHub fetch, is available
[here](https://github.com/mo/abortcontroller-polyfill-examples).
## Using it along with 'create-react-app'
create-react-app enforces the no-undef eslint rule at compile time so if your
version of eslint does not list ```AbortController``` etc as a known global for
the ```browser``` environment, then you might run into an compile error like:
```
'AbortController' is not defined no-undef
```
This can be worked around by (temporarily, details [here](https://github.com/mo/abortcontroller-polyfill/issues/10)) adding a declaration like:
```js
const AbortController = window.AbortController;
```
## Using the AbortController/AbortSignal without patching fetch
If you just want to polyfill AbortController/AbortSignal without patching fetch
you can use:
```js
import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'
```
# Using it on Node.js
You can either import it as a [ponyfill](https://ponyfill.com/) without modifying globals:
```js
const { AbortController, abortableFetch } = require('abortcontroller-polyfill/dist/cjs-ponyfill');
const { fetch } = abortableFetch(require('node-fetch'));
// or
// import { AbortController, abortableFetch } from 'abortcontroller-polyfill/dist/cjs-ponyfill';
// import _fetch from 'node-fetch';
// const { fetch } = abortableFetch(_fetch);
```
or if you're lazy
```js
global.fetch = require('node-fetch');
require('abortcontroller-polyfill/dist/polyfill-patch-fetch');
```
If you also need a ```Request``` class with support for aborting you can do:
```js
const { AbortController, abortableFetch } = require('abortcontroller-polyfill/dist/cjs-ponyfill');
const _nodeFetch = require('node-fetch');
const { fetch, Request } = abortableFetch({fetch: _nodeFetch, Request: _nodeFetch.Request});
const controller = new AbortController();
const signal = controller.signal;
controller.abort();
fetch(Request("http://api.github.com", {signal}))
.then(r => r.json())
.then(j => console.log(j))
.catch(err => {
if (err.name === 'AbortError') {
console.log('aborted');
}
})
```
See also Node.js examples [here](https://github.com/mo/abortcontroller-polyfill-examples/tree/master/node)
# Using it on Internet Explorer 11 (MSIE11)
The ```abortcontroller-polyfill``` works on Internet Explorer 11. However, to use it you must first
install separate polyfills for promises and for ```fetch()```. For the promise polyfill, you can
use the ```promise-polyfill``` package from npm, and for ```fetch()``` you can use either the ```whatwg-fetch``` npm package (complete fetch implementation) or the ```unfetch``` npm package (not a complete polyfill but it's only 500 bytes large and covers a lot of the basic use cases).
If you choose ```unfetch```, the imports should be done in this order for example:
```js
import 'promise-polyfill/src/polyfill';
import 'unfetch/polyfill';
import 'abortcontroller-polyfill';
```
See example code [here](https://github.com/mo/abortcontroller-polyfill-examples/tree/master/create-react-app-msie11).
# Using it on Internet Explorer 8 (MSIE8)
The ```abortcontroller-polyfill``` works on Internet Explorer 8. However, since ```github-fetch```
only supports IE 10+ you need to use the ```fetch-ie8``` npm package instead and also note that IE 8 only
implements ES 3 so you need to use the ```es5-shim``` package (or similar). Finally, just like with
IE 11 you also need to polyfill promises. One caveat is that CORS requests will not work out of the box on IE 8.
Here is a basic example of [abortable fetch running in IE 8](https://github.com/mo/abortcontroller-polyfill-examples/tree/master/plain-javascript-fetch-ie8).
# Contributors
* [Martin Olsson](https://github.com/mo)
* [Jimmy Wärting](https://github.com/jimmywarting)
* [silverwind](https://github.com/silverwind)
* [Rasmus Jacobsen](https://github.com/rmja)
* [João Vieira](https://github.com/joaovieira)
* [Cyril Auburtin](https://github.com/caub)
* [Leonardo Apiwan](https://github.com/homer0)
* [Jake Champion](https://github.com/JakeChampion)
* [Sai Srinivasan](https://github.com/SairamSrinivasan)
* [Ambar Lee](https://github.com/ambar)
# License
MIT

View File

@@ -0,0 +1,384 @@
(function (factory) {
typeof define === 'function' && define.amd ? define(factory) :
factory();
})((function () { 'use strict';
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
Object.defineProperty(Constructor, "prototype", {
writable: false
});
return Constructor;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
} else if (call !== void 0) {
throw new TypeError("Derived constructors may only return object or undefined");
}
return _assertThisInitialized(self);
}
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _superPropBase(object, property) {
while (!Object.prototype.hasOwnProperty.call(object, property)) {
object = _getPrototypeOf(object);
if (object === null) break;
}
return object;
}
function _get() {
if (typeof Reflect !== "undefined" && Reflect.get) {
_get = Reflect.get.bind();
} else {
_get = function _get(target, property, receiver) {
var base = _superPropBase(target, property);
if (!base) return;
var desc = Object.getOwnPropertyDescriptor(base, property);
if (desc.get) {
return desc.get.call(arguments.length < 3 ? target : receiver);
}
return desc.value;
};
}
return _get.apply(this, arguments);
}
var Emitter = /*#__PURE__*/function () {
function Emitter() {
_classCallCheck(this, Emitter);
Object.defineProperty(this, 'listeners', {
value: {},
writable: true,
configurable: true
});
}
_createClass(Emitter, [{
key: "addEventListener",
value: function addEventListener(type, callback, options) {
if (!(type in this.listeners)) {
this.listeners[type] = [];
}
this.listeners[type].push({
callback: callback,
options: options
});
}
}, {
key: "removeEventListener",
value: function removeEventListener(type, callback) {
if (!(type in this.listeners)) {
return;
}
var stack = this.listeners[type];
for (var i = 0, l = stack.length; i < l; i++) {
if (stack[i].callback === callback) {
stack.splice(i, 1);
return;
}
}
}
}, {
key: "dispatchEvent",
value: function dispatchEvent(event) {
if (!(event.type in this.listeners)) {
return;
}
var stack = this.listeners[event.type];
var stackToCall = stack.slice();
for (var i = 0, l = stackToCall.length; i < l; i++) {
var listener = stackToCall[i];
try {
listener.callback.call(this, event);
} catch (e) {
Promise.resolve().then(function () {
throw e;
});
}
if (listener.options && listener.options.once) {
this.removeEventListener(event.type, listener.callback);
}
}
return !event.defaultPrevented;
}
}]);
return Emitter;
}();
var AbortSignal = /*#__PURE__*/function (_Emitter) {
_inherits(AbortSignal, _Emitter);
var _super = _createSuper(AbortSignal);
function AbortSignal() {
var _this;
_classCallCheck(this, AbortSignal);
_this = _super.call(this); // Some versions of babel does not transpile super() correctly for IE <= 10, if the parent
// constructor has failed to run, then "this.listeners" will still be undefined and then we call
// the parent constructor directly instead as a workaround. For general details, see babel bug:
// https://github.com/babel/babel/issues/3041
// This hack was added as a fix for the issue described here:
// https://github.com/Financial-Times/polyfill-library/pull/59#issuecomment-477558042
if (!_this.listeners) {
Emitter.call(_assertThisInitialized(_this));
} // Compared to assignment, Object.defineProperty makes properties non-enumerable by default and
// we want Object.keys(new AbortController().signal) to be [] for compat with the native impl
Object.defineProperty(_assertThisInitialized(_this), 'aborted', {
value: false,
writable: true,
configurable: true
});
Object.defineProperty(_assertThisInitialized(_this), 'onabort', {
value: null,
writable: true,
configurable: true
});
Object.defineProperty(_assertThisInitialized(_this), 'reason', {
value: undefined,
writable: true,
configurable: true
});
return _this;
}
_createClass(AbortSignal, [{
key: "toString",
value: function toString() {
return '[object AbortSignal]';
}
}, {
key: "dispatchEvent",
value: function dispatchEvent(event) {
if (event.type === 'abort') {
this.aborted = true;
if (typeof this.onabort === 'function') {
this.onabort.call(this, event);
}
}
_get(_getPrototypeOf(AbortSignal.prototype), "dispatchEvent", this).call(this, event);
}
}]);
return AbortSignal;
}(Emitter);
var AbortController = /*#__PURE__*/function () {
function AbortController() {
_classCallCheck(this, AbortController);
// Compared to assignment, Object.defineProperty makes properties non-enumerable by default and
// we want Object.keys(new AbortController()) to be [] for compat with the native impl
Object.defineProperty(this, 'signal', {
value: new AbortSignal(),
writable: true,
configurable: true
});
}
_createClass(AbortController, [{
key: "abort",
value: function abort(reason) {
var event;
try {
event = new Event('abort');
} catch (e) {
if (typeof document !== 'undefined') {
if (!document.createEvent) {
// For Internet Explorer 8:
event = document.createEventObject();
event.type = 'abort';
} else {
// For Internet Explorer 11:
event = document.createEvent('Event');
event.initEvent('abort', false, false);
}
} else {
// Fallback where document isn't available:
event = {
type: 'abort',
bubbles: false,
cancelable: false
};
}
}
var signalReason = reason;
if (signalReason === undefined) {
if (typeof document === 'undefined') {
signalReason = new Error('This operation was aborted');
signalReason.name = 'AbortError';
} else {
try {
signalReason = new DOMException('signal is aborted without reason');
} catch (err) {
// IE 11 does not support calling the DOMException constructor, use a
// regular error object on it instead.
signalReason = new Error('This operation was aborted');
signalReason.name = 'AbortError';
}
}
}
this.signal.reason = signalReason;
this.signal.dispatchEvent(event);
}
}, {
key: "toString",
value: function toString() {
return '[object AbortController]';
}
}]);
return AbortController;
}();
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
// These are necessary to make sure that we get correct output for:
// Object.prototype.toString.call(new AbortController())
AbortController.prototype[Symbol.toStringTag] = 'AbortController';
AbortSignal.prototype[Symbol.toStringTag] = 'AbortSignal';
}
function polyfillNeeded(self) {
if (self.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) {
console.log('__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill');
return true;
} // Note that the "unfetch" minimal fetch polyfill defines fetch() without
// defining window.Request, and this polyfill need to work on top of unfetch
// so the below feature detection needs the !self.AbortController part.
// The Request.prototype check is also needed because Safari versions 11.1.2
// up to and including 12.1.x has a window.AbortController present but still
// does NOT correctly implement abortable fetch:
// https://bugs.webkit.org/show_bug.cgi?id=174980#c2
return typeof self.Request === 'function' && !self.Request.prototype.hasOwnProperty('signal') || !self.AbortController;
}
(function (self) {
if (!polyfillNeeded(self)) {
return;
}
self.AbortController = AbortController;
self.AbortSignal = AbortSignal;
})(typeof self !== 'undefined' ? self : global);
}));

View File

@@ -0,0 +1,359 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
Object.defineProperty(Constructor, "prototype", {
writable: false
});
return Constructor;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
} else if (call !== void 0) {
throw new TypeError("Derived constructors may only return object or undefined");
}
return _assertThisInitialized(self);
}
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _superPropBase(object, property) {
while (!Object.prototype.hasOwnProperty.call(object, property)) {
object = _getPrototypeOf(object);
if (object === null) break;
}
return object;
}
function _get() {
if (typeof Reflect !== "undefined" && Reflect.get) {
_get = Reflect.get.bind();
} else {
_get = function _get(target, property, receiver) {
var base = _superPropBase(target, property);
if (!base) return;
var desc = Object.getOwnPropertyDescriptor(base, property);
if (desc.get) {
return desc.get.call(arguments.length < 3 ? target : receiver);
}
return desc.value;
};
}
return _get.apply(this, arguments);
}
var Emitter = /*#__PURE__*/function () {
function Emitter() {
_classCallCheck(this, Emitter);
Object.defineProperty(this, 'listeners', {
value: {},
writable: true,
configurable: true
});
}
_createClass(Emitter, [{
key: "addEventListener",
value: function addEventListener(type, callback, options) {
if (!(type in this.listeners)) {
this.listeners[type] = [];
}
this.listeners[type].push({
callback: callback,
options: options
});
}
}, {
key: "removeEventListener",
value: function removeEventListener(type, callback) {
if (!(type in this.listeners)) {
return;
}
var stack = this.listeners[type];
for (var i = 0, l = stack.length; i < l; i++) {
if (stack[i].callback === callback) {
stack.splice(i, 1);
return;
}
}
}
}, {
key: "dispatchEvent",
value: function dispatchEvent(event) {
if (!(event.type in this.listeners)) {
return;
}
var stack = this.listeners[event.type];
var stackToCall = stack.slice();
for (var i = 0, l = stackToCall.length; i < l; i++) {
var listener = stackToCall[i];
try {
listener.callback.call(this, event);
} catch (e) {
Promise.resolve().then(function () {
throw e;
});
}
if (listener.options && listener.options.once) {
this.removeEventListener(event.type, listener.callback);
}
}
return !event.defaultPrevented;
}
}]);
return Emitter;
}();
var AbortSignal = /*#__PURE__*/function (_Emitter) {
_inherits(AbortSignal, _Emitter);
var _super = _createSuper(AbortSignal);
function AbortSignal() {
var _this;
_classCallCheck(this, AbortSignal);
_this = _super.call(this); // Some versions of babel does not transpile super() correctly for IE <= 10, if the parent
// constructor has failed to run, then "this.listeners" will still be undefined and then we call
// the parent constructor directly instead as a workaround. For general details, see babel bug:
// https://github.com/babel/babel/issues/3041
// This hack was added as a fix for the issue described here:
// https://github.com/Financial-Times/polyfill-library/pull/59#issuecomment-477558042
if (!_this.listeners) {
Emitter.call(_assertThisInitialized(_this));
} // Compared to assignment, Object.defineProperty makes properties non-enumerable by default and
// we want Object.keys(new AbortController().signal) to be [] for compat with the native impl
Object.defineProperty(_assertThisInitialized(_this), 'aborted', {
value: false,
writable: true,
configurable: true
});
Object.defineProperty(_assertThisInitialized(_this), 'onabort', {
value: null,
writable: true,
configurable: true
});
Object.defineProperty(_assertThisInitialized(_this), 'reason', {
value: undefined,
writable: true,
configurable: true
});
return _this;
}
_createClass(AbortSignal, [{
key: "toString",
value: function toString() {
return '[object AbortSignal]';
}
}, {
key: "dispatchEvent",
value: function dispatchEvent(event) {
if (event.type === 'abort') {
this.aborted = true;
if (typeof this.onabort === 'function') {
this.onabort.call(this, event);
}
}
_get(_getPrototypeOf(AbortSignal.prototype), "dispatchEvent", this).call(this, event);
}
}]);
return AbortSignal;
}(Emitter);
var AbortController = /*#__PURE__*/function () {
function AbortController() {
_classCallCheck(this, AbortController);
// Compared to assignment, Object.defineProperty makes properties non-enumerable by default and
// we want Object.keys(new AbortController()) to be [] for compat with the native impl
Object.defineProperty(this, 'signal', {
value: new AbortSignal(),
writable: true,
configurable: true
});
}
_createClass(AbortController, [{
key: "abort",
value: function abort(reason) {
var event;
try {
event = new Event('abort');
} catch (e) {
if (typeof document !== 'undefined') {
if (!document.createEvent) {
// For Internet Explorer 8:
event = document.createEventObject();
event.type = 'abort';
} else {
// For Internet Explorer 11:
event = document.createEvent('Event');
event.initEvent('abort', false, false);
}
} else {
// Fallback where document isn't available:
event = {
type: 'abort',
bubbles: false,
cancelable: false
};
}
}
var signalReason = reason;
if (signalReason === undefined) {
if (typeof document === 'undefined') {
signalReason = new Error('This operation was aborted');
signalReason.name = 'AbortError';
} else {
try {
signalReason = new DOMException('signal is aborted without reason');
} catch (err) {
// IE 11 does not support calling the DOMException constructor, use a
// regular error object on it instead.
signalReason = new Error('This operation was aborted');
signalReason.name = 'AbortError';
}
}
}
this.signal.reason = signalReason;
this.signal.dispatchEvent(event);
}
}, {
key: "toString",
value: function toString() {
return '[object AbortController]';
}
}]);
return AbortController;
}();
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
// These are necessary to make sure that we get correct output for:
// Object.prototype.toString.call(new AbortController())
AbortController.prototype[Symbol.toStringTag] = 'AbortController';
AbortSignal.prototype[Symbol.toStringTag] = 'AbortSignal';
}
exports.AbortController = AbortController;
exports.AbortSignal = AbortSignal;
exports["default"] = AbortController;

View File

@@ -0,0 +1,514 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
Object.defineProperty(Constructor, "prototype", {
writable: false
});
return Constructor;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
} else if (call !== void 0) {
throw new TypeError("Derived constructors may only return object or undefined");
}
return _assertThisInitialized(self);
}
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _superPropBase(object, property) {
while (!Object.prototype.hasOwnProperty.call(object, property)) {
object = _getPrototypeOf(object);
if (object === null) break;
}
return object;
}
function _get() {
if (typeof Reflect !== "undefined" && Reflect.get) {
_get = Reflect.get.bind();
} else {
_get = function _get(target, property, receiver) {
var base = _superPropBase(target, property);
if (!base) return;
var desc = Object.getOwnPropertyDescriptor(base, property);
if (desc.get) {
return desc.get.call(arguments.length < 3 ? target : receiver);
}
return desc.value;
};
}
return _get.apply(this, arguments);
}
var Emitter = /*#__PURE__*/function () {
function Emitter() {
_classCallCheck(this, Emitter);
Object.defineProperty(this, 'listeners', {
value: {},
writable: true,
configurable: true
});
}
_createClass(Emitter, [{
key: "addEventListener",
value: function addEventListener(type, callback, options) {
if (!(type in this.listeners)) {
this.listeners[type] = [];
}
this.listeners[type].push({
callback: callback,
options: options
});
}
}, {
key: "removeEventListener",
value: function removeEventListener(type, callback) {
if (!(type in this.listeners)) {
return;
}
var stack = this.listeners[type];
for (var i = 0, l = stack.length; i < l; i++) {
if (stack[i].callback === callback) {
stack.splice(i, 1);
return;
}
}
}
}, {
key: "dispatchEvent",
value: function dispatchEvent(event) {
if (!(event.type in this.listeners)) {
return;
}
var stack = this.listeners[event.type];
var stackToCall = stack.slice();
for (var i = 0, l = stackToCall.length; i < l; i++) {
var listener = stackToCall[i];
try {
listener.callback.call(this, event);
} catch (e) {
Promise.resolve().then(function () {
throw e;
});
}
if (listener.options && listener.options.once) {
this.removeEventListener(event.type, listener.callback);
}
}
return !event.defaultPrevented;
}
}]);
return Emitter;
}();
var AbortSignal = /*#__PURE__*/function (_Emitter) {
_inherits(AbortSignal, _Emitter);
var _super = _createSuper(AbortSignal);
function AbortSignal() {
var _this;
_classCallCheck(this, AbortSignal);
_this = _super.call(this); // Some versions of babel does not transpile super() correctly for IE <= 10, if the parent
// constructor has failed to run, then "this.listeners" will still be undefined and then we call
// the parent constructor directly instead as a workaround. For general details, see babel bug:
// https://github.com/babel/babel/issues/3041
// This hack was added as a fix for the issue described here:
// https://github.com/Financial-Times/polyfill-library/pull/59#issuecomment-477558042
if (!_this.listeners) {
Emitter.call(_assertThisInitialized(_this));
} // Compared to assignment, Object.defineProperty makes properties non-enumerable by default and
// we want Object.keys(new AbortController().signal) to be [] for compat with the native impl
Object.defineProperty(_assertThisInitialized(_this), 'aborted', {
value: false,
writable: true,
configurable: true
});
Object.defineProperty(_assertThisInitialized(_this), 'onabort', {
value: null,
writable: true,
configurable: true
});
Object.defineProperty(_assertThisInitialized(_this), 'reason', {
value: undefined,
writable: true,
configurable: true
});
return _this;
}
_createClass(AbortSignal, [{
key: "toString",
value: function toString() {
return '[object AbortSignal]';
}
}, {
key: "dispatchEvent",
value: function dispatchEvent(event) {
if (event.type === 'abort') {
this.aborted = true;
if (typeof this.onabort === 'function') {
this.onabort.call(this, event);
}
}
_get(_getPrototypeOf(AbortSignal.prototype), "dispatchEvent", this).call(this, event);
}
}]);
return AbortSignal;
}(Emitter);
var AbortController = /*#__PURE__*/function () {
function AbortController() {
_classCallCheck(this, AbortController);
// Compared to assignment, Object.defineProperty makes properties non-enumerable by default and
// we want Object.keys(new AbortController()) to be [] for compat with the native impl
Object.defineProperty(this, 'signal', {
value: new AbortSignal(),
writable: true,
configurable: true
});
}
_createClass(AbortController, [{
key: "abort",
value: function abort(reason) {
var event;
try {
event = new Event('abort');
} catch (e) {
if (typeof document !== 'undefined') {
if (!document.createEvent) {
// For Internet Explorer 8:
event = document.createEventObject();
event.type = 'abort';
} else {
// For Internet Explorer 11:
event = document.createEvent('Event');
event.initEvent('abort', false, false);
}
} else {
// Fallback where document isn't available:
event = {
type: 'abort',
bubbles: false,
cancelable: false
};
}
}
var signalReason = reason;
if (signalReason === undefined) {
if (typeof document === 'undefined') {
signalReason = new Error('This operation was aborted');
signalReason.name = 'AbortError';
} else {
try {
signalReason = new DOMException('signal is aborted without reason');
} catch (err) {
// IE 11 does not support calling the DOMException constructor, use a
// regular error object on it instead.
signalReason = new Error('This operation was aborted');
signalReason.name = 'AbortError';
}
}
}
this.signal.reason = signalReason;
this.signal.dispatchEvent(event);
}
}, {
key: "toString",
value: function toString() {
return '[object AbortController]';
}
}]);
return AbortController;
}();
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
// These are necessary to make sure that we get correct output for:
// Object.prototype.toString.call(new AbortController())
AbortController.prototype[Symbol.toStringTag] = 'AbortController';
AbortSignal.prototype[Symbol.toStringTag] = 'AbortSignal';
}
function polyfillNeeded(self) {
if (self.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) {
console.log('__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill');
return true;
} // Note that the "unfetch" minimal fetch polyfill defines fetch() without
// defining window.Request, and this polyfill need to work on top of unfetch
// so the below feature detection needs the !self.AbortController part.
// The Request.prototype check is also needed because Safari versions 11.1.2
// up to and including 12.1.x has a window.AbortController present but still
// does NOT correctly implement abortable fetch:
// https://bugs.webkit.org/show_bug.cgi?id=174980#c2
return typeof self.Request === 'function' && !self.Request.prototype.hasOwnProperty('signal') || !self.AbortController;
}
/**
* Note: the "fetch.Request" default value is available for fetch imported from
* the "node-fetch" package and not in browsers. This is OK since browsers
* will be importing umd-polyfill.js from that path "self" is passed the
* decorator so the default value will not be used (because browsers that define
* fetch also has Request). One quirky setup where self.fetch exists but
* self.Request does not is when the "unfetch" minimal fetch polyfill is used
* on top of IE11; for this case the browser will try to use the fetch.Request
* default value which in turn will be undefined but then then "if (Request)"
* will ensure that you get a patched fetch but still no Request (as expected).
* @param {fetch, Request = fetch.Request}
* @returns {fetch: abortableFetch, Request: AbortableRequest}
*/
function abortableFetchDecorator(patchTargets) {
if ('function' === typeof patchTargets) {
patchTargets = {
fetch: patchTargets
};
}
var _patchTargets = patchTargets,
fetch = _patchTargets.fetch,
_patchTargets$Request = _patchTargets.Request,
NativeRequest = _patchTargets$Request === void 0 ? fetch.Request : _patchTargets$Request,
NativeAbortController = _patchTargets.AbortController,
_patchTargets$__FORCE = _patchTargets.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL,
__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL = _patchTargets$__FORCE === void 0 ? false : _patchTargets$__FORCE;
if (!polyfillNeeded({
fetch: fetch,
Request: NativeRequest,
AbortController: NativeAbortController,
__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL: __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL
})) {
return {
fetch: fetch,
Request: Request
};
}
var Request = NativeRequest; // Note that the "unfetch" minimal fetch polyfill defines fetch() without
// defining window.Request, and this polyfill need to work on top of unfetch
// hence we only patch it if it's available. Also we don't patch it if signal
// is already available on the Request prototype because in this case support
// is present and the patching below can cause a crash since it assigns to
// request.signal which is technically a read-only property. This latter error
// happens when you run the main5.js node-fetch example in the repo
// "abortcontroller-polyfill-examples". The exact error is:
// request.signal = init.signal;
// ^
// TypeError: Cannot set property signal of #<Request> which has only a getter
if (Request && !Request.prototype.hasOwnProperty('signal') || __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) {
Request = function Request(input, init) {
var signal;
if (init && init.signal) {
signal = init.signal; // Never pass init.signal to the native Request implementation when the polyfill has
// been installed because if we're running on top of a browser with a
// working native AbortController (i.e. the polyfill was installed due to
// __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL being set), then passing our
// fake AbortSignal to the native fetch will trigger:
// TypeError: Failed to construct 'Request': member signal is not of type AbortSignal.
delete init.signal;
}
var request = new NativeRequest(input, init);
if (signal) {
Object.defineProperty(request, 'signal', {
writable: false,
enumerable: false,
configurable: true,
value: signal
});
}
return request;
};
Request.prototype = NativeRequest.prototype;
}
var realFetch = fetch;
var abortableFetch = function abortableFetch(input, init) {
var signal = Request && Request.prototype.isPrototypeOf(input) ? input.signal : init ? init.signal : undefined;
if (signal) {
var abortError;
try {
abortError = new DOMException('Aborted', 'AbortError');
} catch (err) {
// IE 11 does not support calling the DOMException constructor, use a
// regular error object on it instead.
abortError = new Error('Aborted');
abortError.name = 'AbortError';
} // Return early if already aborted, thus avoiding making an HTTP request
if (signal.aborted) {
return Promise.reject(abortError);
} // Turn an event into a promise, reject it once `abort` is dispatched
var cancellation = new Promise(function (_, reject) {
signal.addEventListener('abort', function () {
return reject(abortError);
}, {
once: true
});
});
if (init && init.signal) {
// Never pass .signal to the native implementation when the polyfill has
// been installed because if we're running on top of a browser with a
// working native AbortController (i.e. the polyfill was installed due to
// __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL being set), then passing our
// fake AbortSignal to the native fetch will trigger:
// TypeError: Failed to execute 'fetch' on 'Window': member signal is not of type AbortSignal.
delete init.signal;
} // Return the fastest promise (don't need to wait for request to finish)
return Promise.race([cancellation, realFetch(input, init)]);
}
return realFetch(input, init);
};
return {
fetch: abortableFetch,
Request: Request
};
}
exports.AbortController = AbortController;
exports.AbortSignal = AbortSignal;
exports.abortableFetch = abortableFetchDecorator;

View File

@@ -0,0 +1,544 @@
(function (factory) {
typeof define === 'function' && define.amd ? define(factory) :
factory();
})((function () { 'use strict';
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
Object.defineProperty(Constructor, "prototype", {
writable: false
});
return Constructor;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
} else if (call !== void 0) {
throw new TypeError("Derived constructors may only return object or undefined");
}
return _assertThisInitialized(self);
}
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _superPropBase(object, property) {
while (!Object.prototype.hasOwnProperty.call(object, property)) {
object = _getPrototypeOf(object);
if (object === null) break;
}
return object;
}
function _get() {
if (typeof Reflect !== "undefined" && Reflect.get) {
_get = Reflect.get.bind();
} else {
_get = function _get(target, property, receiver) {
var base = _superPropBase(target, property);
if (!base) return;
var desc = Object.getOwnPropertyDescriptor(base, property);
if (desc.get) {
return desc.get.call(arguments.length < 3 ? target : receiver);
}
return desc.value;
};
}
return _get.apply(this, arguments);
}
var Emitter = /*#__PURE__*/function () {
function Emitter() {
_classCallCheck(this, Emitter);
Object.defineProperty(this, 'listeners', {
value: {},
writable: true,
configurable: true
});
}
_createClass(Emitter, [{
key: "addEventListener",
value: function addEventListener(type, callback, options) {
if (!(type in this.listeners)) {
this.listeners[type] = [];
}
this.listeners[type].push({
callback: callback,
options: options
});
}
}, {
key: "removeEventListener",
value: function removeEventListener(type, callback) {
if (!(type in this.listeners)) {
return;
}
var stack = this.listeners[type];
for (var i = 0, l = stack.length; i < l; i++) {
if (stack[i].callback === callback) {
stack.splice(i, 1);
return;
}
}
}
}, {
key: "dispatchEvent",
value: function dispatchEvent(event) {
if (!(event.type in this.listeners)) {
return;
}
var stack = this.listeners[event.type];
var stackToCall = stack.slice();
for (var i = 0, l = stackToCall.length; i < l; i++) {
var listener = stackToCall[i];
try {
listener.callback.call(this, event);
} catch (e) {
Promise.resolve().then(function () {
throw e;
});
}
if (listener.options && listener.options.once) {
this.removeEventListener(event.type, listener.callback);
}
}
return !event.defaultPrevented;
}
}]);
return Emitter;
}();
var AbortSignal = /*#__PURE__*/function (_Emitter) {
_inherits(AbortSignal, _Emitter);
var _super = _createSuper(AbortSignal);
function AbortSignal() {
var _this;
_classCallCheck(this, AbortSignal);
_this = _super.call(this); // Some versions of babel does not transpile super() correctly for IE <= 10, if the parent
// constructor has failed to run, then "this.listeners" will still be undefined and then we call
// the parent constructor directly instead as a workaround. For general details, see babel bug:
// https://github.com/babel/babel/issues/3041
// This hack was added as a fix for the issue described here:
// https://github.com/Financial-Times/polyfill-library/pull/59#issuecomment-477558042
if (!_this.listeners) {
Emitter.call(_assertThisInitialized(_this));
} // Compared to assignment, Object.defineProperty makes properties non-enumerable by default and
// we want Object.keys(new AbortController().signal) to be [] for compat with the native impl
Object.defineProperty(_assertThisInitialized(_this), 'aborted', {
value: false,
writable: true,
configurable: true
});
Object.defineProperty(_assertThisInitialized(_this), 'onabort', {
value: null,
writable: true,
configurable: true
});
Object.defineProperty(_assertThisInitialized(_this), 'reason', {
value: undefined,
writable: true,
configurable: true
});
return _this;
}
_createClass(AbortSignal, [{
key: "toString",
value: function toString() {
return '[object AbortSignal]';
}
}, {
key: "dispatchEvent",
value: function dispatchEvent(event) {
if (event.type === 'abort') {
this.aborted = true;
if (typeof this.onabort === 'function') {
this.onabort.call(this, event);
}
}
_get(_getPrototypeOf(AbortSignal.prototype), "dispatchEvent", this).call(this, event);
}
}]);
return AbortSignal;
}(Emitter);
var AbortController = /*#__PURE__*/function () {
function AbortController() {
_classCallCheck(this, AbortController);
// Compared to assignment, Object.defineProperty makes properties non-enumerable by default and
// we want Object.keys(new AbortController()) to be [] for compat with the native impl
Object.defineProperty(this, 'signal', {
value: new AbortSignal(),
writable: true,
configurable: true
});
}
_createClass(AbortController, [{
key: "abort",
value: function abort(reason) {
var event;
try {
event = new Event('abort');
} catch (e) {
if (typeof document !== 'undefined') {
if (!document.createEvent) {
// For Internet Explorer 8:
event = document.createEventObject();
event.type = 'abort';
} else {
// For Internet Explorer 11:
event = document.createEvent('Event');
event.initEvent('abort', false, false);
}
} else {
// Fallback where document isn't available:
event = {
type: 'abort',
bubbles: false,
cancelable: false
};
}
}
var signalReason = reason;
if (signalReason === undefined) {
if (typeof document === 'undefined') {
signalReason = new Error('This operation was aborted');
signalReason.name = 'AbortError';
} else {
try {
signalReason = new DOMException('signal is aborted without reason');
} catch (err) {
// IE 11 does not support calling the DOMException constructor, use a
// regular error object on it instead.
signalReason = new Error('This operation was aborted');
signalReason.name = 'AbortError';
}
}
}
this.signal.reason = signalReason;
this.signal.dispatchEvent(event);
}
}, {
key: "toString",
value: function toString() {
return '[object AbortController]';
}
}]);
return AbortController;
}();
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
// These are necessary to make sure that we get correct output for:
// Object.prototype.toString.call(new AbortController())
AbortController.prototype[Symbol.toStringTag] = 'AbortController';
AbortSignal.prototype[Symbol.toStringTag] = 'AbortSignal';
}
function polyfillNeeded(self) {
if (self.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) {
console.log('__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill');
return true;
} // Note that the "unfetch" minimal fetch polyfill defines fetch() without
// defining window.Request, and this polyfill need to work on top of unfetch
// so the below feature detection needs the !self.AbortController part.
// The Request.prototype check is also needed because Safari versions 11.1.2
// up to and including 12.1.x has a window.AbortController present but still
// does NOT correctly implement abortable fetch:
// https://bugs.webkit.org/show_bug.cgi?id=174980#c2
return typeof self.Request === 'function' && !self.Request.prototype.hasOwnProperty('signal') || !self.AbortController;
}
/**
* Note: the "fetch.Request" default value is available for fetch imported from
* the "node-fetch" package and not in browsers. This is OK since browsers
* will be importing umd-polyfill.js from that path "self" is passed the
* decorator so the default value will not be used (because browsers that define
* fetch also has Request). One quirky setup where self.fetch exists but
* self.Request does not is when the "unfetch" minimal fetch polyfill is used
* on top of IE11; for this case the browser will try to use the fetch.Request
* default value which in turn will be undefined but then then "if (Request)"
* will ensure that you get a patched fetch but still no Request (as expected).
* @param {fetch, Request = fetch.Request}
* @returns {fetch: abortableFetch, Request: AbortableRequest}
*/
function abortableFetchDecorator(patchTargets) {
if ('function' === typeof patchTargets) {
patchTargets = {
fetch: patchTargets
};
}
var _patchTargets = patchTargets,
fetch = _patchTargets.fetch,
_patchTargets$Request = _patchTargets.Request,
NativeRequest = _patchTargets$Request === void 0 ? fetch.Request : _patchTargets$Request,
NativeAbortController = _patchTargets.AbortController,
_patchTargets$__FORCE = _patchTargets.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL,
__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL = _patchTargets$__FORCE === void 0 ? false : _patchTargets$__FORCE;
if (!polyfillNeeded({
fetch: fetch,
Request: NativeRequest,
AbortController: NativeAbortController,
__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL: __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL
})) {
return {
fetch: fetch,
Request: Request
};
}
var Request = NativeRequest; // Note that the "unfetch" minimal fetch polyfill defines fetch() without
// defining window.Request, and this polyfill need to work on top of unfetch
// hence we only patch it if it's available. Also we don't patch it if signal
// is already available on the Request prototype because in this case support
// is present and the patching below can cause a crash since it assigns to
// request.signal which is technically a read-only property. This latter error
// happens when you run the main5.js node-fetch example in the repo
// "abortcontroller-polyfill-examples". The exact error is:
// request.signal = init.signal;
// ^
// TypeError: Cannot set property signal of #<Request> which has only a getter
if (Request && !Request.prototype.hasOwnProperty('signal') || __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) {
Request = function Request(input, init) {
var signal;
if (init && init.signal) {
signal = init.signal; // Never pass init.signal to the native Request implementation when the polyfill has
// been installed because if we're running on top of a browser with a
// working native AbortController (i.e. the polyfill was installed due to
// __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL being set), then passing our
// fake AbortSignal to the native fetch will trigger:
// TypeError: Failed to construct 'Request': member signal is not of type AbortSignal.
delete init.signal;
}
var request = new NativeRequest(input, init);
if (signal) {
Object.defineProperty(request, 'signal', {
writable: false,
enumerable: false,
configurable: true,
value: signal
});
}
return request;
};
Request.prototype = NativeRequest.prototype;
}
var realFetch = fetch;
var abortableFetch = function abortableFetch(input, init) {
var signal = Request && Request.prototype.isPrototypeOf(input) ? input.signal : init ? init.signal : undefined;
if (signal) {
var abortError;
try {
abortError = new DOMException('Aborted', 'AbortError');
} catch (err) {
// IE 11 does not support calling the DOMException constructor, use a
// regular error object on it instead.
abortError = new Error('Aborted');
abortError.name = 'AbortError';
} // Return early if already aborted, thus avoiding making an HTTP request
if (signal.aborted) {
return Promise.reject(abortError);
} // Turn an event into a promise, reject it once `abort` is dispatched
var cancellation = new Promise(function (_, reject) {
signal.addEventListener('abort', function () {
return reject(abortError);
}, {
once: true
});
});
if (init && init.signal) {
// Never pass .signal to the native implementation when the polyfill has
// been installed because if we're running on top of a browser with a
// working native AbortController (i.e. the polyfill was installed due to
// __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL being set), then passing our
// fake AbortSignal to the native fetch will trigger:
// TypeError: Failed to execute 'fetch' on 'Window': member signal is not of type AbortSignal.
delete init.signal;
} // Return the fastest promise (don't need to wait for request to finish)
return Promise.race([cancellation, realFetch(input, init)]);
}
return realFetch(input, init);
};
return {
fetch: abortableFetch,
Request: Request
};
}
(function (self) {
if (!polyfillNeeded(self)) {
return;
}
if (!self.fetch) {
console.warn('fetch() is not available, cannot install abortcontroller-polyfill');
return;
}
var _abortableFetch = abortableFetchDecorator(self),
fetch = _abortableFetch.fetch,
Request = _abortableFetch.Request;
self.fetch = fetch;
self.Request = Request;
Object.defineProperty(self, 'AbortController', {
writable: true,
enumerable: false,
configurable: true,
value: AbortController
});
Object.defineProperty(self, 'AbortSignal', {
writable: true,
enumerable: false,
configurable: true,
value: AbortSignal
});
})(typeof self !== 'undefined' ? self : global);
}));

View File

@@ -0,0 +1,544 @@
(function (factory) {
typeof define === 'function' && define.amd ? define(factory) :
factory();
})((function () { 'use strict';
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
Object.defineProperty(Constructor, "prototype", {
writable: false
});
return Constructor;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
} else if (call !== void 0) {
throw new TypeError("Derived constructors may only return object or undefined");
}
return _assertThisInitialized(self);
}
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _superPropBase(object, property) {
while (!Object.prototype.hasOwnProperty.call(object, property)) {
object = _getPrototypeOf(object);
if (object === null) break;
}
return object;
}
function _get() {
if (typeof Reflect !== "undefined" && Reflect.get) {
_get = Reflect.get.bind();
} else {
_get = function _get(target, property, receiver) {
var base = _superPropBase(target, property);
if (!base) return;
var desc = Object.getOwnPropertyDescriptor(base, property);
if (desc.get) {
return desc.get.call(arguments.length < 3 ? target : receiver);
}
return desc.value;
};
}
return _get.apply(this, arguments);
}
var Emitter = /*#__PURE__*/function () {
function Emitter() {
_classCallCheck(this, Emitter);
Object.defineProperty(this, 'listeners', {
value: {},
writable: true,
configurable: true
});
}
_createClass(Emitter, [{
key: "addEventListener",
value: function addEventListener(type, callback, options) {
if (!(type in this.listeners)) {
this.listeners[type] = [];
}
this.listeners[type].push({
callback: callback,
options: options
});
}
}, {
key: "removeEventListener",
value: function removeEventListener(type, callback) {
if (!(type in this.listeners)) {
return;
}
var stack = this.listeners[type];
for (var i = 0, l = stack.length; i < l; i++) {
if (stack[i].callback === callback) {
stack.splice(i, 1);
return;
}
}
}
}, {
key: "dispatchEvent",
value: function dispatchEvent(event) {
if (!(event.type in this.listeners)) {
return;
}
var stack = this.listeners[event.type];
var stackToCall = stack.slice();
for (var i = 0, l = stackToCall.length; i < l; i++) {
var listener = stackToCall[i];
try {
listener.callback.call(this, event);
} catch (e) {
Promise.resolve().then(function () {
throw e;
});
}
if (listener.options && listener.options.once) {
this.removeEventListener(event.type, listener.callback);
}
}
return !event.defaultPrevented;
}
}]);
return Emitter;
}();
var AbortSignal = /*#__PURE__*/function (_Emitter) {
_inherits(AbortSignal, _Emitter);
var _super = _createSuper(AbortSignal);
function AbortSignal() {
var _this;
_classCallCheck(this, AbortSignal);
_this = _super.call(this); // Some versions of babel does not transpile super() correctly for IE <= 10, if the parent
// constructor has failed to run, then "this.listeners" will still be undefined and then we call
// the parent constructor directly instead as a workaround. For general details, see babel bug:
// https://github.com/babel/babel/issues/3041
// This hack was added as a fix for the issue described here:
// https://github.com/Financial-Times/polyfill-library/pull/59#issuecomment-477558042
if (!_this.listeners) {
Emitter.call(_assertThisInitialized(_this));
} // Compared to assignment, Object.defineProperty makes properties non-enumerable by default and
// we want Object.keys(new AbortController().signal) to be [] for compat with the native impl
Object.defineProperty(_assertThisInitialized(_this), 'aborted', {
value: false,
writable: true,
configurable: true
});
Object.defineProperty(_assertThisInitialized(_this), 'onabort', {
value: null,
writable: true,
configurable: true
});
Object.defineProperty(_assertThisInitialized(_this), 'reason', {
value: undefined,
writable: true,
configurable: true
});
return _this;
}
_createClass(AbortSignal, [{
key: "toString",
value: function toString() {
return '[object AbortSignal]';
}
}, {
key: "dispatchEvent",
value: function dispatchEvent(event) {
if (event.type === 'abort') {
this.aborted = true;
if (typeof this.onabort === 'function') {
this.onabort.call(this, event);
}
}
_get(_getPrototypeOf(AbortSignal.prototype), "dispatchEvent", this).call(this, event);
}
}]);
return AbortSignal;
}(Emitter);
var AbortController = /*#__PURE__*/function () {
function AbortController() {
_classCallCheck(this, AbortController);
// Compared to assignment, Object.defineProperty makes properties non-enumerable by default and
// we want Object.keys(new AbortController()) to be [] for compat with the native impl
Object.defineProperty(this, 'signal', {
value: new AbortSignal(),
writable: true,
configurable: true
});
}
_createClass(AbortController, [{
key: "abort",
value: function abort(reason) {
var event;
try {
event = new Event('abort');
} catch (e) {
if (typeof document !== 'undefined') {
if (!document.createEvent) {
// For Internet Explorer 8:
event = document.createEventObject();
event.type = 'abort';
} else {
// For Internet Explorer 11:
event = document.createEvent('Event');
event.initEvent('abort', false, false);
}
} else {
// Fallback where document isn't available:
event = {
type: 'abort',
bubbles: false,
cancelable: false
};
}
}
var signalReason = reason;
if (signalReason === undefined) {
if (typeof document === 'undefined') {
signalReason = new Error('This operation was aborted');
signalReason.name = 'AbortError';
} else {
try {
signalReason = new DOMException('signal is aborted without reason');
} catch (err) {
// IE 11 does not support calling the DOMException constructor, use a
// regular error object on it instead.
signalReason = new Error('This operation was aborted');
signalReason.name = 'AbortError';
}
}
}
this.signal.reason = signalReason;
this.signal.dispatchEvent(event);
}
}, {
key: "toString",
value: function toString() {
return '[object AbortController]';
}
}]);
return AbortController;
}();
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
// These are necessary to make sure that we get correct output for:
// Object.prototype.toString.call(new AbortController())
AbortController.prototype[Symbol.toStringTag] = 'AbortController';
AbortSignal.prototype[Symbol.toStringTag] = 'AbortSignal';
}
function polyfillNeeded(self) {
if (self.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) {
console.log('__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill');
return true;
} // Note that the "unfetch" minimal fetch polyfill defines fetch() without
// defining window.Request, and this polyfill need to work on top of unfetch
// so the below feature detection needs the !self.AbortController part.
// The Request.prototype check is also needed because Safari versions 11.1.2
// up to and including 12.1.x has a window.AbortController present but still
// does NOT correctly implement abortable fetch:
// https://bugs.webkit.org/show_bug.cgi?id=174980#c2
return typeof self.Request === 'function' && !self.Request.prototype.hasOwnProperty('signal') || !self.AbortController;
}
/**
* Note: the "fetch.Request" default value is available for fetch imported from
* the "node-fetch" package and not in browsers. This is OK since browsers
* will be importing umd-polyfill.js from that path "self" is passed the
* decorator so the default value will not be used (because browsers that define
* fetch also has Request). One quirky setup where self.fetch exists but
* self.Request does not is when the "unfetch" minimal fetch polyfill is used
* on top of IE11; for this case the browser will try to use the fetch.Request
* default value which in turn will be undefined but then then "if (Request)"
* will ensure that you get a patched fetch but still no Request (as expected).
* @param {fetch, Request = fetch.Request}
* @returns {fetch: abortableFetch, Request: AbortableRequest}
*/
function abortableFetchDecorator(patchTargets) {
if ('function' === typeof patchTargets) {
patchTargets = {
fetch: patchTargets
};
}
var _patchTargets = patchTargets,
fetch = _patchTargets.fetch,
_patchTargets$Request = _patchTargets.Request,
NativeRequest = _patchTargets$Request === void 0 ? fetch.Request : _patchTargets$Request,
NativeAbortController = _patchTargets.AbortController,
_patchTargets$__FORCE = _patchTargets.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL,
__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL = _patchTargets$__FORCE === void 0 ? false : _patchTargets$__FORCE;
if (!polyfillNeeded({
fetch: fetch,
Request: NativeRequest,
AbortController: NativeAbortController,
__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL: __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL
})) {
return {
fetch: fetch,
Request: Request
};
}
var Request = NativeRequest; // Note that the "unfetch" minimal fetch polyfill defines fetch() without
// defining window.Request, and this polyfill need to work on top of unfetch
// hence we only patch it if it's available. Also we don't patch it if signal
// is already available on the Request prototype because in this case support
// is present and the patching below can cause a crash since it assigns to
// request.signal which is technically a read-only property. This latter error
// happens when you run the main5.js node-fetch example in the repo
// "abortcontroller-polyfill-examples". The exact error is:
// request.signal = init.signal;
// ^
// TypeError: Cannot set property signal of #<Request> which has only a getter
if (Request && !Request.prototype.hasOwnProperty('signal') || __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) {
Request = function Request(input, init) {
var signal;
if (init && init.signal) {
signal = init.signal; // Never pass init.signal to the native Request implementation when the polyfill has
// been installed because if we're running on top of a browser with a
// working native AbortController (i.e. the polyfill was installed due to
// __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL being set), then passing our
// fake AbortSignal to the native fetch will trigger:
// TypeError: Failed to construct 'Request': member signal is not of type AbortSignal.
delete init.signal;
}
var request = new NativeRequest(input, init);
if (signal) {
Object.defineProperty(request, 'signal', {
writable: false,
enumerable: false,
configurable: true,
value: signal
});
}
return request;
};
Request.prototype = NativeRequest.prototype;
}
var realFetch = fetch;
var abortableFetch = function abortableFetch(input, init) {
var signal = Request && Request.prototype.isPrototypeOf(input) ? input.signal : init ? init.signal : undefined;
if (signal) {
var abortError;
try {
abortError = new DOMException('Aborted', 'AbortError');
} catch (err) {
// IE 11 does not support calling the DOMException constructor, use a
// regular error object on it instead.
abortError = new Error('Aborted');
abortError.name = 'AbortError';
} // Return early if already aborted, thus avoiding making an HTTP request
if (signal.aborted) {
return Promise.reject(abortError);
} // Turn an event into a promise, reject it once `abort` is dispatched
var cancellation = new Promise(function (_, reject) {
signal.addEventListener('abort', function () {
return reject(abortError);
}, {
once: true
});
});
if (init && init.signal) {
// Never pass .signal to the native implementation when the polyfill has
// been installed because if we're running on top of a browser with a
// working native AbortController (i.e. the polyfill was installed due to
// __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL being set), then passing our
// fake AbortSignal to the native fetch will trigger:
// TypeError: Failed to execute 'fetch' on 'Window': member signal is not of type AbortSignal.
delete init.signal;
} // Return the fastest promise (don't need to wait for request to finish)
return Promise.race([cancellation, realFetch(input, init)]);
}
return realFetch(input, init);
};
return {
fetch: abortableFetch,
Request: Request
};
}
(function (self) {
if (!polyfillNeeded(self)) {
return;
}
if (!self.fetch) {
console.warn('fetch() is not available, cannot install abortcontroller-polyfill');
return;
}
var _abortableFetch = abortableFetchDecorator(self),
fetch = _abortableFetch.fetch,
Request = _abortableFetch.Request;
self.fetch = fetch;
self.Request = Request;
Object.defineProperty(self, 'AbortController', {
writable: true,
enumerable: false,
configurable: true,
value: AbortController
});
Object.defineProperty(self, 'AbortSignal', {
writable: true,
enumerable: false,
configurable: true,
value: AbortSignal
});
})(typeof self !== 'undefined' ? self : global);
}));

View File

@@ -0,0 +1,44 @@
{
"name": "abortcontroller-polyfill",
"version": "1.7.5",
"description": "Polyfill/ponyfill for the AbortController DOM API + optional patching of fetch (stub that calls catch, doesn't actually abort request).",
"main": "dist/umd-polyfill.js",
"files": [
"src",
"dist"
],
"scripts": {
"build": "rollup -c",
"prepare": "npm run build",
"test": "npm run build && npm-run-all test-headless eslint",
"test-headless": "SELENIUM_BROWSER=chrome E2E_HEADLESS=1 ./scripts/wdio-suppress-exitcode",
"test-chrome": "SELENIUM_BROWSER=chrome ./scripts/wdio-suppress-exitcode",
"test-firefox": "SELENIUM_BROWSER=firefox ./scripts/wdio-suppress-exitcode",
"test-inspect-brk": "E2E_WDIO_EXEC_ARGV=--inspect-brk npm run test-chrome",
"test-verbose": "SELENIUM_BROWSER=chrome E2E_LOG_LEVEL=verbose wdio wdio.conf.js",
"upgrade-packages": "npx npm-check --update",
"eslint": "eslint src/ tests/"
},
"keywords": [],
"repository": "mo/abortcontroller-polyfill",
"author": "Martin Olsson <martin@minimum.se> (https://mo.github.io)",
"license": "MIT",
"devDependencies": {
"@babel/cli": "^7.19.3",
"@babel/core": "^7.19.3",
"@babel/plugin-transform-member-expression-literals": "^7.18.6",
"@babel/preset-env": "^7.19.3",
"@wdio/cli": "^7.25.1",
"@wdio/jasmine-framework": "^7.25.1",
"@wdio/local-runner": "^7.25.1",
"@wdio/selenium-standalone-service": "^7.25.1",
"@wdio/spec-reporter": "^7.25.1",
"detect-browser": "^5.3.0",
"eslint": "^8.25.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.7.1",
"rollup": "^2.79.1",
"rollup-plugin-babel": "^4.4.0",
"webdriverio": "^7.25.1"
}
}

View File

@@ -0,0 +1,118 @@
import { polyfillNeeded } from './utils.js';
/**
* Note: the "fetch.Request" default value is available for fetch imported from
* the "node-fetch" package and not in browsers. This is OK since browsers
* will be importing umd-polyfill.js from that path "self" is passed the
* decorator so the default value will not be used (because browsers that define
* fetch also has Request). One quirky setup where self.fetch exists but
* self.Request does not is when the "unfetch" minimal fetch polyfill is used
* on top of IE11; for this case the browser will try to use the fetch.Request
* default value which in turn will be undefined but then then "if (Request)"
* will ensure that you get a patched fetch but still no Request (as expected).
* @param {fetch, Request = fetch.Request}
* @returns {fetch: abortableFetch, Request: AbortableRequest}
*/
export default function abortableFetchDecorator(patchTargets) {
if ('function' === typeof patchTargets) {
patchTargets = { fetch: patchTargets };
}
const {
fetch,
Request: NativeRequest = fetch.Request,
AbortController: NativeAbortController,
__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL = false,
} = patchTargets;
if (
!polyfillNeeded({
fetch,
Request: NativeRequest,
AbortController: NativeAbortController,
__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL,
})
) {
return { fetch, Request };
}
let Request = NativeRequest;
// Note that the "unfetch" minimal fetch polyfill defines fetch() without
// defining window.Request, and this polyfill need to work on top of unfetch
// hence we only patch it if it's available. Also we don't patch it if signal
// is already available on the Request prototype because in this case support
// is present and the patching below can cause a crash since it assigns to
// request.signal which is technically a read-only property. This latter error
// happens when you run the main5.js node-fetch example in the repo
// "abortcontroller-polyfill-examples". The exact error is:
// request.signal = init.signal;
// ^
// TypeError: Cannot set property signal of #<Request> which has only a getter
if ((Request && !Request.prototype.hasOwnProperty('signal')) || __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) {
Request = function Request(input, init) {
let signal;
if (init && init.signal) {
signal = init.signal;
// Never pass init.signal to the native Request implementation when the polyfill has
// been installed because if we're running on top of a browser with a
// working native AbortController (i.e. the polyfill was installed due to
// __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL being set), then passing our
// fake AbortSignal to the native fetch will trigger:
// TypeError: Failed to construct 'Request': member signal is not of type AbortSignal.
delete init.signal;
}
const request = new NativeRequest(input, init);
if (signal) {
Object.defineProperty(request, 'signal', {
writable: false,
enumerable: false,
configurable: true,
value: signal,
});
}
return request;
};
Request.prototype = NativeRequest.prototype;
}
const realFetch = fetch;
const abortableFetch = (input, init) => {
const signal = Request && Request.prototype.isPrototypeOf(input) ? input.signal : init ? init.signal : undefined;
if (signal) {
let abortError;
try {
abortError = new DOMException('Aborted', 'AbortError');
} catch (err) {
// IE 11 does not support calling the DOMException constructor, use a
// regular error object on it instead.
abortError = new Error('Aborted');
abortError.name = 'AbortError';
}
// Return early if already aborted, thus avoiding making an HTTP request
if (signal.aborted) {
return Promise.reject(abortError);
}
// Turn an event into a promise, reject it once `abort` is dispatched
const cancellation = new Promise((_, reject) => {
signal.addEventListener('abort', () => reject(abortError), { once: true });
});
if (init && init.signal) {
// Never pass .signal to the native implementation when the polyfill has
// been installed because if we're running on top of a browser with a
// working native AbortController (i.e. the polyfill was installed due to
// __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL being set), then passing our
// fake AbortSignal to the native fetch will trigger:
// TypeError: Failed to execute 'fetch' on 'Window': member signal is not of type AbortSignal.
delete init.signal;
}
// Return the fastest promise (don't need to wait for request to finish)
return Promise.race([cancellation, realFetch(input, init)]);
}
return realFetch(input, init);
};
return { fetch: abortableFetch, Request };
}

View File

@@ -0,0 +1,13 @@
import AbortController, { AbortSignal } from './abortcontroller';
import { polyfillNeeded } from './utils';
(function (self) {
'use strict';
if (!polyfillNeeded(self)) {
return;
}
self.AbortController = AbortController;
self.AbortSignal = AbortSignal;
})(typeof self !== 'undefined' ? self : global);

View File

@@ -0,0 +1,143 @@
class Emitter {
constructor() {
Object.defineProperty(this, 'listeners', { value: {}, writable: true, configurable: true });
}
addEventListener(type, callback, options) {
if (!(type in this.listeners)) {
this.listeners[type] = [];
}
this.listeners[type].push({ callback, options });
}
removeEventListener(type, callback) {
if (!(type in this.listeners)) {
return;
}
const stack = this.listeners[type];
for (let i = 0, l = stack.length; i < l; i++) {
if (stack[i].callback === callback) {
stack.splice(i, 1);
return;
}
}
}
dispatchEvent(event) {
if (!(event.type in this.listeners)) {
return;
}
const stack = this.listeners[event.type];
const stackToCall = stack.slice();
for (let i = 0, l = stackToCall.length; i < l; i++) {
const listener = stackToCall[i];
try {
listener.callback.call(this, event);
} catch (e) {
Promise.resolve().then(() => {
throw e;
});
}
if (listener.options && listener.options.once) {
this.removeEventListener(event.type, listener.callback);
}
}
return !event.defaultPrevented;
}
}
export class AbortSignal extends Emitter {
constructor() {
super();
// Some versions of babel does not transpile super() correctly for IE <= 10, if the parent
// constructor has failed to run, then "this.listeners" will still be undefined and then we call
// the parent constructor directly instead as a workaround. For general details, see babel bug:
// https://github.com/babel/babel/issues/3041
// This hack was added as a fix for the issue described here:
// https://github.com/Financial-Times/polyfill-library/pull/59#issuecomment-477558042
if (!this.listeners) {
Emitter.call(this);
}
// Compared to assignment, Object.defineProperty makes properties non-enumerable by default and
// we want Object.keys(new AbortController().signal) to be [] for compat with the native impl
Object.defineProperty(this, 'aborted', { value: false, writable: true, configurable: true });
Object.defineProperty(this, 'onabort', { value: null, writable: true, configurable: true });
Object.defineProperty(this, 'reason', { value: undefined, writable: true, configurable: true });
}
toString() {
return '[object AbortSignal]';
}
dispatchEvent(event) {
if (event.type === 'abort') {
this.aborted = true;
if (typeof this.onabort === 'function') {
this.onabort.call(this, event);
}
}
super.dispatchEvent(event);
}
}
export class AbortController {
constructor() {
// Compared to assignment, Object.defineProperty makes properties non-enumerable by default and
// we want Object.keys(new AbortController()) to be [] for compat with the native impl
Object.defineProperty(this, 'signal', { value: new AbortSignal(), writable: true, configurable: true });
}
abort(reason) {
let event;
try {
event = new Event('abort');
} catch (e) {
if (typeof document !== 'undefined') {
if (!document.createEvent) {
// For Internet Explorer 8:
event = document.createEventObject();
event.type = 'abort';
} else {
// For Internet Explorer 11:
event = document.createEvent('Event');
event.initEvent('abort', false, false);
}
} else {
// Fallback where document isn't available:
event = {
type: 'abort',
bubbles: false,
cancelable: false,
};
}
}
let signalReason = reason;
if (signalReason === undefined) {
if (typeof document === 'undefined') {
signalReason = new Error('This operation was aborted');
signalReason.name = 'AbortError';
} else {
try {
signalReason = new DOMException('signal is aborted without reason');
} catch (err) {
// IE 11 does not support calling the DOMException constructor, use a
// regular error object on it instead.
signalReason = new Error('This operation was aborted');
signalReason.name = 'AbortError';
}
}
}
this.signal.reason = signalReason;
this.signal.dispatchEvent(event);
}
toString() {
return '[object AbortController]';
}
}
export default AbortController;
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
// These are necessary to make sure that we get correct output for:
// Object.prototype.toString.call(new AbortController())
AbortController.prototype[Symbol.toStringTag] = 'AbortController';
AbortSignal.prototype[Symbol.toStringTag] = 'AbortSignal';
}

View File

@@ -0,0 +1,34 @@
import AbortController, { AbortSignal } from './abortcontroller';
import abortableFetch from './abortableFetch';
import { polyfillNeeded } from './utils';
(function (self) {
'use strict';
if (!polyfillNeeded(self)) {
return;
}
if (!self.fetch) {
console.warn('fetch() is not available, cannot install abortcontroller-polyfill');
return;
}
const { fetch, Request } = abortableFetch(self);
self.fetch = fetch;
self.Request = Request;
Object.defineProperty(self, 'AbortController', {
writable: true,
enumerable: false,
configurable: true,
value: AbortController,
});
Object.defineProperty(self, 'AbortSignal', {
writable: true,
enumerable: false,
configurable: true,
value: AbortSignal,
});
})(typeof self !== 'undefined' ? self : global);

View File

@@ -0,0 +1,2 @@
export { default as AbortController, AbortSignal } from './abortcontroller';
export { default as abortableFetch } from './abortableFetch';

View File

@@ -0,0 +1,17 @@
export function polyfillNeeded(self) {
if (self.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) {
console.log('__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill');
return true;
}
// Note that the "unfetch" minimal fetch polyfill defines fetch() without
// defining window.Request, and this polyfill need to work on top of unfetch
// so the below feature detection needs the !self.AbortController part.
// The Request.prototype check is also needed because Safari versions 11.1.2
// up to and including 12.1.x has a window.AbortController present but still
// does NOT correctly implement abortable fetch:
// https://bugs.webkit.org/show_bug.cgi?id=174980#c2
return (
(typeof self.Request === 'function' && !self.Request.prototype.hasOwnProperty('signal')) || !self.AbortController
);
}