From 0e6e85c3cb2c93dcefdab0193c975122ba71a051 Mon Sep 17 00:00:00 2001 From: Ruslan Lesiutin Date: Fri, 6 Oct 2023 18:26:14 +0100 Subject: [PATCH] fix[devtools/inspectElement]: dont pause initial inspectElement call when user switched tabs --- packages/react-devtools-core/src/backend.js | 2 +- .../react-devtools-core/src/standalone.js | 2 +- packages/react-devtools-inline/src/backend.js | 2 +- .../react-devtools-inline/src/frontend.js | 2 +- .../__tests__/legacy/inspectElement-test.js | 7 +- .../src/__tests__/ownersListContext-test.js | 2 +- .../src/__tests__/profilerStore-test.js | 2 +- .../__tests__/storeComponentFilters-test.js | 2 +- .../src/__tests__/utils.js | 10 +- .../src/backend/StyleX/utils.js | 2 +- .../src/backend/agent.js | 2 +- .../src/backend/legacy/renderer.js | 4 +- .../src/backend/renderer.js | 4 +- .../src/backend/types.js | 4 +- .../src/backend/utils.js | 2 +- .../react-devtools-shared/src/backendAPI.js | 43 ++++-- packages/react-devtools-shared/src/bridge.js | 2 +- .../src/devtools/store.js | 11 +- .../src/devtools/utils.js | 2 +- .../src/devtools/views/Components/Badge.js | 2 +- .../Components/CannotSuspendWarningMessage.js | 2 +- .../src/devtools/views/Components/Element.js | 2 +- .../devtools/views/Components/HocBadges.js | 2 +- .../views/Components/InspectedElement.js | 4 +- .../Components/InspectedElementContext.js | 4 +- .../Components/InspectedElementContextTree.js | 6 +- .../InspectedElementErrorsAndWarningsTree.js | 2 +- .../Components/InspectedElementHooksTree.js | 6 +- .../Components/InspectedElementPropsTree.js | 6 +- .../Components/InspectedElementStateTree.js | 6 +- .../InspectedElementStyleXPlugin.js | 4 +- .../InspectedElementSuspenseToggle.js | 4 +- .../views/Components/InspectedElementView.js | 11 +- .../src/devtools/views/Components/KeyValue.js | 4 +- .../Components/NativeStyleEditor/context.js | 2 +- .../views/Components/NewArrayValue.js | 2 +- .../devtools/views/Components/NewKeyValue.js | 2 +- .../views/Components/OwnersListContext.js | 2 +- .../devtools/views/Components/OwnersStack.js | 2 +- .../views/Components/SelectedTreeHighlight.js | 3 +- .../devtools/views/Components/TreeContext.js | 2 +- .../src/devtools/views/Components/types.js | 140 ------------------ .../src/devtools/views/DevTools.js | 4 +- .../views/Profiler/CommitTreeBuilder.js | 4 +- .../views/Profiler/RankedChartBuilder.js | 2 +- .../src/devtools/views/Profiler/Updaters.js | 4 +- .../src/devtools/views/Profiler/types.js | 6 +- .../views/Settings/ComponentsSettings.js | 4 +- .../views/Settings/SettingsContext.js | 2 +- .../src/{ => frontend}/types.js | 133 +++++++++++++++++ packages/react-devtools-shared/src/hook.js | 2 +- .../src/hookNamesCache.js | 4 +- .../src/hooks/parseHookNames/index.js | 2 +- .../parseHookNames/parseSourceAndMetadata.js | 5 +- .../react-devtools-shared/src/hydration.js | 11 +- .../src/inspectedElementCache.js | 20 ++- .../src/inspectedElementMutableSource.js | 42 +++--- packages/react-devtools-shared/src/utils.js | 15 +- 58 files changed, 305 insertions(+), 282 deletions(-) delete mode 100644 packages/react-devtools-shared/src/devtools/views/Components/types.js rename packages/react-devtools-shared/src/{ => frontend}/types.js (51%) diff --git a/packages/react-devtools-core/src/backend.js b/packages/react-devtools-core/src/backend.js index d4db634f94e97..72674a0a8cdd7 100644 --- a/packages/react-devtools-core/src/backend.js +++ b/packages/react-devtools-core/src/backend.js @@ -22,7 +22,7 @@ import { } from './cachedSettings'; import type {BackendBridge} from 'react-devtools-shared/src/bridge'; -import type {ComponentFilter} from 'react-devtools-shared/src/types'; +import type {ComponentFilter} from 'react-devtools-shared/src/frontend/types'; import type {DevToolsHook} from 'react-devtools-shared/src/backend/types'; import type {ResolveNativeStyle} from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor'; diff --git a/packages/react-devtools-core/src/standalone.js b/packages/react-devtools-core/src/standalone.js index acc43fef5dc26..00cc19f6d8342 100644 --- a/packages/react-devtools-core/src/standalone.js +++ b/packages/react-devtools-core/src/standalone.js @@ -33,7 +33,7 @@ import { import {localStorageSetItem} from 'react-devtools-shared/src/storage'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; -import type {InspectedElement} from 'react-devtools-shared/src/devtools/views/Components/types'; +import type {InspectedElement} from 'react-devtools-shared/src/frontend/types'; installHook(window); diff --git a/packages/react-devtools-inline/src/backend.js b/packages/react-devtools-inline/src/backend.js index c647eccaf1773..e7d0485b37569 100644 --- a/packages/react-devtools-inline/src/backend.js +++ b/packages/react-devtools-inline/src/backend.js @@ -8,7 +8,7 @@ import {installHook} from 'react-devtools-shared/src/hook'; import setupNativeStyleEditor from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor'; import type {BackendBridge} from 'react-devtools-shared/src/bridge'; -import type {Wall} from 'react-devtools-shared/src/types'; +import type {Wall} from 'react-devtools-shared/src/frontend/types'; function startActivation(contentWindow: any, bridge: BackendBridge) { const onSavedPreferences = (data: $FlowFixMe) => { diff --git a/packages/react-devtools-inline/src/frontend.js b/packages/react-devtools-inline/src/frontend.js index 5b9dd6e668872..b1a81e0400fec 100644 --- a/packages/react-devtools-inline/src/frontend.js +++ b/packages/react-devtools-inline/src/frontend.js @@ -13,7 +13,7 @@ import { getHideConsoleLogsInStrictMode, } from 'react-devtools-shared/src/utils'; -import type {Wall} from 'react-devtools-shared/src/types'; +import type {Wall} from 'react-devtools-shared/src/frontend/types'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; import type {Props} from 'react-devtools-shared/src/devtools/views/DevTools'; diff --git a/packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js b/packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js index 278b82ac1ab75..1940e82a80f40 100644 --- a/packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js +++ b/packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js @@ -30,12 +30,7 @@ describe('InspectedElementContext', () => { ): Promise { const rendererID = ((store.getRendererIDForElement(id): any): number); const promise = backendAPI - .inspectElement({ - bridge, - id, - path, - rendererID, - }) + .inspectElement(bridge, false, id, path, rendererID) .then(data => backendAPI.convertInspectedElementBackendToFrontend(data.value), ); diff --git a/packages/react-devtools-shared/src/__tests__/ownersListContext-test.js b/packages/react-devtools-shared/src/__tests__/ownersListContext-test.js index 0da44023c02da..c02a895feeaec 100644 --- a/packages/react-devtools-shared/src/__tests__/ownersListContext-test.js +++ b/packages/react-devtools-shared/src/__tests__/ownersListContext-test.js @@ -8,7 +8,7 @@ */ import typeof ReactTestRenderer from 'react-test-renderer'; -import type {Element} from 'react-devtools-shared/src/devtools/views/Components/types'; +import type {Element} from 'react-devtools-shared/src/frontend/types'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; import type Store from 'react-devtools-shared/src/devtools/store'; diff --git a/packages/react-devtools-shared/src/__tests__/profilerStore-test.js b/packages/react-devtools-shared/src/__tests__/profilerStore-test.js index fcc4de34eafc7..e9339649359de 100644 --- a/packages/react-devtools-shared/src/__tests__/profilerStore-test.js +++ b/packages/react-devtools-shared/src/__tests__/profilerStore-test.js @@ -187,7 +187,7 @@ describe('ProfilerStore', () => { utils.act(() => { const { ElementTypeHostComponent, - } = require('react-devtools-shared/src/types'); + } = require('react-devtools-shared/src/frontend/types'); store.componentFilters = [ utils.createElementTypeFilter(ElementTypeHostComponent), ]; diff --git a/packages/react-devtools-shared/src/__tests__/storeComponentFilters-test.js b/packages/react-devtools-shared/src/__tests__/storeComponentFilters-test.js index c5dd04865cfb6..44c7e85217cfd 100644 --- a/packages/react-devtools-shared/src/__tests__/storeComponentFilters-test.js +++ b/packages/react-devtools-shared/src/__tests__/storeComponentFilters-test.js @@ -36,7 +36,7 @@ describe('Store component filters', () => { store.recordChangeDescriptions = true; React = require('react'); - Types = require('react-devtools-shared/src/types'); + Types = require('react-devtools-shared/src/frontend/types'); utils = require('./utils'); legacyRender = utils.legacyRender; diff --git a/packages/react-devtools-shared/src/__tests__/utils.js b/packages/react-devtools-shared/src/__tests__/utils.js index 3cb4bec5c15b0..0c5a0b09f7d01 100644 --- a/packages/react-devtools-shared/src/__tests__/utils.js +++ b/packages/react-devtools-shared/src/__tests__/utils.js @@ -12,7 +12,7 @@ import typeof ReactTestRenderer from 'react-test-renderer'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; import type Store from 'react-devtools-shared/src/devtools/store'; import type {ProfilingDataFrontend} from 'react-devtools-shared/src/devtools/views/Profiler/types'; -import type {ElementType} from 'react-devtools-shared/src/types'; +import type {ElementType} from 'react-devtools-shared/src/frontend/types'; export function act( callback: Function, @@ -86,7 +86,7 @@ export function createDisplayNameFilter( source: string, isEnabled: boolean = true, ) { - const Types = require('react-devtools-shared/src/types'); + const Types = require('react-devtools-shared/src/frontend/types'); let isValid = true; try { new RegExp(source); // eslint-disable-line no-new @@ -102,7 +102,7 @@ export function createDisplayNameFilter( } export function createHOCFilter(isEnabled: boolean = true) { - const Types = require('react-devtools-shared/src/types'); + const Types = require('react-devtools-shared/src/frontend/types'); return { type: Types.ComponentFilterHOC, isEnabled, @@ -114,7 +114,7 @@ export function createElementTypeFilter( elementType: ElementType, isEnabled: boolean = true, ) { - const Types = require('react-devtools-shared/src/types'); + const Types = require('react-devtools-shared/src/frontend/types'); return { type: Types.ComponentFilterElementType, isEnabled, @@ -126,7 +126,7 @@ export function createLocationFilter( source: string, isEnabled: boolean = true, ) { - const Types = require('react-devtools-shared/src/types'); + const Types = require('react-devtools-shared/src/frontend/types'); let isValid = true; try { new RegExp(source); // eslint-disable-line no-new diff --git a/packages/react-devtools-shared/src/backend/StyleX/utils.js b/packages/react-devtools-shared/src/backend/StyleX/utils.js index 2ae10f316b78d..ad137c7184e58 100644 --- a/packages/react-devtools-shared/src/backend/StyleX/utils.js +++ b/packages/react-devtools-shared/src/backend/StyleX/utils.js @@ -7,7 +7,7 @@ * @flow */ -import type {StyleXPlugin} from 'react-devtools-shared/src/types'; +import type {StyleXPlugin} from 'react-devtools-shared/src/frontend/types'; import isArray from 'react-devtools-shared/src/isArray'; const cachedStyleNameToValueMap: Map = new Map(); diff --git a/packages/react-devtools-shared/src/backend/agent.js b/packages/react-devtools-shared/src/backend/agent.js index e15bd1705e305..54df48bfe87fd 100644 --- a/packages/react-devtools-shared/src/backend/agent.js +++ b/packages/react-devtools-shared/src/backend/agent.js @@ -42,7 +42,7 @@ import type { import type { ComponentFilter, BrowserTheme, -} from 'react-devtools-shared/src/types'; +} from 'react-devtools-shared/src/frontend/types'; import {isSynchronousXHRSupported} from './utils'; const debug = (methodName: string, ...args: Array) => { diff --git a/packages/react-devtools-shared/src/backend/legacy/renderer.js b/packages/react-devtools-shared/src/backend/legacy/renderer.js index 603d84d076548..9b1a860a40ed2 100644 --- a/packages/react-devtools-shared/src/backend/legacy/renderer.js +++ b/packages/react-devtools-shared/src/backend/legacy/renderer.js @@ -13,7 +13,7 @@ import { ElementTypeRoot, ElementTypeHostComponent, ElementTypeOtherOrUnknown, -} from 'react-devtools-shared/src/types'; +} from 'react-devtools-shared/src/frontend/types'; import {getUID, utfEncodeString, printOperationsArray} from '../../utils'; import { cleanForBridge, @@ -50,7 +50,7 @@ import type { import type { ComponentFilter, ElementType, -} from 'react-devtools-shared/src/types'; +} from 'react-devtools-shared/src/frontend/types'; import type {InspectedElement, SerializedElement} from '../types'; export type InternalInstance = Object; diff --git a/packages/react-devtools-shared/src/backend/renderer.js b/packages/react-devtools-shared/src/backend/renderer.js index 050793aa107b6..60581b4033fde 100644 --- a/packages/react-devtools-shared/src/backend/renderer.js +++ b/packages/react-devtools-shared/src/backend/renderer.js @@ -25,7 +25,7 @@ import { ElementTypeSuspenseList, ElementTypeTracingMarker, StrictMode, -} from 'react-devtools-shared/src/types'; +} from 'react-devtools-shared/src/frontend/types'; import { deletePathInObject, getDisplayName, @@ -121,7 +121,7 @@ import type { ComponentFilter, ElementType, Plugins, -} from 'react-devtools-shared/src/types'; +} from 'react-devtools-shared/src/frontend/types'; type getDisplayNameForFiberType = (fiber: Fiber) => string | null; type getTypeSymbolType = (type: any) => symbol | number; diff --git a/packages/react-devtools-shared/src/backend/types.js b/packages/react-devtools-shared/src/backend/types.js index c3a2f35a5d59b..14a26140b2d3f 100644 --- a/packages/react-devtools-shared/src/backend/types.js +++ b/packages/react-devtools-shared/src/backend/types.js @@ -21,14 +21,14 @@ import type { ComponentFilter, ElementType, Plugins, -} from 'react-devtools-shared/src/types'; +} from 'react-devtools-shared/src/frontend/types'; import type { ResolveNativeStyle, SetupNativeStyleEditor, } from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor'; import type {InitBackend} from 'react-devtools-shared/src/backend'; import type {TimelineDataExport} from 'react-devtools-timeline/src/types'; -import type {BrowserTheme} from 'react-devtools-shared/src/types'; +import type {BrowserTheme} from 'react-devtools-shared/src/frontend/types'; import type {BackendBridge} from 'react-devtools-shared/src/bridge'; import type Agent from './agent'; diff --git a/packages/react-devtools-shared/src/backend/utils.js b/packages/react-devtools-shared/src/backend/utils.js index bcadf4a7c0ccd..19d34f335abb2 100644 --- a/packages/react-devtools-shared/src/backend/utils.js +++ b/packages/react-devtools-shared/src/backend/utils.js @@ -12,7 +12,7 @@ import {compareVersions} from 'compare-versions'; import {dehydrate} from '../hydration'; import isArray from 'shared/isArray'; -import type {DehydratedData} from 'react-devtools-shared/src/devtools/views/Components/types'; +import type {DehydratedData} from 'react-devtools-shared/src/frontend/types'; // TODO: update this to the first React version that has a corresponding DevTools backend const FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER = '999.9.9'; diff --git a/packages/react-devtools-shared/src/backendAPI.js b/packages/react-devtools-shared/src/backendAPI.js index fcbfb423a7f01..27700c27c71cd 100644 --- a/packages/react-devtools-shared/src/backendAPI.js +++ b/packages/react-devtools-shared/src/backendAPI.js @@ -24,7 +24,8 @@ import type { import type { DehydratedData, InspectedElement as InspectedElementFrontend, -} from 'react-devtools-shared/src/devtools/views/Components/types'; +} from 'react-devtools-shared/src/frontend/types'; +import type {InspectedElementPath} from 'react-devtools-shared/src/frontend/types'; export function clearErrorsAndWarnings({ bridge, @@ -86,25 +87,21 @@ export function copyInspectedElementPath({ }); } -export function inspectElement({ - bridge, - forceFullData, - id, - path, - rendererID, -}: { +export function inspectElement( bridge: FrontendBridge, forceFullData: boolean, id: number, - path: Array | null, + path: InspectedElementPath | null, rendererID: number, -}): Promise { + shouldListenToPauseEvents: boolean = false, +): Promise { const requestID = requestCounter++; const promise = getPromiseForRequestID( requestID, 'inspectedElement', bridge, `Timed out while inspecting element ${id}.`, + shouldListenToPauseEvents, ); bridge.send('inspectElement', { @@ -148,16 +145,29 @@ function getPromiseForRequestID( eventType: $Keys, bridge: FrontendBridge, timeoutMessage: string, + shouldListenToPauseEvents: boolean = false, ): Promise { return new Promise((resolve, reject) => { const cleanup = () => { bridge.removeListener(eventType, onInspectedElement); - bridge.removeListener('shutdown', onDisconnect); - bridge.removeListener('pauseElementPolling', onDisconnect); + bridge.removeListener('shutdown', onShutdown); + + if (shouldListenToPauseEvents) { + bridge.removeListener('pauseElementPolling', onDisconnect); + } clearTimeout(timeoutID); }; + const onShutdown = () => { + cleanup(); + reject( + new Error( + 'Failed to inspect element. Try again or restart React DevTools.', + ), + ); + }; + const onDisconnect = () => { cleanup(); reject(new ElementPollingCancellationError()); @@ -176,8 +186,11 @@ function getPromiseForRequestID( }; bridge.addListener(eventType, onInspectedElement); - bridge.addListener('shutdown', onDisconnect); - bridge.addListener('pauseElementPolling', onDisconnect); + bridge.addListener('shutdown', onShutdown); + + if (shouldListenToPauseEvents) { + bridge.addListener('pauseElementPolling', onDisconnect); + } const timeoutID = setTimeout(onTimeout, TIMEOUT_DELAY); }); @@ -277,7 +290,7 @@ export function convertInspectedElementBackendToFrontend( export function hydrateHelper( dehydratedData: DehydratedData | null, - path?: Array, + path: ?InspectedElementPath, ): Object | null { if (dehydratedData !== null) { const {cleaned, data, unserializable} = dehydratedData; diff --git a/packages/react-devtools-shared/src/bridge.js b/packages/react-devtools-shared/src/bridge.js index b5876ddb33623..afbf564988634 100644 --- a/packages/react-devtools-shared/src/bridge.js +++ b/packages/react-devtools-shared/src/bridge.js @@ -9,7 +9,7 @@ import EventEmitter from './events'; -import type {ComponentFilter, Wall} from './types'; +import type {ComponentFilter, Wall} from './frontend/types'; import type { InspectedElementPayload, OwnersList, diff --git a/packages/react-devtools-shared/src/devtools/store.js b/packages/react-devtools-shared/src/devtools/store.js index 2c1316cba1e64..a04a31cf630f7 100644 --- a/packages/react-devtools-shared/src/devtools/store.js +++ b/packages/react-devtools-shared/src/devtools/store.js @@ -21,7 +21,7 @@ import { TREE_OPERATION_UPDATE_ERRORS_OR_WARNINGS, TREE_OPERATION_UPDATE_TREE_BASE_DURATION, } from '../constants'; -import {ElementTypeRoot} from '../types'; +import {ElementTypeRoot} from '../frontend/types'; import { getSavedComponentFilters, setSavedComponentFilters, @@ -37,10 +37,13 @@ import { BRIDGE_PROTOCOL, currentBridgeProtocol, } from 'react-devtools-shared/src/bridge'; -import {StrictMode} from 'react-devtools-shared/src/types'; +import {StrictMode} from 'react-devtools-shared/src/frontend/types'; -import type {Element} from './views/Components/types'; -import type {ComponentFilter, ElementType} from '../types'; +import type { + Element, + ComponentFilter, + ElementType, +} from 'react-devtools-shared/src/frontend/types'; import type { FrontendBridge, BridgeProtocol, diff --git a/packages/react-devtools-shared/src/devtools/utils.js b/packages/react-devtools-shared/src/devtools/utils.js index 6a6fb08f7e8f3..7de23d50c9e0a 100644 --- a/packages/react-devtools-shared/src/devtools/utils.js +++ b/packages/react-devtools-shared/src/devtools/utils.js @@ -9,7 +9,7 @@ import JSON5 from 'json5'; -import type {Element} from './views/Components/types'; +import type {Element} from 'react-devtools-shared/src/frontend/types'; import type {StateContext} from './views/Components/TreeContext'; import type Store from './store'; diff --git a/packages/react-devtools-shared/src/devtools/views/Components/Badge.js b/packages/react-devtools-shared/src/devtools/views/Components/Badge.js index dca342de4eb6c..b58818e39a3ad 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/Badge.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/Badge.js @@ -11,7 +11,7 @@ import * as React from 'react'; import {Fragment} from 'react'; import styles from './Badge.css'; -import type {ElementType} from 'react-devtools-shared/src/types'; +import type {ElementType} from 'react-devtools-shared/src/frontend/types'; type Props = { className?: string, diff --git a/packages/react-devtools-shared/src/devtools/views/Components/CannotSuspendWarningMessage.js b/packages/react-devtools-shared/src/devtools/views/Components/CannotSuspendWarningMessage.js index 3494bf95c040d..71fce90b5b80b 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/CannotSuspendWarningMessage.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/CannotSuspendWarningMessage.js @@ -13,7 +13,7 @@ import {StoreContext} from '../context'; import { ComponentFilterElementType, ElementTypeSuspense, -} from 'react-devtools-shared/src/types'; +} from 'react-devtools-shared/src/frontend/types'; export default function CannotSuspendWarningMessage(): React.Node { const store = useContext(StoreContext); diff --git a/packages/react-devtools-shared/src/devtools/views/Components/Element.js b/packages/react-devtools-shared/src/devtools/views/Components/Element.js index 0cbf7e06e0e63..b5486cd7ed83c 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/Element.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/Element.js @@ -20,7 +20,7 @@ import {useSubscription} from '../hooks'; import {logEvent} from 'react-devtools-shared/src/Logger'; import type {ItemData} from './Tree'; -import type {Element as ElementType} from './types'; +import type {Element as ElementType} from 'react-devtools-shared/src/frontend/types'; import styles from './Element.css'; import Icon from '../Icon'; diff --git a/packages/react-devtools-shared/src/devtools/views/Components/HocBadges.js b/packages/react-devtools-shared/src/devtools/views/Components/HocBadges.js index 3d23d9cd78756..6eecac653a2e6 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/HocBadges.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/HocBadges.js @@ -10,7 +10,7 @@ import * as React from 'react'; import styles from './HocBadges.css'; -import type {Element} from './types'; +import type {Element} from 'react-devtools-shared/src/frontend/types'; type Props = { element: Element, diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElement.js b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElement.js index eca9f80f2bb32..635af271ade33 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElement.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElement.js @@ -17,7 +17,7 @@ import Icon from '../Icon'; import {ModalDialogContext} from '../ModalDialog'; import ViewElementSourceContext from './ViewElementSourceContext'; import Toggle from '../Toggle'; -import {ElementTypeSuspense} from 'react-devtools-shared/src/types'; +import {ElementTypeSuspense} from 'react-devtools-shared/src/frontend/types'; import CannotSuspendWarningMessage from './CannotSuspendWarningMessage'; import InspectedElementView from './InspectedElementView'; import {InspectedElementContext} from './InspectedElementContext'; @@ -26,7 +26,7 @@ import {LOCAL_STORAGE_OPEN_IN_EDITOR_URL} from '../../../constants'; import styles from './InspectedElement.css'; -import type {InspectedElement} from './types'; +import type {InspectedElement} from 'react-devtools-shared/src/frontend/types'; export type Props = {}; diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementContext.js b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementContext.js index c1b7ac777f11a..601c8c9615a16 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementContext.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementContext.js @@ -37,12 +37,12 @@ import FetchFileWithCachingContext from 'react-devtools-shared/src/devtools/view import HookNamesModuleLoaderContext from 'react-devtools-shared/src/devtools/views/Components/HookNamesModuleLoaderContext'; import {SettingsContext} from '../Settings/SettingsContext'; -import type {HookNames} from 'react-devtools-shared/src/types'; +import type {HookNames} from 'react-devtools-shared/src/frontend/types'; import type {ReactNodeList} from 'shared/ReactTypes'; import type { Element, InspectedElement, -} from 'react-devtools-shared/src/devtools/views/Components/types'; +} from 'react-devtools-shared/src/frontend/types'; type Path = Array; type InspectPathFunction = (path: Path) => void; diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementContextTree.js b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementContextTree.js index eb74c244d9d1a..5e7276b1698a7 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementContextTree.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementContextTree.js @@ -18,11 +18,11 @@ import styles from './InspectedElementSharedStyles.css'; import { ElementTypeClass, ElementTypeFunction, -} from 'react-devtools-shared/src/types'; +} from 'react-devtools-shared/src/frontend/types'; -import type {InspectedElement} from './types'; +import type {InspectedElement} from 'react-devtools-shared/src/frontend/types'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; -import type {Element} from 'react-devtools-shared/src/devtools/views/Components/types'; +import type {Element} from 'react-devtools-shared/src/frontend/types'; type Props = { bridge: FrontendBridge, diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementErrorsAndWarningsTree.js b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementErrorsAndWarningsTree.js index c5b71122d629a..4e192d027e8df 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementErrorsAndWarningsTree.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementErrorsAndWarningsTree.js @@ -24,7 +24,7 @@ import { clearWarningsForElement as clearWarningsForElementAPI, } from 'react-devtools-shared/src/backendAPI'; -import type {InspectedElement} from './types'; +import type {InspectedElement} from 'react-devtools-shared/src/frontend/types'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; type Props = { diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementHooksTree.js b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementHooksTree.js index b1cae27bc40d1..b04fe44737581 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementHooksTree.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementHooksTree.js @@ -25,11 +25,11 @@ import {getHookSourceLocationKey} from 'react-devtools-shared/src/hookNamesCache import HookNamesModuleLoaderContext from 'react-devtools-shared/src/devtools/views/Components/HookNamesModuleLoaderContext'; import isArray from 'react-devtools-shared/src/isArray'; -import type {InspectedElement} from './types'; +import type {InspectedElement} from 'react-devtools-shared/src/frontend/types'; import type {HooksNode, HooksTree} from 'react-debug-tools/src/ReactDebugHooks'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; -import type {HookNames} from 'react-devtools-shared/src/types'; -import type {Element} from 'react-devtools-shared/src/devtools/views/Components/types'; +import type {HookNames} from 'react-devtools-shared/src/frontend/types'; +import type {Element} from 'react-devtools-shared/src/frontend/types'; import type {ToggleParseHookNames} from './InspectedElementContext'; type HooksTreeViewProps = { diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementPropsTree.js b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementPropsTree.js index f3962b3a77290..f0bc91afb3fda 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementPropsTree.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementPropsTree.js @@ -17,11 +17,11 @@ import NewKeyValue from './NewKeyValue'; import {alphaSortEntries, serializeDataForCopy} from '../utils'; import Store from '../../store'; import styles from './InspectedElementSharedStyles.css'; -import {ElementTypeClass} from 'react-devtools-shared/src/types'; +import {ElementTypeClass} from 'react-devtools-shared/src/frontend/types'; -import type {InspectedElement} from './types'; +import type {InspectedElement} from 'react-devtools-shared/src/frontend/types'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; -import type {Element} from 'react-devtools-shared/src/devtools/views/Components/types'; +import type {Element} from 'react-devtools-shared/src/frontend/types'; type Props = { bridge: FrontendBridge, diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementStateTree.js b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementStateTree.js index a1767f7f6e07c..76e02856b220d 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementStateTree.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementStateTree.js @@ -9,7 +9,7 @@ import {copy} from 'clipboard-js'; import * as React from 'react'; -import {ElementTypeHostComponent} from 'react-devtools-shared/src/types'; +import {ElementTypeHostComponent} from 'react-devtools-shared/src/frontend/types'; import Button from '../Button'; import ButtonIcon from '../ButtonIcon'; import KeyValue from './KeyValue'; @@ -17,9 +17,9 @@ import {alphaSortEntries, serializeDataForCopy} from '../utils'; import Store from '../../store'; import styles from './InspectedElementSharedStyles.css'; -import type {InspectedElement} from './types'; +import type {InspectedElement} from 'react-devtools-shared/src/frontend/types'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; -import type {Element} from 'react-devtools-shared/src/devtools/views/Components/types'; +import type {Element} from 'react-devtools-shared/src/frontend/types'; type Props = { bridge: FrontendBridge, diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementStyleXPlugin.js b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementStyleXPlugin.js index 3a93e002382d7..e4f9c4c4d7160 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementStyleXPlugin.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementStyleXPlugin.js @@ -14,9 +14,9 @@ import sharedStyles from './InspectedElementSharedStyles.css'; import styles from './InspectedElementStyleXPlugin.css'; import {enableStyleXFeatures} from 'react-devtools-feature-flags'; -import type {InspectedElement} from './types'; +import type {InspectedElement} from 'react-devtools-shared/src/frontend/types'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; -import type {Element} from 'react-devtools-shared/src/devtools/views/Components/types'; +import type {Element} from 'react-devtools-shared/src/frontend/types'; type Props = { bridge: FrontendBridge, diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSuspenseToggle.js b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSuspenseToggle.js index 09808d6e3dfdd..4b60af34dfb6f 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSuspenseToggle.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSuspenseToggle.js @@ -11,10 +11,10 @@ import * as React from 'react'; import {OptionsContext} from '../context'; import EditableValue from './EditableValue'; import Store from '../../store'; -import {ElementTypeSuspense} from 'react-devtools-shared/src/types'; +import {ElementTypeSuspense} from 'react-devtools-shared/src/frontend/types'; import styles from './InspectedElementSharedStyles.css'; -import type {InspectedElement} from './types'; +import type {InspectedElement} from 'react-devtools-shared/src/frontend/types'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; type Props = { diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementView.js b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementView.js index 4804662f31007..462677457c928 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementView.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementView.js @@ -38,8 +38,15 @@ import {logEvent} from 'react-devtools-shared/src/Logger'; import styles from './InspectedElementView.css'; import type {ContextMenuContextType} from '../context'; -import type {Element, InspectedElement, SerializedElement} from './types'; -import type {ElementType, HookNames} from 'react-devtools-shared/src/types'; +import type { + Element, + InspectedElement, + SerializedElement, +} from 'react-devtools-shared/src/frontend/types'; +import type { + ElementType, + HookNames, +} from 'react-devtools-shared/src/frontend/types'; import type {ToggleParseHookNames} from './InspectedElementContext'; export type CopyPath = (path: Array) => void; diff --git a/packages/react-devtools-shared/src/devtools/views/Components/KeyValue.js b/packages/react-devtools-shared/src/devtools/views/Components/KeyValue.js index ecfc3499795b5..72684cf5946bc 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/KeyValue.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/KeyValue.js @@ -28,8 +28,8 @@ import isArray from 'react-devtools-shared/src/isArray'; import {InspectedElementContext} from './InspectedElementContext'; import {PROTOCOLS_SUPPORTED_AS_LINKS_IN_KEY_VALUE} from './constants'; -import type {InspectedElement} from './types'; -import type {Element} from 'react-devtools-shared/src/devtools/views/Components/types'; +import type {InspectedElement} from 'react-devtools-shared/src/frontend/types'; +import type {Element} from 'react-devtools-shared/src/frontend/types'; import type {Element as ReactElement} from 'react'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; diff --git a/packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/context.js b/packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/context.js index d405dc1d54a4a..d037ca56add54 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/context.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/context.js @@ -31,7 +31,7 @@ import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; import type Store from 'react-devtools-shared/src/devtools/store'; import type {StyleAndLayout as StyleAndLayoutBackend} from 'react-devtools-shared/src/backend/NativeStyleEditor/types'; import type {StyleAndLayout as StyleAndLayoutFrontend} from './types'; -import type {Element} from 'react-devtools-shared/src/devtools/views/Components/types'; +import type {Element} from 'react-devtools-shared/src/frontend/types'; import type { Resource, Thenable, diff --git a/packages/react-devtools-shared/src/devtools/views/Components/NewArrayValue.js b/packages/react-devtools-shared/src/devtools/views/Components/NewArrayValue.js index c8247f7449623..efaf0d6ac1601 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/NewArrayValue.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/NewArrayValue.js @@ -15,7 +15,7 @@ import {smartParse} from '../../utils'; import {parseHookPathForEdit} from './utils'; import styles from './NewArrayValue.css'; -import type {InspectedElement} from './types'; +import type {InspectedElement} from 'react-devtools-shared/src/frontend/types'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; type Props = { diff --git a/packages/react-devtools-shared/src/devtools/views/Components/NewKeyValue.js b/packages/react-devtools-shared/src/devtools/views/Components/NewKeyValue.js index 8fb4cc1dc8ca9..7933ac252123d 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/NewKeyValue.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/NewKeyValue.js @@ -15,7 +15,7 @@ import EditableValue from './EditableValue'; import {parseHookPathForEdit} from './utils'; import styles from './NewKeyValue.css'; -import type {InspectedElement} from './types'; +import type {InspectedElement} from 'react-devtools-shared/src/frontend/types'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; type Props = { diff --git a/packages/react-devtools-shared/src/devtools/views/Components/OwnersListContext.js b/packages/react-devtools-shared/src/devtools/views/Components/OwnersListContext.js index 04c90a1d81912..760c490d72513 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/OwnersListContext.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/OwnersListContext.js @@ -20,7 +20,7 @@ import type {OwnersList} from 'react-devtools-shared/src/backend/types'; import type { Element, SerializedElement, -} from 'react-devtools-shared/src/devtools/views/Components/types'; +} from 'react-devtools-shared/src/frontend/types'; import type {Resource, Thenable} from '../../cache'; type Context = (id: number) => Array | null; diff --git a/packages/react-devtools-shared/src/devtools/views/Components/OwnersStack.js b/packages/react-devtools-shared/src/devtools/views/Components/OwnersStack.js index 27c57fda5f933..fda6efcc0d846 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/OwnersStack.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/OwnersStack.js @@ -32,7 +32,7 @@ import { MenuItem, } from '../Components/reach-ui/menu-button'; -import type {SerializedElement} from './types'; +import type {SerializedElement} from 'react-devtools-shared/src/frontend/types'; import styles from './OwnersStack.css'; diff --git a/packages/react-devtools-shared/src/devtools/views/Components/SelectedTreeHighlight.js b/packages/react-devtools-shared/src/devtools/views/Components/SelectedTreeHighlight.js index 72b8e6c019e8d..44183f6575234 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/SelectedTreeHighlight.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/SelectedTreeHighlight.js @@ -7,7 +7,8 @@ * @flow */ -import type {Element} from './types'; +import type {Element} from 'react-devtools-shared/src/frontend/types'; + import * as React from 'react'; import {useContext, useMemo} from 'react'; import {TreeStateContext} from './TreeContext'; diff --git a/packages/react-devtools-shared/src/devtools/views/Components/TreeContext.js b/packages/react-devtools-shared/src/devtools/views/Components/TreeContext.js index 9233a2aea4cc2..21cfea44dd825 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/TreeContext.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/TreeContext.js @@ -42,7 +42,7 @@ import {createRegExp} from '../utils'; import {BridgeContext, StoreContext} from '../context'; import Store from '../../store'; -import type {Element} from './types'; +import type {Element} from 'react-devtools-shared/src/frontend/types'; export type StateContext = { // Tree diff --git a/packages/react-devtools-shared/src/devtools/views/Components/types.js b/packages/react-devtools-shared/src/devtools/views/Components/types.js deleted file mode 100644 index 2eb4fc232cef2..0000000000000 --- a/packages/react-devtools-shared/src/devtools/views/Components/types.js +++ /dev/null @@ -1,140 +0,0 @@ -/** - * 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 {Source} from 'shared/ReactElementType'; -import type { - Dehydrated, - Unserializable, -} from 'react-devtools-shared/src/hydration'; -import type {ElementType, Plugins} from 'react-devtools-shared/src/types'; - -// Each element on the frontend corresponds to a Fiber on the backend. -// Some of its information (e.g. id, type, displayName) come from the backend. -// Other bits (e.g. weight and depth) are computed on the frontend for windowing and display purposes. -// Elements are updated on a push basis– meaning the backend pushes updates to the frontend when needed. -export type Element = { - id: number, - parentID: number, - children: Array, - type: ElementType, - displayName: string | null, - key: number | string | null, - - hocDisplayNames: null | Array, - - // Should the elements children be visible in the tree? - isCollapsed: boolean, - - // Owner (if available) - ownerID: number, - - // How many levels deep within the tree is this element? - // This determines how much indentation (left padding) should be used in the Elements tree. - depth: number, - - // How many nodes (including itself) are below this Element within the tree. - // This property is used to quickly determine the total number of Elements, - // and the Element at any given index (for windowing purposes). - weight: number, - - // This element is not in a StrictMode compliant subtree. - // Only true for React versions supporting StrictMode. - isStrictModeNonCompliant: boolean, -}; - -export type SerializedElement = { - displayName: string | null, - id: number, - key: number | string | null, - hocDisplayNames: Array | null, - type: ElementType, -}; - -export type OwnersList = { - id: number, - owners: Array | null, -}; - -export type InspectedElementResponseType = - | 'error' - | 'full-data' - | 'hydrated-path' - | 'no-change' - | 'not-found'; - -export type InspectedElement = { - id: number, - - // Does the current renderer support editable hooks and function props? - canEditHooks: boolean, - canEditFunctionProps: boolean, - - // Does the current renderer support advanced editing interface? - canEditHooksAndDeletePaths: boolean, - canEditHooksAndRenamePaths: boolean, - canEditFunctionPropsDeletePaths: boolean, - canEditFunctionPropsRenamePaths: boolean, - - // Is this Error, and can its value be overridden now? - isErrored: boolean, - canToggleError: boolean, - targetErrorBoundaryID: ?number, - - // Is this Suspense, and can its value be overridden now? - canToggleSuspense: boolean, - - // Can view component source location. - canViewSource: boolean, - - // Does the component have legacy context attached to it. - hasLegacyContext: boolean, - - // Inspectable properties. - context: Object | null, - hooks: Object | null, - props: Object | null, - state: Object | null, - key: number | string | null, - errors: Array<[string, number]>, - warnings: Array<[string, number]>, - - // List of owners - owners: Array | null, - - // Location of component in source code. - source: Source | null, - - type: ElementType, - - // Meta information about the root this element belongs to. - rootType: string | null, - - // Meta information about the renderer that created this element. - rendererPackageName: string | null, - rendererVersion: string | null, - - // UI plugins/visualizations for the inspected element. - plugins: Plugins, -}; - -// TODO: Add profiling type - -type Data = - | string - | Dehydrated - | Unserializable - | Array - | Array - | {[string]: Data}; - -export type DehydratedData = { - cleaned: Array>, - data: Data, - unserializable: Array>, -}; diff --git a/packages/react-devtools-shared/src/devtools/views/DevTools.js b/packages/react-devtools-shared/src/devtools/views/DevTools.js index 3eef04ece7c63..934ebd6928bd1 100644 --- a/packages/react-devtools-shared/src/devtools/views/DevTools.js +++ b/packages/react-devtools-shared/src/devtools/views/DevTools.js @@ -46,11 +46,11 @@ import styles from './DevTools.css'; import './root.css'; -import type {InspectedElement} from 'react-devtools-shared/src/devtools/views/Components/types'; +import type {InspectedElement} from 'react-devtools-shared/src/frontend/types'; import type {FetchFileWithCaching} from './Components/FetchFileWithCachingContext'; import type {HookNamesModuleLoaderFunction} from 'react-devtools-shared/src/devtools/views/Components/HookNamesModuleLoaderContext'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; -import type {BrowserTheme} from 'react-devtools-shared/src/types'; +import type {BrowserTheme} from 'react-devtools-shared/src/frontend/types'; export type TabID = 'components' | 'profiler'; diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitTreeBuilder.js b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitTreeBuilder.js index 4ff09adee7450..5b3b73482e3f4 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/CommitTreeBuilder.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/CommitTreeBuilder.js @@ -18,10 +18,10 @@ import { TREE_OPERATION_UPDATE_ERRORS_OR_WARNINGS, } from 'react-devtools-shared/src/constants'; import {utfDecodeString} from 'react-devtools-shared/src/utils'; -import {ElementTypeRoot} from 'react-devtools-shared/src/types'; +import {ElementTypeRoot} from 'react-devtools-shared/src/frontend/types'; import ProfilerStore from 'react-devtools-shared/src/devtools/ProfilerStore'; -import type {ElementType} from 'react-devtools-shared/src/types'; +import type {ElementType} from 'react-devtools-shared/src/frontend/types'; import type { CommitTree, CommitTreeNode, diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/RankedChartBuilder.js b/packages/react-devtools-shared/src/devtools/views/Profiler/RankedChartBuilder.js index af3c26c0fd45f..f5938674b7b23 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/RankedChartBuilder.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/RankedChartBuilder.js @@ -10,7 +10,7 @@ import { ElementTypeForwardRef, ElementTypeMemo, -} from 'react-devtools-shared/src/types'; +} from 'react-devtools-shared/src/frontend/types'; import {formatDuration} from './utils'; import ProfilerStore from 'react-devtools-shared/src/devtools/ProfilerStore'; diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/Updaters.js b/packages/react-devtools-shared/src/devtools/views/Profiler/Updaters.js index 668eec712047a..d0b3131632426 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/Updaters.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/Updaters.js @@ -8,13 +8,13 @@ */ import type {CommitTree} from './types'; -import type {SerializedElement} from '../Components/types'; +import type {SerializedElement} from 'react-devtools-shared/src/frontend/types'; import * as React from 'react'; import {useContext} from 'react'; import {ProfilerContext} from './ProfilerContext'; import styles from './Updaters.css'; -import {ElementTypeRoot} from '../../../types'; +import {ElementTypeRoot} from '../../../frontend/types'; export type Props = { commitTree: CommitTree, diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/types.js b/packages/react-devtools-shared/src/devtools/views/Profiler/types.js index 483a86d1ef24f..0df849e3fb0a4 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/types.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/types.js @@ -7,8 +7,10 @@ * @flow */ -import type {ElementType} from 'react-devtools-shared/src/types'; -import type {SerializedElement} from '../Components/types'; +import type { + ElementType, + SerializedElement, +} from 'react-devtools-shared/src/frontend/types'; import type { TimelineData, TimelineDataExport, diff --git a/packages/react-devtools-shared/src/devtools/views/Settings/ComponentsSettings.js b/packages/react-devtools-shared/src/devtools/views/Settings/ComponentsSettings.js index 99a5ab2d103f0..e19f056c8b4c9 100644 --- a/packages/react-devtools-shared/src/devtools/views/Settings/ComponentsSettings.js +++ b/packages/react-devtools-shared/src/devtools/views/Settings/ComponentsSettings.js @@ -40,7 +40,7 @@ import { ElementTypeOtherOrUnknown, ElementTypeProfiler, ElementTypeSuspense, -} from 'react-devtools-shared/src/types'; +} from 'react-devtools-shared/src/frontend/types'; import {getDefaultOpenInEditorURL} from 'react-devtools-shared/src/utils'; import styles from './SettingsShared.css'; @@ -52,7 +52,7 @@ import type { ElementType, ElementTypeComponentFilter, RegExpComponentFilter, -} from 'react-devtools-shared/src/types'; +} from 'react-devtools-shared/src/frontend/types'; const vscodeFilepath = 'vscode://file/{path}:{line}'; diff --git a/packages/react-devtools-shared/src/devtools/views/Settings/SettingsContext.js b/packages/react-devtools-shared/src/devtools/views/Settings/SettingsContext.js index 40eea803deded..a6f2c5e8c2a78 100644 --- a/packages/react-devtools-shared/src/devtools/views/Settings/SettingsContext.js +++ b/packages/react-devtools-shared/src/devtools/views/Settings/SettingsContext.js @@ -34,7 +34,7 @@ import {useLocalStorage} from '../hooks'; import {BridgeContext} from '../context'; import {logEvent} from 'react-devtools-shared/src/Logger'; -import type {BrowserTheme} from 'react-devtools-shared/src/types'; +import type {BrowserTheme} from 'react-devtools-shared/src/frontend/types'; export type DisplayDensity = 'comfortable' | 'compact'; export type Theme = 'auto' | 'light' | 'dark'; diff --git a/packages/react-devtools-shared/src/types.js b/packages/react-devtools-shared/src/frontend/types.js similarity index 51% rename from packages/react-devtools-shared/src/types.js rename to packages/react-devtools-shared/src/frontend/types.js index 51376553a3a45..3d85a0109570d 100644 --- a/packages/react-devtools-shared/src/types.js +++ b/packages/react-devtools-shared/src/frontend/types.js @@ -14,6 +14,12 @@ * Be mindful of backwards compatibility when making changes. */ +import type {Source} from 'shared/ReactElementType'; +import type { + Dehydrated, + Unserializable, +} from 'react-devtools-shared/src/hydration'; + export type BrowserTheme = 'dark' | 'light'; export type Wall = { @@ -112,3 +118,130 @@ export type Plugins = { }; export const StrictMode = 1; + +// Each element on the frontend corresponds to a Fiber on the backend. +// Some of its information (e.g. id, type, displayName) come from the backend. +// Other bits (e.g. weight and depth) are computed on the frontend for windowing and display purposes. +// Elements are updated on a push basis– meaning the backend pushes updates to the frontend when needed. +export type Element = { + id: number, + parentID: number, + children: Array, + type: ElementType, + displayName: string | null, + key: number | string | null, + + hocDisplayNames: null | Array, + + // Should the elements children be visible in the tree? + isCollapsed: boolean, + + // Owner (if available) + ownerID: number, + + // How many levels deep within the tree is this element? + // This determines how much indentation (left padding) should be used in the Elements tree. + depth: number, + + // How many nodes (including itself) are below this Element within the tree. + // This property is used to quickly determine the total number of Elements, + // and the Element at any given index (for windowing purposes). + weight: number, + + // This element is not in a StrictMode compliant subtree. + // Only true for React versions supporting StrictMode. + isStrictModeNonCompliant: boolean, +}; + +export type SerializedElement = { + displayName: string | null, + id: number, + key: number | string | null, + hocDisplayNames: Array | null, + type: ElementType, +}; + +export type OwnersList = { + id: number, + owners: Array | null, +}; + +export type InspectedElementResponseType = + | 'error' + | 'full-data' + | 'hydrated-path' + | 'no-change' + | 'not-found'; + +export type InspectedElementPath = Array; + +export type InspectedElement = { + id: number, + + // Does the current renderer support editable hooks and function props? + canEditHooks: boolean, + canEditFunctionProps: boolean, + + // Does the current renderer support advanced editing interface? + canEditHooksAndDeletePaths: boolean, + canEditHooksAndRenamePaths: boolean, + canEditFunctionPropsDeletePaths: boolean, + canEditFunctionPropsRenamePaths: boolean, + + // Is this Error, and can its value be overridden now? + isErrored: boolean, + canToggleError: boolean, + targetErrorBoundaryID: ?number, + + // Is this Suspense, and can its value be overridden now? + canToggleSuspense: boolean, + + // Can view component source location. + canViewSource: boolean, + + // Does the component have legacy context attached to it. + hasLegacyContext: boolean, + + // Inspectable properties. + context: Object | null, + hooks: Object | null, + props: Object | null, + state: Object | null, + key: number | string | null, + errors: Array<[string, number]>, + warnings: Array<[string, number]>, + + // List of owners + owners: Array | null, + + // Location of component in source code. + source: Source | null, + + type: ElementType, + + // Meta information about the root this element belongs to. + rootType: string | null, + + // Meta information about the renderer that created this element. + rendererPackageName: string | null, + rendererVersion: string | null, + + // UI plugins/visualizations for the inspected element. + plugins: Plugins, +}; + +// TODO: Add profiling type + +type Data = + | string + | Dehydrated + | Unserializable + | Array + | Array + | {[string]: Data}; + +export type DehydratedData = { + cleaned: Array>, + data: Data, + unserializable: Array>, +}; diff --git a/packages/react-devtools-shared/src/hook.js b/packages/react-devtools-shared/src/hook.js index 4df992e23ea61..92389abf6e6c7 100644 --- a/packages/react-devtools-shared/src/hook.js +++ b/packages/react-devtools-shared/src/hook.js @@ -8,7 +8,7 @@ * @flow */ -import type {BrowserTheme} from './types'; +import type {BrowserTheme} from './frontend/types'; import type { DevToolsHook, Handler, diff --git a/packages/react-devtools-shared/src/hookNamesCache.js b/packages/react-devtools-shared/src/hookNamesCache.js index 0efa5e5f9a348..89377eebb18fd 100644 --- a/packages/react-devtools-shared/src/hookNamesCache.js +++ b/packages/react-devtools-shared/src/hookNamesCache.js @@ -11,11 +11,11 @@ import {__DEBUG__} from 'react-devtools-shared/src/constants'; import type {HooksTree} from 'react-debug-tools/src/ReactDebugHooks'; import type {Thenable, Wakeable} from 'shared/ReactTypes'; -import type {Element} from './devtools/views/Components/types'; import type { + Element, HookNames, HookSourceLocationKey, -} from 'react-devtools-shared/src/types'; +} from 'react-devtools-shared/src/frontend/types'; import type {HookSource} from 'react-debug-tools/src/ReactDebugHooks'; import type {FetchFileWithCaching} from 'react-devtools-shared/src/devtools/views/Components/FetchFileWithCachingContext'; import {withCallbackPerfMeasurements} from './PerformanceLoggingUtils'; diff --git a/packages/react-devtools-shared/src/hooks/parseHookNames/index.js b/packages/react-devtools-shared/src/hooks/parseHookNames/index.js index 13b437d08ca5d..3691f74e4ff35 100644 --- a/packages/react-devtools-shared/src/hooks/parseHookNames/index.js +++ b/packages/react-devtools-shared/src/hooks/parseHookNames/index.js @@ -9,7 +9,7 @@ import type {HookSourceAndMetadata} from './loadSourceAndMetadata'; import type {HooksNode, HooksTree} from 'react-debug-tools/src/ReactDebugHooks'; -import type {HookNames} from 'react-devtools-shared/src/types'; +import type {HookNames} from 'react-devtools-shared/src/frontend/types'; import type {FetchFileWithCaching} from 'react-devtools-shared/src/devtools/views/Components/FetchFileWithCachingContext'; import {withAsyncPerfMeasurements} from 'react-devtools-shared/src/PerformanceLoggingUtils'; diff --git a/packages/react-devtools-shared/src/hooks/parseHookNames/parseSourceAndMetadata.js b/packages/react-devtools-shared/src/hooks/parseHookNames/parseSourceAndMetadata.js index 2cbefe97bf1af..40bfed48ba53f 100644 --- a/packages/react-devtools-shared/src/hooks/parseHookNames/parseSourceAndMetadata.js +++ b/packages/react-devtools-shared/src/hooks/parseHookNames/parseSourceAndMetadata.js @@ -29,7 +29,10 @@ import type { LocationKeyToHookSourceAndMetadata, } from './loadSourceAndMetadata'; import type {HookSource} from 'react-debug-tools/src/ReactDebugHooks'; -import type {HookNames, LRUCache} from 'react-devtools-shared/src/types'; +import type { + HookNames, + LRUCache, +} from 'react-devtools-shared/src/frontend/types'; type AST = mixed; diff --git a/packages/react-devtools-shared/src/hydration.js b/packages/react-devtools-shared/src/hydration.js index 431d3606961b6..f9834fcb41e2a 100644 --- a/packages/react-devtools-shared/src/hydration.js +++ b/packages/react-devtools-shared/src/hydration.js @@ -14,9 +14,12 @@ import { getInObject, formatDataForPreview, setInObject, -} from './utils'; +} from 'react-devtools-shared/src/utils'; -import type {DehydratedData} from './devtools/views/Components/types'; +import type { + DehydratedData, + InspectedElementPath, +} from 'react-devtools-shared/src/frontend/types'; export const meta = { inspectable: (Symbol('inspectable'): symbol), @@ -123,7 +126,7 @@ export function dehydrate( unserializable: Array>, path: Array, isPathAllowed: (path: Array) => boolean, - level?: number = 0, + level: number = 0, ): $PropertyType { const type = getDataType(data); @@ -365,7 +368,7 @@ export function dehydrate( export function fillInPath( object: Object, data: DehydratedData, - path: Array, + path: InspectedElementPath, value: any, ) { const target = getInObject(object, path); diff --git a/packages/react-devtools-shared/src/inspectedElementCache.js b/packages/react-devtools-shared/src/inspectedElementCache.js index bfa9fb1092406..014edf22a7fbe 100644 --- a/packages/react-devtools-shared/src/inspectedElementCache.js +++ b/packages/react-devtools-shared/src/inspectedElementCache.js @@ -21,7 +21,8 @@ import type { Element, InspectedElement as InspectedElementFrontend, InspectedElementResponseType, -} from 'react-devtools-shared/src/devtools/views/Components/types'; + InspectedElementPath, +} from 'react-devtools-shared/src/frontend/types'; const Pending = 0; const Resolved = 1; @@ -83,7 +84,7 @@ function createCacheSeed( */ export function inspectElement( element: Element, - path: Array | null, + path: InspectedElementPath | null, store: Store, bridge: FrontendBridge, ): InspectedElementFrontend | null { @@ -123,12 +124,7 @@ export function inspectElement( return null; } - inspectElementMutableSource({ - bridge, - element, - path, - rendererID: ((rendererID: any): number), - }).then( + inspectElementMutableSource(bridge, element, path, rendererID).then( ([inspectedElement]: [ InspectedElementFrontend, InspectedElementResponseType, @@ -151,6 +147,7 @@ export function inspectElement( wake(); }, ); + map.set(element, record); } @@ -186,12 +183,13 @@ export function checkForUpdate({ return; } - return inspectElementMutableSource({ + return inspectElementMutableSource( bridge, element, - path: null, + null, rendererID, - }).then( + true, + ).then( ([inspectedElement, responseType]: [ InspectedElementFrontend, InspectedElementResponseType, diff --git a/packages/react-devtools-shared/src/inspectedElementMutableSource.js b/packages/react-devtools-shared/src/inspectedElementMutableSource.js index 445d4a65d6d60..ae90bd021bcb6 100644 --- a/packages/react-devtools-shared/src/inspectedElementMutableSource.js +++ b/packages/react-devtools-shared/src/inspectedElementMutableSource.js @@ -15,20 +15,21 @@ import { } from 'react-devtools-shared/src/backendAPI'; import {fillInPath} from 'react-devtools-shared/src/hydration'; -import type {LRUCache} from 'react-devtools-shared/src/types'; +import type {LRUCache} from 'react-devtools-shared/src/frontend/types'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; import type { InspectElementError, InspectElementFullData, InspectElementHydratedPath, } from 'react-devtools-shared/src/backend/types'; +import UserError from 'react-devtools-shared/src/errors/UserError'; +import UnknownHookError from 'react-devtools-shared/src/errors/UnknownHookError'; import type { Element, InspectedElement as InspectedElementFrontend, InspectedElementResponseType, -} from 'react-devtools-shared/src/devtools/views/Components/types'; -import UserError from 'react-devtools-shared/src/errors/UserError'; -import UnknownHookError from 'react-devtools-shared/src/errors/UnknownHookError'; + InspectedElementPath, +} from 'react-devtools-shared/src/frontend/types'; // Maps element ID to inspected data. // We use an LRU for this rather than a WeakMap because of how the "no-change" optimization works. @@ -44,24 +45,18 @@ const inspectedElementCache: LRUCache = max: 25, }); -type Path = Array; - type InspectElementReturnType = [ InspectedElementFrontend, InspectedElementResponseType, ]; -export function inspectElement({ - bridge, - element, - path, - rendererID, -}: { +export function inspectElement( bridge: FrontendBridge, element: Element, - path: Path | null, + path: InspectedElementPath | null, rendererID: number, -}): Promise { + shouldListenToPauseEvents: boolean = false, +): Promise { const {id} = element; // This could indicate that the DevTools UI has been closed and reopened. @@ -69,13 +64,14 @@ export function inspectElement({ // In this case, we need to tell it to resend the full data. const forceFullData = !inspectedElementCache.has(id); - return inspectElementAPI({ + return inspectElementAPI( bridge, forceFullData, id, path, rendererID, - }).then((data: any) => { + shouldListenToPauseEvents, + ).then((data: any) => { const {type} = data; let inspectedElement; @@ -141,12 +137,14 @@ export function inspectElement({ inspectedElement = {...inspectedElement}; // Merge hydrated data - fillInPath( - inspectedElement, - value, - ((path: any): Path), - hydrateHelper(value, ((path: any): Path)), - ); + if (path != null) { + fillInPath( + inspectedElement, + value, + path, + hydrateHelper(value, path), + ); + } inspectedElementCache.set(id, inspectedElement); diff --git a/packages/react-devtools-shared/src/utils.js b/packages/react-devtools-shared/src/utils.js index bf2b7852f16cf..924b0e8aef7aa 100644 --- a/packages/react-devtools-shared/src/utils.js +++ b/packages/react-devtools-shared/src/utils.js @@ -41,20 +41,27 @@ import { LOCAL_STORAGE_SHOW_INLINE_WARNINGS_AND_ERRORS_KEY, LOCAL_STORAGE_HIDE_CONSOLE_LOGS_IN_STRICT_MODE, } from './constants'; -import {ComponentFilterElementType, ElementTypeHostComponent} from './types'; +import { + ComponentFilterElementType, + ElementTypeHostComponent, +} from './frontend/types'; import { ElementTypeRoot, ElementTypeClass, ElementTypeForwardRef, ElementTypeFunction, ElementTypeMemo, -} from 'react-devtools-shared/src/types'; +} from 'react-devtools-shared/src/frontend/types'; import {localStorageGetItem, localStorageSetItem} from './storage'; import {meta} from './hydration'; import isArray from './isArray'; -import type {ComponentFilter, ElementType, BrowserTheme} from './types'; -import type {LRUCache} from 'react-devtools-shared/src/types'; +import type { + ComponentFilter, + ElementType, + BrowserTheme, +} from './frontend/types'; +import type {LRUCache} from 'react-devtools-shared/src/frontend/types'; // $FlowFixMe[method-unbinding] const hasOwnProperty = Object.prototype.hasOwnProperty;