/
setUpTimers.js
103 lines (95 loc) · 3.25 KB
/
setUpTimers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
const {polyfillGlobal} = require('../Utilities/PolyfillFunctions');
const {isNativeFunction} = require('../Utilities/FeatureDetection');
if (__DEV__) {
if (typeof global.Promise !== 'function') {
console.error('Promise should exist before setting up timers.');
}
}
// Currently, Hermes `Promise` is implemented via Internal Bytecode.
const hasHermesPromiseQueuedToJSVM =
global.HermesInternal?.hasPromise?.() === true &&
global.HermesInternal?.useEngineQueue?.() === true;
const hasNativePromise = isNativeFunction(Promise);
const hasPromiseQueuedToJSVM = hasNativePromise || hasHermesPromiseQueuedToJSVM;
// In bridgeless mode, timers are host functions installed from cpp.
if (global.RN$Bridgeless !== true) {
/**
* Set up timers.
* You can use this module directly, or just require InitializeCore.
*/
const defineLazyTimer = (
name:
| $TEMPORARY$string<'cancelAnimationFrame'>
| $TEMPORARY$string<'cancelIdleCallback'>
| $TEMPORARY$string<'clearInterval'>
| $TEMPORARY$string<'clearTimeout'>
| $TEMPORARY$string<'requestAnimationFrame'>
| $TEMPORARY$string<'requestIdleCallback'>
| $TEMPORARY$string<'setInterval'>
| $TEMPORARY$string<'setTimeout'>,
) => {
polyfillGlobal(name, () => require('./Timers/JSTimers')[name]);
};
defineLazyTimer('setTimeout');
defineLazyTimer('clearTimeout');
defineLazyTimer('setInterval');
defineLazyTimer('clearInterval');
defineLazyTimer('requestAnimationFrame');
defineLazyTimer('cancelAnimationFrame');
defineLazyTimer('requestIdleCallback');
defineLazyTimer('cancelIdleCallback');
}
/**
* Set up immediate APIs, which is required to use the same microtask queue
* as the Promise.
*/
if (hasPromiseQueuedToJSVM) {
// When promise queues to the JSVM microtasks queue, we shim the immedaite
// APIs via `queueMicrotask` to maintain the backward compatibility.
polyfillGlobal(
'setImmediate',
() => require('./Timers/immediateShim').setImmediate,
);
polyfillGlobal(
'clearImmediate',
() => require('./Timers/immediateShim').clearImmediate,
);
} else {
// When promise was polyfilled hence is queued to the RN microtask queue,
// we polyfill the immediate APIs as aliases to the ReactNativeMicrotask APIs.
// Note that in bridgeless mode, immediate APIs are installed from cpp.
if (global.RN$Bridgeless !== true) {
polyfillGlobal(
'setImmediate',
() => require('./Timers/JSTimers').queueReactNativeMicrotask,
);
polyfillGlobal(
'clearImmediate',
() => require('./Timers/JSTimers').clearReactNativeMicrotask,
);
}
}
/**
* Set up the microtask queueing API, which is required to use the same
* microtask queue as the Promise.
*/
if (hasHermesPromiseQueuedToJSVM) {
// Fast path for Hermes.
polyfillGlobal('queueMicrotask', () => global.HermesInternal?.enqueueJob);
} else {
// Polyfill it with promise (regardless it's polyfiled or native) otherwise.
polyfillGlobal(
'queueMicrotask',
() => require('./Timers/queueMicrotask.js').default,
);
}