Skip to content

[pull] main from facebook:main #188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions packages/react-devtools-core/src/standalone.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
import {localStorageSetItem} from 'react-devtools-shared/src/storage';

import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
import type {Source} from 'react-devtools-shared/src/shared/types';
import type {ReactFunctionLocation} from 'shared/ReactTypes';

export type StatusTypes = 'server-connected' | 'devtools-connected' | 'error';
export type StatusListener = (message: string, status: StatusTypes) => void;
Expand Down Expand Up @@ -144,29 +144,27 @@ async function fetchFileWithCaching(url: string) {
}

function canViewElementSourceFunction(
_source: Source,
symbolicatedSource: Source | null,
_source: ReactFunctionLocation,
symbolicatedSource: ReactFunctionLocation | null,
): boolean {
if (symbolicatedSource == null) {
return false;
}
const [, sourceURL, ,] = symbolicatedSource;

return doesFilePathExist(symbolicatedSource.sourceURL, projectRoots);
return doesFilePathExist(sourceURL, projectRoots);
}

function viewElementSourceFunction(
_source: Source,
symbolicatedSource: Source | null,
_source: ReactFunctionLocation,
symbolicatedSource: ReactFunctionLocation | null,
): void {
if (symbolicatedSource == null) {
return;
}

launchEditor(
symbolicatedSource.sourceURL,
symbolicatedSource.line,
projectRoots,
);
const [, sourceURL, line] = symbolicatedSource;
launchEditor(sourceURL, line, projectRoots);
}

