[Flight] Clarify that location field is a FunctionLocation not a CallSite (#33141)
Follow up to #33136. This clarifies in the types where the conversion happens from a CallSite which we use to simulate getting the enclosing line/col to a FunctionLocation which doesn't represent a CallSite but actually just the function which only has an enclosing line/col.
Sebastian Markbåge committed
May 7, 2025 at 13:02 UTC
a437c99ff7a45025367571363653c2ad5db482a7
4 files changed
+23
-10
packages/react-client/src/ReactFlightClient.js
+2
-2
@@ -15,7 +15,7 @@ import type {
15
ReactAsyncInfo,
16
ReactTimeInfo,
17
ReactStackTrace,
18
- ReactCallSite,
18
+ ReactFunctionLocation,
19
ReactErrorInfoDev,
20
} from 'shared/ReactTypes';
21
import type {LazyComponent} from 'react/src/ReactLazy';
@@ -1074,7 +1074,7 @@ function loadServerReference<A: Iterable<any>, T>(
1074
bound: null | Thenable<Array<any>>,
1075
name?: string, // DEV-only
1076
env?: string, // DEV-only
1077
- location?: ReactCallSite, // DEV-only
1077
+ location?: ReactFunctionLocation, // DEV-only
1078
},
1079
parentObject: Object,
1080
key: string,
packages/react-client/src/ReactFlightReplyClient.js
+4
-4
@@ -13,7 +13,7 @@ import type {
13
FulfilledThenable,
14
RejectedThenable,
15
ReactCustomFormAction,
16
- ReactCallSite,
16
+ ReactFunctionLocation,
17
} from 'shared/ReactTypes';
18
import type {LazyComponent} from 'react/src/ReactLazy';
19
import type {TemporaryReferenceSet} from './ReactFlightTemporaryReferences';
@@ -1248,7 +1248,7 @@ export function createBoundServerReference<A: Iterable<any>, T>(
1248
bound: null | Thenable<Array<any>>,
1249
name?: string, // DEV-only
1250
env?: string, // DEV-only
1251
- location?: ReactCallSite, // DEV-only
1251
+ location?: ReactFunctionLocation, // DEV-only
1252
},
1253
callServer: CallServerCallback,
1254
encodeFormAction?: EncodeFormActionCallback,
@@ -1309,7 +1309,7 @@ const v8FrameRegExp =
1309
// filename:0:0
1310
const jscSpiderMonkeyFrameRegExp = /(?:(.*)@)?(.*):(\d+):(\d+)/;
1311
1312
-function parseStackLocation(error: Error): null | ReactCallSite {
1312
+function parseStackLocation(error: Error): null | ReactFunctionLocation {
1313
// This parsing is special in that we know that the calling function will always
1314
// be a module that initializes the server action. We also need this part to work
1315
// cross-browser so not worth a Config. It's DEV only so not super code size
@@ -1354,7 +1354,7 @@ function parseStackLocation(error: Error): null | ReactCallSite {
1354
const line = +(parsed[3] || parsed[6]);
1355
const col = +(parsed[4] || parsed[7]);
1356
1357
- return [name, filename, line, col, line, col];
1357
+ return [name, filename, line, col];
1358
}
1359
1360
export function createServerReference<A: Iterable<any>, T>(
packages/react-server/src/ReactFlightServer.js
+10
-4
@@ -62,7 +62,7 @@ import type {
62
ReactAsyncInfo,
63
ReactTimeInfo,
64
ReactStackTrace,
65
- ReactCallSite,
65
+ ReactFunctionLocation,
66
ReactErrorInfo,
67
ReactErrorInfoDev,
68
} from 'shared/ReactTypes';
@@ -2089,7 +2089,7 @@ function serializeServerReference(
2089
const bound = boundArgs === null ? null : Promise.resolve(boundArgs);
2090
const id = getServerReferenceId(request.bundlerConfig, serverReference);
2091
2092
- let location: null | ReactCallSite = null;
2092
+ let location: null | ReactFunctionLocation = null;
2093
if (__DEV__) {
2094
const error = getServerReferenceLocation(
2095
request.bundlerConfig,
@@ -2098,7 +2098,13 @@ function serializeServerReference(
2098
if (error) {
2099
const frames = parseStackTrace(error, 1);
2100
if (frames.length > 0) {
2101
- location = frames[0];
2101
+ const firstFrame = frames[0];
2102
+ location = [
2103
+ firstFrame[0],
2104
+ firstFrame[1],
2105
+ firstFrame[2], // The line and col of the callsite represents the
2106
+ firstFrame[3], // enclosing line and col of the function.
2107
+ ];
2108
}
2109
}
2110
}
@@ -2108,7 +2114,7 @@ function serializeServerReference(
2114
bound: null | Promise<Array<any>>,
2115
name?: string, // DEV-only
2116
env?: string, // DEV-only
2111
- location?: ReactCallSite, // DEV-only
2117
+ location?: ReactFunctionLocation, // DEV-only
2118
} =
2119
__DEV__ && location !== null
2120
? {
packages/shared/ReactTypes.js
+7
@@ -192,6 +192,13 @@ export type ReactCallSite = [
192
193
export type ReactStackTrace = Array<ReactCallSite>;
194
195
+export type ReactFunctionLocation = [
196
+ string, // function name
197
+ string, // file name TODO: model nested eval locations as nested arrays
198
+ number, // enclosing line number
199
+ number, // enclosing column number
200
+];
201
+
202
export type ReactComponentInfo = {
203
+name: string,
204
+env?: string,