Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use native scheduler if defined in global scope #26554

Merged
merged 9 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions packages/scheduler/index.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* 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
*/

'use strict';

export * from './src/forks/SchedulerNative';
7 changes: 7 additions & 0 deletions packages/scheduler/npm/index.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';

if (process.env.NODE_ENV === 'production') {
module.exports = require('./cjs/scheduler.native.production.min.js');
} else {
module.exports = require('./cjs/scheduler.native.development.js');
}
2 changes: 1 addition & 1 deletion packages/scheduler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"name": "scheduler",
"version": "0.23.0",
"description": "Cooperative scheduler for the browser environment.",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/facebook/react.git",
Expand All @@ -23,6 +22,7 @@
"LICENSE",
"README.md",
"index.js",
"index.native.js",
"unstable_mock.js",
"unstable_post_task.js",
"cjs/",
Expand Down
2 changes: 1 addition & 1 deletion packages/scheduler/src/forks/Scheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import {

export type Callback = boolean => ?Callback;

type Task = {
export opaque type Task = {
id: number,
callback: Callback | null,
priorityLevel: PriorityLevel,
Expand Down
112 changes: 112 additions & 0 deletions packages/scheduler/src/forks/SchedulerNative.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**
* 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
*/

import * as Scheduler from './Scheduler';
import type {Callback, Task} from './Scheduler';
import type {PriorityLevel} from '../SchedulerPriorities';
import typeof * as SchedulerExportsType from './Scheduler';
import typeof * as SchedulerNativeExportsType from './SchedulerNative';

// This type is supposed to reflect the actual methods and arguments currently supported by the C++ implementation:
// https://github.com/facebook/react-native/blob/main/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp
type NativeSchedulerType = {
unstable_ImmediatePriority: PriorityLevel,
unstable_UserBlockingPriority: PriorityLevel,
unstable_NormalPriority: PriorityLevel,
unstable_IdlePriority: PriorityLevel,
unstable_LowPriority: PriorityLevel,
unstable_scheduleCallback: (
priorityLevel: PriorityLevel,
callback: Callback,
) => Task,
unstable_cancelCallback: (task: Task) => void,
unstable_getCurrentPriorityLevel: () => PriorityLevel,
unstable_shouldYield: () => boolean,
unstable_requestPaint: () => void,
unstable_now: () => DOMHighResTimeStamp,
};

declare var nativeRuntimeScheduler: void | NativeSchedulerType;

export const unstable_UserBlockingPriority: PriorityLevel =
typeof nativeRuntimeScheduler !== 'undefined'
? nativeRuntimeScheduler.unstable_UserBlockingPriority
: Scheduler.unstable_UserBlockingPriority;

export const unstable_NormalPriority: PriorityLevel =
typeof nativeRuntimeScheduler !== 'undefined'
? nativeRuntimeScheduler.unstable_NormalPriority
: Scheduler.unstable_NormalPriority;

export const unstable_IdlePriority: PriorityLevel =
typeof nativeRuntimeScheduler !== 'undefined'
? nativeRuntimeScheduler.unstable_IdlePriority
: Scheduler.unstable_IdlePriority;

export const unstable_LowPriority: PriorityLevel =
typeof nativeRuntimeScheduler !== 'undefined'
? nativeRuntimeScheduler.unstable_LowPriority
: Scheduler.unstable_LowPriority;

export const unstable_ImmediatePriority: PriorityLevel =
typeof nativeRuntimeScheduler !== 'undefined'
? nativeRuntimeScheduler.unstable_ImmediatePriority
: Scheduler.unstable_ImmediatePriority;

export const unstable_scheduleCallback: (
priorityLevel: PriorityLevel,
callback: Callback,
) => Task =
typeof nativeRuntimeScheduler !== 'undefined'
? nativeRuntimeScheduler.unstable_scheduleCallback
: Scheduler.unstable_scheduleCallback;

export const unstable_cancelCallback: (task: Task) => void =
typeof nativeRuntimeScheduler !== 'undefined'
? nativeRuntimeScheduler.unstable_cancelCallback
: Scheduler.unstable_cancelCallback;

export const unstable_getCurrentPriorityLevel: () => PriorityLevel =
typeof nativeRuntimeScheduler !== 'undefined'
? nativeRuntimeScheduler.unstable_getCurrentPriorityLevel
: Scheduler.unstable_getCurrentPriorityLevel;

export const unstable_shouldYield: () => boolean =
typeof nativeRuntimeScheduler !== 'undefined'
? nativeRuntimeScheduler.unstable_shouldYield
: Scheduler.unstable_shouldYield;

export const unstable_requestPaint: () => void =
typeof nativeRuntimeScheduler !== 'undefined'
? nativeRuntimeScheduler.unstable_requestPaint
: Scheduler.unstable_requestPaint;

export const unstable_now: () => number | DOMHighResTimeStamp =
typeof nativeRuntimeScheduler !== 'undefined'
? nativeRuntimeScheduler.unstable_now
: Scheduler.unstable_now;

// These were never implemented on the native scheduler because React never calls them.
// For consistency, let's disable them altogether and make them throw.
export const unstable_next: any = throwNotImplemented;
export const unstable_runWithPriority: any = throwNotImplemented;
export const unstable_wrapCallback: any = throwNotImplemented;
export const unstable_continueExecution: any = throwNotImplemented;
export const unstable_pauseExecution: any = throwNotImplemented;
export const unstable_getFirstCallbackNode: any = throwNotImplemented;
export const unstable_forceFrameRate: any = throwNotImplemented;
export const unstable_Profiling: any = null;

function throwNotImplemented() {
throw Error('Not implemented.');
}

// Flow magic to verify the exports of this file match the original version.
export type {Callback, Task};
((((null: any): SchedulerExportsType): SchedulerNativeExportsType): SchedulerExportsType);
11 changes: 11 additions & 0 deletions scripts/rollup/bundles.js
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,17 @@ const bundles = [
externals: ['ReactNativeInternalFeatureFlags'],
},

/******* React Scheduler Native *******/
{
bundleTypes: [NODE_DEV, NODE_PROD],
moduleType: ISOMORPHIC,
entry: 'scheduler/index.native',
global: 'SchedulerNative',
minifyWithProdErrorCodes: false,
wrapWithModuleBoundaries: false,
externals: ['ReactNativeInternalFeatureFlags'],
},

/******* React Scheduler Post Task (experimental) *******/
{
bundleTypes: [
Expand Down
3 changes: 3 additions & 0 deletions scripts/rollup/validate/eslintrc.cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ module.exports = {

// act
IS_REACT_ACT_ENVIRONMENT: 'readonly',

// Native Scheduler
nativeRuntimeScheduler: 'readonly',
},
parserOptions: {
ecmaVersion: 2020,
Expand Down