From f046fe9b65f349e20897e0ddfe897aa160aa6af8 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Sat, 7 Sep 2024 01:04:10 -0400 Subject: [PATCH] Add Flight renderer This represents a virtual renderer that connects to the Flight Client. This will initially only be used to track console logs but could be expanded to more. --- .../src/backend/flight/renderer.js | 101 ++++++++++++++++++ .../src/backend/index.js | 9 +- .../src/backend/types.js | 9 +- 3 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 packages/react-devtools-shared/src/backend/flight/renderer.js diff --git a/packages/react-devtools-shared/src/backend/flight/renderer.js b/packages/react-devtools-shared/src/backend/flight/renderer.js new file mode 100644 index 0000000000000..566ec6ed9c4e9 --- /dev/null +++ b/packages/react-devtools-shared/src/backend/flight/renderer.js @@ -0,0 +1,101 @@ +/** + * 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 + */ + +import type {DevToolsHook, ReactRenderer, RendererInterface} from '../types'; + +import { + patchConsoleUsingWindowValues, + registerRenderer as registerRendererWithConsole, +} from '../console'; + +export function attach( + hook: DevToolsHook, + rendererID: number, + renderer: ReactRenderer, + global: Object, +): RendererInterface { + patchConsoleUsingWindowValues(); + registerRendererWithConsole(renderer); + + return { + cleanup() {}, + clearErrorsAndWarnings() {}, + clearErrorsForElementID() {}, + clearWarningsForElementID() {}, + getSerializedElementValueByPath() {}, + deletePath() {}, + findHostInstancesForElementID() { + return null; + }, + flushInitialOperations() {}, + getBestMatchForTrackedPath() { + return null; + }, + getDisplayNameForElementID() { + return null; + }, + getNearestMountedDOMNode() { + return null; + }, + getElementIDForHostInstance() { + return null; + }, + getInstanceAndStyle() { + return { + instance: null, + style: null, + }; + }, + getOwnersList() { + return null; + }, + getPathForElement() { + return null; + }, + getProfilingData() { + throw new Error('getProfilingData not supported by this renderer'); + }, + handleCommitFiberRoot() {}, + handleCommitFiberUnmount() {}, + handlePostCommitFiberRoot() {}, + hasElementWithId() { + return false; + }, + inspectElement( + requestID: number, + id: number, + path: Array | null, + ) { + return { + id, + responseID: requestID, + type: 'not-found', + }; + }, + logElementToConsole() {}, + patchConsoleForStrictMode() {}, + getElementAttributeByPath() {}, + getElementSourceFunctionById() {}, + overrideError() {}, + overrideSuspense() {}, + overrideValueAtPath() {}, + renamePath() {}, + renderer, + setTraceUpdatesEnabled() {}, + setTrackedPath() {}, + startProfiling() {}, + stopProfiling() {}, + storeAsGlobal() {}, + unpatchConsoleForStrictMode() {}, + updateComponentFilters() {}, + getEnvironmentNames() { + return []; + }, + }; +} diff --git a/packages/react-devtools-shared/src/backend/index.js b/packages/react-devtools-shared/src/backend/index.js index f264134b4bb53..03a8f0755d496 100644 --- a/packages/react-devtools-shared/src/backend/index.js +++ b/packages/react-devtools-shared/src/backend/index.js @@ -9,8 +9,10 @@ import Agent from './agent'; -import {attach} from './fiber/renderer'; +import {attach as attachFiber} from './fiber/renderer'; +import {attach as attachFlight} from './flight/renderer'; import {attach as attachLegacy} from './legacy/renderer'; + import {hasAssignedBackend} from './utils'; import type {DevToolsHook, ReactRenderer, RendererInterface} from './types'; @@ -80,7 +82,10 @@ export function initBackend( renderer.currentDispatcherRef != null ) { // react-reconciler v16+ - rendererInterface = attach(hook, id, renderer, global); + rendererInterface = attachFiber(hook, id, renderer, global); + } else if (typeof renderer.getCurrentComponentInfo === 'function') { + // react-flight/client + rendererInterface = attachFlight(hook, id, renderer, global); } else if (renderer.ComponentTree) { // react-dom v15 rendererInterface = attachLegacy(hook, id, renderer, global); diff --git a/packages/react-devtools-shared/src/backend/types.js b/packages/react-devtools-shared/src/backend/types.js index 3ceec410803e3..f8261c5c7927e 100644 --- a/packages/react-devtools-shared/src/backend/types.js +++ b/packages/react-devtools-shared/src/backend/types.js @@ -14,7 +14,11 @@ * Be mindful of backwards compatibility when making changes. */ -import type {ReactContext, Wakeable} from 'shared/ReactTypes'; +import type { + ReactContext, + Wakeable, + ReactComponentInfo, +} from 'shared/ReactTypes'; import type {Fiber} from 'react-reconciler/src/ReactInternalTypes'; import type { ComponentFilter, @@ -155,6 +159,9 @@ export type ReactRenderer = { // Only injected by React v16.9+ in DEV mode. // Enables DevTools to append owners-only component stack to error messages. getCurrentFiber?: () => Fiber | null, + // Only injected by React Flight Clients in DEV mode. + // Enables DevTools to append owners-only component stack to error messages from Server Components. + getCurrentComponentInfo?: () => ReactComponentInfo | null, // 17.0.2+ reconcilerVersion?: string, // Uniquely identifies React DOM v15.