function onDisconnected() {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-devtools-extensions/src/main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ function createBridgeAndStore() {
};

const viewElementSourceFunction = (source, symbolicatedSource) => {
const {sourceURL, line, column} = symbolicatedSource
const [, sourceURL, line, column] = symbolicatedSource
? symbolicatedSource
: source;

Expand Down
19 changes: 10 additions & 9 deletions packages/react-devtools-fusebox/src/frontend.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,23 @@ export type Config = {
export function createBridge(wall: Wall): Bridge;
export function createStore(bridge: Bridge, config?: Config): Store;

export type Source = {
sourceURL: string,
line: number,
column: number,
};
export type ReactFunctionLocation = [
string, // function name
string, // file name TODO: model nested eval locations as nested arrays
number, // enclosing line number
number, // enclosing column number
];
export type ViewElementSource = (
source: Source,
symbolicatedSource: Source | null,
source: ReactFunctionLocation,
symbolicatedSource: ReactFunctionLocation | null,
) => void;
export type ViewAttributeSource = (
id: number,
path: Array<string | number>,
) => void;
export type CanViewElementSource = (
source: Source,
symbolicatedSource: Source | null,
source: ReactFunctionLocation,
symbolicatedSource: ReactFunctionLocation | null,
) => boolean;

export type InitializationOptions = {
Expand Down
75 changes: 37 additions & 38 deletions packages/react-devtools-shared/src/__tests__/utils-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
getDisplayNameForReactElement,
isPlainObject,
} from 'react-devtools-shared/src/utils';
import {stackToComponentSources} from 'react-devtools-shared/src/devtools/utils';
import {stackToComponentLocations} from 'react-devtools-shared/src/devtools/utils';
import {
formatConsoleArguments,
formatConsoleArgumentsToSingleString,
Expand Down Expand Up @@ -63,14 +63,17 @@ describe('utils', () => {

it('should parse a component stack trace', () => {
expect(
stackToComponentSources(`
stackToComponentLocations(`
at Foobar (http://localhost:3000/static/js/bundle.js:103:74)
at a
at header
at div
at App`),
).toEqual([
['Foobar', ['http://localhost:3000/static/js/bundle.js', 103, 74]],
[
'Foobar',
['Foobar', 'http://localhost:3000/static/js/bundle.js', 103, 74],
],
['a', null],
['header', null],
['div', null],
Expand Down Expand Up @@ -315,12 +318,12 @@ describe('utils', () => {
'at f (https://react.dev/_next/static/chunks/pages/%5B%5B...markdownPath%5D%5D-af2ed613aedf1d57.js:1:8519)\n' +
'at r (https://react.dev/_next/static/chunks/pages/_app-dd0b77ea7bd5b246.js:1:498)\n',
),
).toEqual({
sourceURL:
'https://react.dev/_next/static/chunks/main-78a3b4c2aa4e4850.js',
line: 1,
column: 10389,
});
).toEqual([
'',
'https://react.dev/_next/static/chunks/main-78a3b4c2aa4e4850.js',
1,
10389,
]);
});

it('should construct the source from highest available frame', () => {
Expand All @@ -338,12 +341,12 @@ describe('utils', () => {
' at tt (https://react.dev/_next/static/chunks/363-3c5f1b553b6be118.js:1:165520)\n' +
' at f (https://react.dev/_next/static/chunks/pages/%5B%5B...markdownPath%5D%5D-af2ed613aedf1d57.js:1:8519)',
),
).toEqual({
sourceURL:
'https://react.dev/_next/static/chunks/848-122f91e9565d9ffa.js',
line: 5,
column: 9236,
});
).toEqual([
'',
'https://react.dev/_next/static/chunks/848-122f91e9565d9ffa.js',
5,
9236,
]);
});

it('should construct the source from frame, which has only url specified', () => {
Expand All @@ -353,12 +356,12 @@ describe('utils', () => {
' at a\n' +
' at https://react.dev/_next/static/chunks/848-122f91e9565d9ffa.js:5:9236\n',
),
).toEqual({
sourceURL:
'https://react.dev/_next/static/chunks/848-122f91e9565d9ffa.js',
line: 5,
column: 9236,
});
).toEqual([
'',
'https://react.dev/_next/static/chunks/848-122f91e9565d9ffa.js',
5,
9236,
]);
});

it('should parse sourceURL correctly if it includes parentheses', () => {
Expand All @@ -368,12 +371,12 @@ describe('utils', () => {
' at Router (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/app-router.js:181:11)\n' +
' at ErrorBoundaryHandler (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/error-boundary.js:114:9)',
),
).toEqual({
sourceURL:
'webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/react-dev-overlay/hot-reloader-client.js',
line: 307,
column: 11,
});
).toEqual([
'',
'webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/react-dev-overlay/hot-reloader-client.js',
307,
11,
]);
});

it('should support Firefox stack', () => {
Expand All @@ -383,12 +386,12 @@ describe('utils', () => {
'f@https://react.dev/_next/static/chunks/pages/%5B%5B...markdownPath%5D%5D-af2ed613aedf1d57.js:1:8535\n' +
'r@https://react.dev/_next/static/chunks/pages/_app-dd0b77ea7bd5b246.js:1:513',
),
).toEqual({
sourceURL:
'https://react.dev/_next/static/chunks/363-3c5f1b553b6be118.js',
line: 1,
column: 165558,
});
).toEqual([
'',
'https://react.dev/_next/static/chunks/363-3c5f1b553b6be118.js',
1,
165558,
]);
});
});

Expand All @@ -398,11 +401,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.f = f;
function f() { }
//# sourceMappingURL=`;
const result = {
column: 16,
line: 1,
sourceURL: 'http://test/a.mts',
};
const result = ['', 'http://test/a.mts', 1, 16];
const fs = {
'http://test/a.mts': `export function f() {}`,
'http://test/a.mjs.map': `{"version":3,"file":"a.mjs","sourceRoot":"","sources":["a.mts"],"names":[],"mappings":";;AAAA,cAAsB;AAAtB,SAAgB,CAAC,KAAI,CAAC"}`,
Expand Down
14 changes: 8 additions & 6 deletions packages/react-devtools-shared/src/backend/fiber/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ import type {
ElementType,
Plugins,
} from 'react-devtools-shared/src/frontend/types';
import type {Source} from 'react-devtools-shared/src/shared/types';
import type {ReactFunctionLocation} from 'shared/ReactTypes';
import {getSourceLocationByFiber} from './DevToolsFiberComponentStack';
import {formatOwnerStack} from '../shared/DevToolsOwnerStack';

Expand All @@ -162,7 +162,7 @@ type FiberInstance = {
parent: null | DevToolsInstance,
firstChild: null | DevToolsInstance,
nextSibling: null | DevToolsInstance,
source: null | string | Error | Source, // source ___location of this component function, or owned child stack
source: null | string | Error | ReactFunctionLocation, // source ___location of this component function, or owned child stack
logCount: number, // total number of errors/warnings last seen
treeBaseDuration: number, // the profiled time of the last render of this subtree
data: Fiber, // one of a Fiber pair
Expand Down Expand Up @@ -190,7 +190,7 @@ type FilteredFiberInstance = {
parent: null | DevToolsInstance,
firstChild: null | DevToolsInstance,
nextSibling: null | DevToolsInstance,
source: null | string | Error | Source, // always null here.
source: null | string | Error | ReactFunctionLocation, // always null here.
logCount: number, // total number of errors/warnings last seen
treeBaseDuration: number, // the profiled time of the last render of this subtree
data: Fiber, // one of a Fiber pair
Expand Down Expand Up @@ -222,7 +222,7 @@ type VirtualInstance = {
parent: null | DevToolsInstance,
firstChild: null | DevToolsInstance,
nextSibling: null | DevToolsInstance,
source: null | string | Error | Source, // source ___location of this server component, or owned child stack
source: null | string | Error | ReactFunctionLocation, // source ___location of this server component, or owned child stack
logCount: number, // total number of errors/warnings last seen
treeBaseDuration: number, // the profiled time of the last render of this subtree
// The latest info for this instance. This can be updated over time and the
Expand Down Expand Up @@ -5805,7 +5805,7 @@ export function attach(

function getSourceForFiberInstance(
fiberInstance: FiberInstance,
): Source | null {
): ReactFunctionLocation | null {
// Favor the owner source if we have one.
const ownerSource = getSourceForInstance(fiberInstance);
if (ownerSource !== null) {
Expand All @@ -5830,7 +5830,9 @@ export function attach(
return source;
}

function getSourceForInstance(instance: DevToolsInstance): Source | null {
function getSourceForInstance(
instance: DevToolsInstance,
): ReactFunctionLocation | null {
let unresolvedSource = instance.source;
if (unresolvedSource === null) {
// We don't have any source yet. We can try again later in case an owned child mounts later.
Expand Down
4 changes: 2 additions & 2 deletions packages/react-devtools-shared/src/backend/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import type {
import type {InitBackend} from 'react-devtools-shared/src/backend';
import type {TimelineDataExport} from 'react-devtools-timeline/src/types';
import type {BackendBridge} from 'react-devtools-shared/src/bridge';
import type {Source} from 'react-devtools-shared/src/shared/types';
import type {ReactFunctionLocation} from 'shared/ReactTypes';
import type Agent from './agent';

type BundleType =
Expand Down Expand Up @@ -281,7 +281,7 @@ export type InspectedElement = {

// List of owners
owners: Array<SerializedElement> | null,
source: Source | null,
source: ReactFunctionLocation | null,

type: ElementType,

Expand Down
Loading
Loading