Use native scheduler if defined in global scope (#26554)
Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
Samuel Susla committed
May 5, 2023 at 14:01 UTC
b00e27342d6ff0f2a3a57b8e1edf66290d27cf07
7 files changed
+147
-2
packages/scheduler/index.native.js
new
+12
@@ -0,0 +1,12 @@
1
+/**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ */
9
+
10
+'use strict';
11
+
12
+export * from './src/forks/SchedulerNative';
packages/scheduler/npm/index.native.js
new
+7
@@ -0,0 +1,7 @@
1
+'use strict';
2
+
3
+if (process.env.NODE_ENV === 'production') {
4
+ module.exports = require('./cjs/scheduler.native.production.min.js');
5
+} else {
6
+ module.exports = require('./cjs/scheduler.native.development.js');
7
+}
packages/scheduler/package.json
+1
-1
@@ -2,7 +2,6 @@
2
"name": "scheduler",
3
"version": "0.23.0",
4
"description": "Cooperative scheduler for the browser environment.",
5
- "main": "index.js",
5
"repository": {
6
"type": "git",
7
"url": "https://github.com/facebook/react.git",
@@ -23,6 +22,7 @@
22
"LICENSE",
23
"README.md",
24
"index.js",
25
+ "index.native.js",
26
"unstable_mock.js",
27
"unstable_post_task.js",
28
"cjs/",
packages/scheduler/src/forks/Scheduler.js
+1
-1
@@ -46,7 +46,7 @@ import {
46
47
export type Callback = boolean => ?Callback;
48
49
-type Task = {
49
+export opaque type Task = {
50
id: number,
51
callback: Callback | null,
52
priorityLevel: PriorityLevel,
packages/scheduler/src/forks/SchedulerNative.js
new
+112
@@ -0,0 +1,112 @@
1
+/**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict
8
+ */
9
+
10
+import * as Scheduler from './Scheduler';
11
+import type {Callback, Task} from './Scheduler';
12
+import type {PriorityLevel} from '../SchedulerPriorities';
13
+import typeof * as SchedulerExportsType from './Scheduler';
14
+import typeof * as SchedulerNativeExportsType from './SchedulerNative';
15
+
16
+// This type is supposed to reflect the actual methods and arguments currently supported by the C++ implementation:
17
+// https://github.com/facebook/react-native/blob/main/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp
18
+type NativeSchedulerType = {
19
+ unstable_ImmediatePriority: PriorityLevel,
20
+ unstable_UserBlockingPriority: PriorityLevel,
21
+ unstable_NormalPriority: PriorityLevel,
22
+ unstable_IdlePriority: PriorityLevel,
23
+ unstable_LowPriority: PriorityLevel,
24
+ unstable_scheduleCallback: (
25
+ priorityLevel: PriorityLevel,
26
+ callback: Callback,
27
+ ) => Task,
28
+ unstable_cancelCallback: (task: Task) => void,
29
+ unstable_getCurrentPriorityLevel: () => PriorityLevel,
30
+ unstable_shouldYield: () => boolean,
31
+ unstable_requestPaint: () => void,
32
+ unstable_now: () => DOMHighResTimeStamp,
33
+};
34
+
35
+declare var nativeRuntimeScheduler: void | NativeSchedulerType;
36
+
37
+export const unstable_UserBlockingPriority: PriorityLevel =
38
+ typeof nativeRuntimeScheduler !== 'undefined'
39
+ ? nativeRuntimeScheduler.unstable_UserBlockingPriority
40
+ : Scheduler.unstable_UserBlockingPriority;
41
+
42
+export const unstable_NormalPriority: PriorityLevel =
43
+ typeof nativeRuntimeScheduler !== 'undefined'
44
+ ? nativeRuntimeScheduler.unstable_NormalPriority
45
+ : Scheduler.unstable_NormalPriority;
46
+
47
+export const unstable_IdlePriority: PriorityLevel =
48
+ typeof nativeRuntimeScheduler !== 'undefined'
49
+ ? nativeRuntimeScheduler.unstable_IdlePriority
50
+ : Scheduler.unstable_IdlePriority;
51
+
52
+export const unstable_LowPriority: PriorityLevel =
53
+ typeof nativeRuntimeScheduler !== 'undefined'
54
+ ? nativeRuntimeScheduler.unstable_LowPriority
55
+ : Scheduler.unstable_LowPriority;
56
+
57
+export const unstable_ImmediatePriority: PriorityLevel =
58
+ typeof nativeRuntimeScheduler !== 'undefined'
59
+ ? nativeRuntimeScheduler.unstable_ImmediatePriority
60
+ : Scheduler.unstable_ImmediatePriority;
61
+
62
+export const unstable_scheduleCallback: (
63
+ priorityLevel: PriorityLevel,
64
+ callback: Callback,
65
+) => Task =
66
+ typeof nativeRuntimeScheduler !== 'undefined'
67
+ ? nativeRuntimeScheduler.unstable_scheduleCallback
68
+ : Scheduler.unstable_scheduleCallback;
69
+
70
+export const unstable_cancelCallback: (task: Task) => void =
71
+ typeof nativeRuntimeScheduler !== 'undefined'
72
+ ? nativeRuntimeScheduler.unstable_cancelCallback
73
+ : Scheduler.unstable_cancelCallback;
74
+
75
+export const unstable_getCurrentPriorityLevel: () => PriorityLevel =
76
+ typeof nativeRuntimeScheduler !== 'undefined'
77
+ ? nativeRuntimeScheduler.unstable_getCurrentPriorityLevel
78
+ : Scheduler.unstable_getCurrentPriorityLevel;
79
+
80
+export const unstable_shouldYield: () => boolean =
81
+ typeof nativeRuntimeScheduler !== 'undefined'
82
+ ? nativeRuntimeScheduler.unstable_shouldYield
83
+ : Scheduler.unstable_shouldYield;
84
+
85
+export const unstable_requestPaint: () => void =
86
+ typeof nativeRuntimeScheduler !== 'undefined'
87
+ ? nativeRuntimeScheduler.unstable_requestPaint
88
+ : Scheduler.unstable_requestPaint;
89
+
90
+export const unstable_now: () => number | DOMHighResTimeStamp =
91
+ typeof nativeRuntimeScheduler !== 'undefined'
92
+ ? nativeRuntimeScheduler.unstable_now
93
+ : Scheduler.unstable_now;
94
+
95
+// These were never implemented on the native scheduler because React never calls them.
96
+// For consistency, let's disable them altogether and make them throw.
97
+export const unstable_next: any = throwNotImplemented;
98
+export const unstable_runWithPriority: any = throwNotImplemented;
99
+export const unstable_wrapCallback: any = throwNotImplemented;
100
+export const unstable_continueExecution: any = throwNotImplemented;
101
+export const unstable_pauseExecution: any = throwNotImplemented;
102
+export const unstable_getFirstCallbackNode: any = throwNotImplemented;
103
+export const unstable_forceFrameRate: any = throwNotImplemented;
104
+export const unstable_Profiling: any = null;
105
+
106
+function throwNotImplemented() {
107
+ throw Error('Not implemented.');
108
+}
109
+
110
+// Flow magic to verify the exports of this file match the original version.
111
+export type {Callback, Task};
112
+((((null: any): SchedulerExportsType): SchedulerNativeExportsType): SchedulerExportsType);
scripts/rollup/bundles.js
+11
@@ -935,6 +935,17 @@ const bundles = [
935
externals: ['ReactNativeInternalFeatureFlags'],
936
},
937
938
+ /******* React Scheduler Native *******/
939
+ {
940
+ bundleTypes: [NODE_DEV, NODE_PROD],
941
+ moduleType: ISOMORPHIC,
942
+ entry: 'scheduler/index.native',
943
+ global: 'SchedulerNative',
944
+ minifyWithProdErrorCodes: false,
945
+ wrapWithModuleBoundaries: false,
946
+ externals: ['ReactNativeInternalFeatureFlags'],
947
+ },
948
+
949
/******* React Scheduler Post Task (experimental) *******/
950
{
951
bundleTypes: [
scripts/rollup/validate/eslintrc.cjs.js
+3
@@ -52,6 +52,9 @@ module.exports = {
52
53
// act
54
IS_REACT_ACT_ENVIRONMENT: 'readonly',
55
+
56
+ // Native Scheduler
57
+ nativeRuntimeScheduler: 'readonly',
58
},
59
parserOptions: {
60
ecmaVersion: 2020,