From b2cff474722953ac6090898850025e41431276e4 Mon Sep 17 00:00:00 2001 From: Ruslan Lesiutin <28902667+hoxyq@users.noreply.github.com> Date: Tue, 9 Sep 2025 13:00:53 +0100 Subject: [PATCH] [DevTools] feat: propagate fetchFileWithCaching from initialization options for Fusebox (#34429) Each integrator: browser extension, Chrome DevTools Frontend fork, Electron shell must define and provide `fetchFileWithCaching` in order for DevTools to be able to fetch application resources, such as scripts or source maps. More specifically, if this is available, React DevTools will be able to symbolicate source locations for component frames, owner stacks, "suspended by" Promises call frames. This will be available with the next release of React DevTools. --- .../react-devtools-fusebox/src/frontend.d.ts | 40 +++++++++++++------ .../react-devtools-fusebox/src/frontend.js | 4 ++ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/packages/react-devtools-fusebox/src/frontend.d.ts b/packages/react-devtools-fusebox/src/frontend.d.ts index a1142178f47a7..988197e89ca41 100644 --- a/packages/react-devtools-fusebox/src/frontend.d.ts +++ b/packages/react-devtools-fusebox/src/frontend.d.ts @@ -5,13 +5,19 @@ * LICENSE file in the root directory of this source tree. */ -export type MessagePayload = null | string | number | boolean | { [key: string]: MessagePayload } | MessagePayload[]; -export type Message = { event: string, payload?: MessagePayload }; +export type MessagePayload = + | null + | string + | number + | boolean + | {[key: string]: MessagePayload} + | MessagePayload[]; +export type Message = {event: string; payload?: MessagePayload}; export type WallListener = (message: Message) => void; export type Wall = { - listen: (fn: WallListener) => Function, - send: (event: string, payload?: MessagePayload) => void, + listen: (fn: WallListener) => Function; + send: (event: string, payload?: MessagePayload) => void; }; export type Bridge = { @@ -22,7 +28,7 @@ export type Bridge = { export type Store = Object; export type BrowserTheme = 'dark' | 'light'; export type Config = { - supportsReloadAndProfile?: boolean, + supportsReloadAndProfile?: boolean; }; export function createBridge(wall: Wall): Bridge; @@ -55,15 +61,23 @@ export type CanViewElementSource = ( source: ReactFunctionLocation | ReactCallSite, symbolicatedSource: ReactFunctionLocation | ReactCallSite | null, ) => boolean; +export type FetchFileWithCaching = (url: string) => Promise; export type InitializationOptions = { - bridge: Bridge, - store: Store, - theme?: BrowserTheme, - viewAttributeSourceFunction?: ViewAttributeSource, - viewElementSourceFunction?: ViewElementSource, - canViewElementSourceFunction?: CanViewElementSource, + bridge: Bridge; + store: Store; + theme?: BrowserTheme; + viewAttributeSourceFunction?: ViewAttributeSource; + viewElementSourceFunction?: ViewElementSource; + canViewElementSourceFunction?: CanViewElementSource; + fetchFileWithCaching?: FetchFileWithCaching; }; -export function initializeComponents(node: Element | Document, options: InitializationOptions): void; -export function initializeProfiler(node: Element | Document, options: InitializationOptions): void; +export function initializeComponents( + node: Element | Document, + options: InitializationOptions, +): void; +export function initializeProfiler( + node: Element | Document, + options: InitializationOptions, +): void; diff --git a/packages/react-devtools-fusebox/src/frontend.js b/packages/react-devtools-fusebox/src/frontend.js index 2bcd897c4622c..7d09e280233a9 100644 --- a/packages/react-devtools-fusebox/src/frontend.js +++ b/packages/react-devtools-fusebox/src/frontend.js @@ -24,6 +24,7 @@ import type { ViewAttributeSource, ViewElementSource, } from 'react-devtools-shared/src/devtools/views/DevTools'; +import type {FetchFileWithCaching} from 'react-devtools-shared/src/devtools/views/Components/FetchFileWithCachingContext'; import type {Config} from 'react-devtools-shared/src/devtools/store'; export function createBridge(wall?: Wall): FrontendBridge { @@ -50,6 +51,7 @@ type InitializationOptions = { viewAttributeSourceFunction?: ViewAttributeSource, viewElementSourceFunction?: ViewElementSource, canViewElementSourceFunction?: CanViewElementSource, + fetchFileWithCaching?: FetchFileWithCaching, }; function initializeTab( @@ -64,6 +66,7 @@ function initializeTab( viewAttributeSourceFunction, viewElementSourceFunction, canViewElementSourceFunction, + fetchFileWithCaching, } = options; const root = createRoot(contentWindow); @@ -79,6 +82,7 @@ function initializeTab( viewAttributeSourceFunction={viewAttributeSourceFunction} viewElementSourceFunction={viewElementSourceFunction} canViewElementSourceFunction={canViewElementSourceFunction} + fetchFileWithCaching={fetchFileWithCaching} />, ); }