Skip to content

Commit a14c75f

Browse files
committed
Fork abort-controller to react-native repo
1 parent 1127e54 commit a14c75f

5 files changed

Lines changed: 396 additions & 14 deletions

File tree

packages/react-native/Libraries/Core/setUpXHR.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ polyfillGlobal('URL', () => require('../Blob/URL').URL);
3636
polyfillGlobal('URLSearchParams', () => require('../Blob/URL').URLSearchParams);
3737
polyfillGlobal(
3838
'AbortController',
39-
() => require('abort-controller/dist/abort-controller').AbortController, // flowlint-line untyped-import:off
39+
() => require('../../src/private/webapis/dom/abort-api/AbortController').AbortController, // flowlint-line untyped-import:off
4040
);
4141
polyfillGlobal(
4242
'AbortSignal',
43-
() => require('abort-controller/dist/abort-controller').AbortSignal, // flowlint-line untyped-import:off
43+
() =>
44+
require('../../src/private/webapis/dom/abort-api/AbortSignal').AbortSignal, // flowlint-line untyped-import:off
4445
);
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* @flow strict
3+
* @format
4+
*/
5+
import {AbortSignal, abortSignal, createAbortSignal} from './AbortSignal';
6+
7+
/**
8+
* The AbortController.
9+
* @see https://dom.spec.whatwg.org/#abortcontroller
10+
*/
11+
export class AbortController {
12+
/**
13+
* Initialize this controller.
14+
*/
15+
constructor() {
16+
signals.set(this, createAbortSignal());
17+
}
18+
19+
/**
20+
* Returns the `AbortSignal` object associated with this object.
21+
*/
22+
// $FlowExpectedError[unsafe-getters-setters]
23+
get signal(): AbortSignal {
24+
return getSignal(this);
25+
}
26+
27+
/**
28+
* Abort and signal to any observers that the associated activity is to be aborted.
29+
*/
30+
abort(): void {
31+
abortSignal(getSignal(this));
32+
}
33+
}
34+
35+
/**
36+
* Associated signals.
37+
*/
38+
const signals = new WeakMap<AbortController, AbortSignal>()
39+
40+
/**
41+
* Get the associated signal of a given controller.
42+
*/
43+
function getSignal(controller: AbortController): AbortSignal {
44+
const signal = signals.get(controller)
45+
if (signal == null) {
46+
throw new TypeError(
47+
`Expected 'this' to be an 'AbortController' object, but got ${
48+
// $FlowExpectedError[invalid-compare]
49+
controller === null ? 'null' : typeof controller
50+
}`,
51+
);
52+
}
53+
return signal
54+
}
55+
56+
// Properties should be enumerable.
57+
//$FlowExpectedError[cannot-write]
58+
Object.defineProperties(AbortController.prototype, {
59+
signal: { enumerable: true },
60+
abort: { enumerable: true },
61+
})
62+
63+
if (typeof Symbol === "function" && typeof Symbol.toStringTag === "symbol") {
64+
//$FlowExpectedError[cannot-write]
65+
Object.defineProperty(AbortController.prototype, Symbol.toStringTag, {
66+
configurable: true,
67+
value: 'AbortController',
68+
});
69+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/**
2+
* @flow strict
3+
* @format
4+
*/
5+
import Event from '../events/Event';
6+
import EventTarget from '../events/EventTarget'
7+
8+
9+
10+
/**
11+
* The signal class.
12+
* @see https://dom.spec.whatwg.org/#abortsignal
13+
*/
14+
export class AbortSignal extends EventTarget {
15+
/**
16+
* AbortSignal cannot be constructed directly.
17+
*/
18+
constructor() {
19+
super();
20+
throw new TypeError('AbortSignal cannot be constructed directly');
21+
}
22+
23+
/**
24+
* Returns `true` if this `AbortSignal`'s `AbortController` has signaled to abort, and `false` otherwise.
25+
*/
26+
// $FlowExpectedError[unsafe-getters-setters]
27+
get aborted(): boolean {
28+
const aborted = abortedFlags.get(this);
29+
if (typeof aborted !== 'boolean') {
30+
throw new TypeError(
31+
`Expected 'this' to be an 'AbortSignal' object, but got ${
32+
// $FlowExpectedError[invalid-compare]
33+
this === null ? 'null' : typeof this
34+
}`,
35+
);
36+
}
37+
return aborted;
38+
}
39+
}
40+
41+
const listeners = new WeakMap<AbortSignal, (()=> void)>();
42+
Object.defineProperty(AbortSignal.prototype, `onabort`, {
43+
enumerable: true,
44+
configurable: true,
45+
get() {
46+
// $FlowExpectedError[object-this-reference]
47+
return listeners.get(this) || null;
48+
},
49+
// $FlowExpectedError[missing-local-annot]
50+
set(value) {
51+
// $FlowExpectedError[object-this-reference]
52+
const currentListener = listeners.get(this);
53+
if (currentListener === value) return; // same handler? do nothing!
54+
if (currentListener) {
55+
// Before setting a new listener, remove the old one if exists
56+
// $FlowExpectedError[object-this-reference]
57+
this.removeEventListener('abort', currentListener);
58+
}
59+
if (typeof value === 'function') {
60+
// $FlowExpectedError[object-this-reference]
61+
listeners.set(this, value);
62+
// $FlowExpectedError[object-this-reference]
63+
this.addEventListener('abort', value);
64+
} else {
65+
// $FlowExpectedError[object-this-reference]
66+
listeners.delete(this);
67+
}
68+
},
69+
});
70+
71+
72+
/**
73+
* Create an AbortSignal object.
74+
*/
75+
export function createAbortSignal(): AbortSignal {
76+
const signal = Object.create(AbortSignal.prototype);
77+
// $FlowExpectedError[incompatible-type]
78+
EventTarget.call(signal);
79+
abortedFlags.set(signal, false);
80+
return signal;
81+
}
82+
83+
/**
84+
* Abort a given signal.
85+
*/
86+
export function abortSignal(signal: AbortSignal): void {
87+
if (abortedFlags.get(signal) !== false) {
88+
return;
89+
}
90+
91+
abortedFlags.set(signal, true);
92+
// $FlowExpectedError[incompatible-type]
93+
signal.dispatchEvent(new Event('abort'));
94+
}
95+
96+
/**
97+
* Aborted flag for each instances.
98+
*/
99+
const abortedFlags = new WeakMap<AbortSignal, boolean>()
100+
101+
// Properties should be enumerable.
102+
//$FlowExpectedError[cannot-write]
103+
Object.defineProperties(AbortSignal.prototype, {
104+
aborted: {enumerable: true},
105+
});
106+
107+
108+
// `toString()` should return `"[object AbortSignal]"`
109+
if (typeof Symbol === "function" && typeof Symbol.toStringTag === "symbol") {
110+
Object.defineProperty(AbortSignal.prototype, Symbol.toStringTag, {
111+
configurable: true,
112+
value: "AbortSignal",
113+
})
114+
}

0 commit comments

Comments
 (0)