UNPKG

react-native

Version:

A framework for building native apps using React

126 lines (114 loc) 3.92 kB
/** * 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 ReactNativeFeatureFlags = require('../../src/private/featureflags/ReactNativeFeatureFlags'); const NativeReactNativeFeatureFlags = require('../../src/private/featureflags/specs/NativeReactNativeFeatureFlags').default; const {polyfillGlobal} = require('../Utilities/PolyfillFunctions'); if (__DEV__) { if (typeof global.Promise !== 'function') { console.error('Promise should exist before setting up timers.'); } } const isEventLoopEnabled = (() => { if (NativeReactNativeFeatureFlags == null) { return false; } return ( ReactNativeFeatureFlags.enableBridgelessArchitecture() && !ReactNativeFeatureFlags.disableEventLoopOnBridgeless() ); })(); // 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: | 'cancelAnimationFrame' | 'cancelIdleCallback' | 'clearInterval' | 'clearTimeout' | 'requestAnimationFrame' | 'requestIdleCallback' | 'setInterval' | 'setTimeout', ) => { polyfillGlobal(name, () => require('./Timers/JSTimers')[name]); }; defineLazyTimer('setTimeout'); defineLazyTimer('clearTimeout'); defineLazyTimer('setInterval'); defineLazyTimer('clearInterval'); defineLazyTimer('requestAnimationFrame'); defineLazyTimer('cancelAnimationFrame'); defineLazyTimer('requestIdleCallback'); defineLazyTimer('cancelIdleCallback'); } else if (isEventLoopEnabled) { polyfillGlobal( 'requestIdleCallback', () => require('../../src/private/webapis/idlecallbacks/specs/NativeIdleCallbacks') .default.requestIdleCallback, ); polyfillGlobal( 'cancelIdleCallback', () => require('../../src/private/webapis/idlecallbacks/specs/NativeIdleCallbacks') .default.cancelIdleCallback, ); } // We need to check if the native module is available before accessing the // feature flag, because otherwise the API would throw an error in the legacy // architecture in OSS, where the native module isn't available. if (isEventLoopEnabled) { // This is the flag that tells React to use `queueMicrotask` to batch state // updates, instead of using the scheduler to schedule a regular task. // We use a global variable because we don't currently have any other // mechanism to pass feature flags from RN to React in OSS. global.RN$enableMicrotasksInReact = true; polyfillGlobal( 'queueMicrotask', () => require('../../src/private/webapis/microtasks/specs/NativeMicrotasks') .default.queueMicrotask, ); // We shim the immediate APIs via `queueMicrotask` to maintain the backward // compatibility. polyfillGlobal( 'setImmediate', () => require('./Timers/immediateShim').setImmediate, ); polyfillGlobal( 'clearImmediate', () => require('./Timers/immediateShim').clearImmediate, ); } else { // Polyfill it with promise (regardless it's polyfilled or native) otherwise. polyfillGlobal( 'queueMicrotask', () => require('./Timers/queueMicrotask.js').default, ); // 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, ); } }