From 04bc6864edb97edc5f8cb19988daea33d06c39f3 Mon Sep 17 00:00:00 2001 From: Ruslan Lesiutin Date: Wed, 22 Oct 2025 15:01:46 +0100 Subject: [PATCH] refactor: renderer config to provide async stack tagging api implementation --- .eslintrc.js | 1 + packages/react-art/src/ReactFiberConfigART.js | 5 +++++ .../src/client/ReactFiberConfigDOM.js | 5 +++++ .../src/ReactFiberConfigFabric.js | 7 +++++++ .../src/ReactFiberConfigNative.js | 2 ++ packages/react-reconciler/src/ReactProfilerTimer.js | 12 +++++++----- .../src/forks/ReactFiberConfig.custom.js | 1 + .../src/ReactFiberConfigTestHost.js | 5 +++++ scripts/flow/react-native-host-hooks.js | 3 +++ scripts/rollup/validate/eslintrc.rn.js | 2 ++ 10 files changed, 38 insertions(+), 5 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 9d142d359afc3..28ba8ff377742 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -462,6 +462,7 @@ module.exports = { globals: { nativeFabricUIManager: 'readonly', RN$enableMicrotasksInReact: 'readonly', + RN$unstable_createTask: 'readonly', }, }, { diff --git a/packages/react-art/src/ReactFiberConfigART.js b/packages/react-art/src/ReactFiberConfigART.js index ca2745beea5cc..a1a6dd8afe1fe 100644 --- a/packages/react-art/src/ReactFiberConfigART.js +++ b/packages/react-art/src/ReactFiberConfigART.js @@ -402,6 +402,11 @@ export function resolveEventTimeStamp(): number { return -1.1; } +// Async Stack Tagging API. +// Chromium-only: https://developer.chrome.com/docs/devtools/console/api#createtask +// eslint-disable-next-line react-internal/no-production-logging +export const createTask = console.createTask; + export function shouldAttemptEagerTransition() { return false; } diff --git a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js index 0af810924bbd7..6d4a537a0b87e 100644 --- a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js +++ b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js @@ -741,6 +741,11 @@ export function resolveEventTimeStamp(): number { return event && event !== schedulerEvent ? event.timeStamp : -1.1; } +// Async Stack Tagging API. +// Chromium-only: https://developer.chrome.com/docs/devtools/console/api#createtask +// eslint-disable-next-line react-internal/no-production-logging +export const createTask: typeof console.createTask | void = console.createTask; + export const isPrimaryRenderer = true; export const warnsIfNotActing = true; // This initialization code may run even on server environments diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabric.js b/packages/react-native-renderer/src/ReactFiberConfigFabric.js index 0f334eea86024..312f9f36f46ba 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigFabric.js +++ b/packages/react-native-renderer/src/ReactFiberConfigFabric.js @@ -424,6 +424,13 @@ export function resolveEventTimeStamp(): number { return -1.1; } +// This matches Chrome's console.createTask in terms of signature. +// This doesn't match Chrome's console.createTask in terms of behavior and implementation. +export const createTask: typeof console.createTask | void = + typeof RN$unstable_createTask === 'function' + ? RN$unstable_createTask + : undefined; + export function shouldAttemptEagerTransition(): boolean { return false; } diff --git a/packages/react-native-renderer/src/ReactFiberConfigNative.js b/packages/react-native-renderer/src/ReactFiberConfigNative.js index 89da4108fc9b8..f8fdeada54c14 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigNative.js +++ b/packages/react-native-renderer/src/ReactFiberConfigNative.js @@ -366,6 +366,8 @@ export function resolveEventTimeStamp(): number { return -1.1; } +export const createTask: typeof console.createTask | void = undefined; + export function shouldAttemptEagerTransition(): boolean { return false; } diff --git a/packages/react-reconciler/src/ReactProfilerTimer.js b/packages/react-reconciler/src/ReactProfilerTimer.js index 42289ea30a1db..b979416deb374 100644 --- a/packages/react-reconciler/src/ReactProfilerTimer.js +++ b/packages/react-reconciler/src/ReactProfilerTimer.js @@ -24,7 +24,11 @@ import { NoLanes, } from './ReactFiberLane'; -import {resolveEventType, resolveEventTimeStamp} from './ReactFiberConfig'; +import { + resolveEventType, + resolveEventTimeStamp, + createTask as createTaskFromFiberConfig, +} from './ReactFiberConfig'; import { enableProfilerCommitHooks, @@ -43,10 +47,8 @@ import * as Scheduler from 'scheduler'; const {unstable_now: now} = Scheduler; const createTask = - // eslint-disable-next-line react-internal/no-production-logging - __DEV__ && console.createTask - ? // eslint-disable-next-line react-internal/no-production-logging - console.createTask + __DEV__ && createTaskFromFiberConfig + ? createTaskFromFiberConfig : (name: string) => null; export const REGULAR_UPDATE: UpdateType = 0; diff --git a/packages/react-reconciler/src/forks/ReactFiberConfig.custom.js b/packages/react-reconciler/src/forks/ReactFiberConfig.custom.js index a6c6613eb39e9..abce1f0e69248 100644 --- a/packages/react-reconciler/src/forks/ReactFiberConfig.custom.js +++ b/packages/react-reconciler/src/forks/ReactFiberConfig.custom.js @@ -85,6 +85,7 @@ export const resolveUpdatePriority = $$$config.resolveUpdatePriority; export const trackSchedulerEvent = $$$config.trackSchedulerEvent; export const resolveEventType = $$$config.resolveEventType; export const resolveEventTimeStamp = $$$config.resolveEventTimeStamp; +export const createTask = $$$config.createTask; export const shouldAttemptEagerTransition = $$$config.shouldAttemptEagerTransition; export const detachDeletedInstance = $$$config.detachDeletedInstance; diff --git a/packages/react-test-renderer/src/ReactFiberConfigTestHost.js b/packages/react-test-renderer/src/ReactFiberConfigTestHost.js index e18523bc04e92..e68f1e627addf 100644 --- a/packages/react-test-renderer/src/ReactFiberConfigTestHost.js +++ b/packages/react-test-renderer/src/ReactFiberConfigTestHost.js @@ -259,6 +259,11 @@ export function resolveEventType(): null | string { export function resolveEventTimeStamp(): number { return -1.1; } +// Async Stack Tagging API. +// Chromium-only: https://developer.chrome.com/docs/devtools/console/api#createtask +// eslint-disable-next-line react-internal/no-production-logging +export const createTask = console.createTask; + export function shouldAttemptEagerTransition(): boolean { return false; } diff --git a/scripts/flow/react-native-host-hooks.js b/scripts/flow/react-native-host-hooks.js index 227c78bca24a1..b0827e012e169 100644 --- a/scripts/flow/react-native-host-hooks.js +++ b/scripts/flow/react-native-host-hooks.js @@ -303,3 +303,6 @@ declare const nativeFabricUIManager: { unstable_getCurrentEventPriority: () => number, ... }; + +// eslint-disable-next-line no-unused-vars +declare const RN$unstable_createTask: typeof console.createTask; diff --git a/scripts/rollup/validate/eslintrc.rn.js b/scripts/rollup/validate/eslintrc.rn.js index 2ee825dd77414..c7f91c05fde80 100644 --- a/scripts/rollup/validate/eslintrc.rn.js +++ b/scripts/rollup/validate/eslintrc.rn.js @@ -48,6 +48,8 @@ module.exports = { nativeFabricUIManager: 'readonly', // RN flag to enable microtasks RN$enableMicrotasksInReact: 'readonly', + // RN's temporary Async Stack Tagging API. + RN$unstable_createTask: 'readonly', // Trusted Types trustedTypes: 'readonly', // RN supports this