Skip to content

Commit a038a31

Browse files
committed
Configure the requested environment and annotate tasks at boundary between environments
1 parent e5d2245 commit a038a31

File tree

10 files changed

+129
-39
lines changed

10 files changed

+129
-39
lines changed

packages/react-client/src/ReactFlightClient.js

Lines changed: 96 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ export type Response = {
255255
_debugRootTask?: null | ConsoleTask, // DEV-only
256256
_debugFindSourceMapURL?: void | FindSourceMapURLCallback, // DEV-only
257257
_replayConsole: boolean, // DEV-only
258+
_rootEnvironmentName: string, // DEV-only, the requested environment name.
258259
};
259260

260261
function readChunk<T>(chunk: SomeChunk<T>): T {
@@ -692,7 +693,7 @@ function createElement(
692693
writable: true,
693694
value: null,
694695
});
695-
let env = '';
696+
let env = response._rootEnvironmentName;
696697
if (enableOwnerStacks) {
697698
if (owner !== null && owner.env != null) {
698699
// Interestingly we don't actually have the environment name of where
@@ -737,7 +738,7 @@ function createElement(
737738
// This owner should ideally have already been initialized to avoid getting
738739
// user stack frames on the stack.
739740
const ownerTask =
740-
owner === null ? null : initializeFakeTask(response, owner);
741+
owner === null ? null : initializeFakeTask(response, owner, env);
741742
if (ownerTask === null) {
742743
const rootTask = response._debugRootTask;
743744
if (rootTask != null) {
@@ -1355,6 +1356,7 @@ function ResponseInstance(
13551356
temporaryReferences: void | TemporaryReferenceSet,
13561357
findSourceMapURL: void | FindSourceMapURLCallback,
13571358
replayConsole: boolean,
1359+
environmentName: void | string,
13581360
) {
13591361
const chunks: Map<number, SomeChunk<any>> = new Map();
13601362
this._bundlerConfig = bundlerConfig;
@@ -1371,17 +1373,21 @@ function ResponseInstance(
13711373
this._rowLength = 0;
13721374
this._buffer = [];
13731375
this._tempRefs = temporaryReferences;
1374-
if (supportsCreateTask) {
1375-
// Any stacks that appear on the server need to be rooted somehow on the client
1376-
// so we create a root Task for this response which will be the root owner for any
1377-
// elements created by the server. We use the "use server" string to indicate that
1378-
// this is where we enter the server from the client.
1379-
// TODO: Make this string configurable.
1380-
this._debugRootTask = (console: any).createTask('"use server"');
1381-
}
13821376
if (__DEV__) {
1377+
const rootEnv = environmentName === undefined ? 'Server' : environmentName;
1378+
if (supportsCreateTask) {
1379+
// Any stacks that appear on the server need to be rooted somehow on the client
1380+
// so we create a root Task for this response which will be the root owner for any
1381+
// elements created by the server. We use the "use server" string to indicate that
1382+
// this is where we enter the server from the client.
1383+
// TODO: Make this string configurable.
1384+
this._debugRootTask = (console: any).createTask(
1385+
'"use ' + rootEnv.toLowerCase() + '"',
1386+
);
1387+
}
13831388
this._debugFindSourceMapURL = findSourceMapURL;
13841389
this._replayConsole = replayConsole;
1390+
this._rootEnvironmentName = rootEnv;
13851391
}
13861392
// Don't inline this call because it causes closure to outline the call above.
13871393
this._fromJSON = createFromJSONCallback(this);
@@ -1396,6 +1402,7 @@ export function createResponse(
13961402
temporaryReferences: void | TemporaryReferenceSet,
13971403
findSourceMapURL: void | FindSourceMapURLCallback,
13981404
replayConsole: boolean,
1405+
environmentName: void | string,
13991406
): Response {
14001407
// $FlowFixMe[invalid-constructor]: the shapes are exact here but Flow doesn't like constructors
14011408
return new ResponseInstance(
@@ -1407,6 +1414,7 @@ export function createResponse(
14071414
temporaryReferences,
14081415
findSourceMapURL,
14091416
replayConsole,
1417+
environmentName,
14101418
);
14111419
}
14121420

@@ -1864,7 +1872,7 @@ function resolveErrorDev(
18641872
'An error occurred in the Server Components render but no message was provided',
18651873
),
18661874
);
1867-
const rootTask = response._debugRootTask;
1875+
const rootTask = getRootTask(response, env);
18681876
if (rootTask != null) {
18691877
error = rootTask.run(callStack);
18701878
} else {
@@ -2098,52 +2106,99 @@ function buildFakeCallStack<T>(
20982106
return callStack;
20992107
}
21002108

2109+
function getRootTask(
2110+
response: Response,
2111+
childEnvironmentName: string,
2112+
): null | ConsoleTask {
2113+
const rootTask = response._debugRootTask;
2114+
if (!rootTask) {
2115+
return null;
2116+
}
2117+
if (response._rootEnvironmentName !== childEnvironmentName) {
2118+
// If the root most owner component is itself in a different environment than the requested
2119+
// environment then we create an extra task to indicate that we're transitioning into it.
2120+
// Like if one environment just requests another environment.
2121+
const createTaskFn = (console: any).createTask.bind(
2122+
console,
2123+
'"use ' + childEnvironmentName.toLowerCase() + '"',
2124+
);
2125+
return rootTask.run(createTaskFn);
2126+
}
2127+
return rootTask;
2128+
}
2129+
21012130
function initializeFakeTask(
21022131
response: Response,
21032132
debugInfo: ReactComponentInfo | ReactAsyncInfo,
2133+
childEnvironmentName: string,
21042134
): null | ConsoleTask {
21052135
if (!supportsCreateTask) {
21062136
return null;
21072137
}
21082138
const componentInfo: ReactComponentInfo = (debugInfo: any); // Refined
2109-
const cachedEntry = componentInfo.debugTask;
2110-
if (cachedEntry !== undefined) {
2111-
return cachedEntry;
2112-
}
2113-
21142139
if (debugInfo.stack == null) {
21152140
// If this is an error, we should've really already initialized the task.
21162141
// If it's null, we can't initialize a task.
21172142
return null;
21182143
}
2119-
21202144
const stack = debugInfo.stack;
2121-
const env = componentInfo.env == null ? '' : componentInfo.env;
2122-
const ownerTask =
2123-
componentInfo.owner == null
2124-
? null
2125-
: initializeFakeTask(response, componentInfo.owner);
2126-
2127-
const createTaskFn = (console: any).createTask.bind(
2128-
console,
2129-
getServerComponentTaskName(componentInfo),
2130-
);
2131-
const callStack = buildFakeCallStack(response, stack, env, createTaskFn);
2145+
const env: string =
2146+
componentInfo.env == null
2147+
? response._rootEnvironmentName
2148+
: componentInfo.env;
2149+
if (env !== childEnvironmentName) {
2150+
// This is the boundary between two environments so we'll annotate the task name.
2151+
// That is unusual so we don't cache it.
2152+
const ownerTask =
2153+
componentInfo.owner == null
2154+
? null
2155+
: initializeFakeTask(response, componentInfo.owner, env);
2156+
return buildFakeTask(
2157+
response,
2158+
ownerTask,
2159+
stack,
2160+
'"use ' + childEnvironmentName.toLowerCase() + '"',
2161+
env,
2162+
);
2163+
} else {
2164+
const cachedEntry = componentInfo.debugTask;
2165+
if (cachedEntry !== undefined) {
2166+
return cachedEntry;
2167+
}
2168+
const ownerTask =
2169+
componentInfo.owner == null
2170+
? null
2171+
: initializeFakeTask(response, componentInfo.owner, env);
2172+
// $FlowFixMe[cannot-write]: We consider this part of initialization.
2173+
return (componentInfo.debugTask = buildFakeTask(
2174+
response,
2175+
ownerTask,
2176+
stack,
2177+
getServerComponentTaskName(componentInfo),
2178+
env,
2179+
));
2180+
}
2181+
}
21322182

2133-
let componentTask;
2183+
function buildFakeTask(
2184+
response: Response,
2185+
ownerTask: null | ConsoleTask,
2186+
stack: ReactStackTrace,
2187+
taskName: string,
2188+
env: string,
2189+
): ConsoleTask {
2190+
const createTaskFn = (console: any).createTask.bind(console, taskName);
2191+
const callStack = buildFakeCallStack(response, stack, env, createTaskFn);
21342192
if (ownerTask === null) {
2135-
const rootTask = response._debugRootTask;
2193+
const rootTask = getRootTask(response, env);
21362194
if (rootTask != null) {
2137-
componentTask = rootTask.run(callStack);
2195+
return rootTask.run(callStack);
21382196
} else {
2139-
componentTask = callStack();
2197+
return callStack();
21402198
}
21412199
} else {
2142-
componentTask = ownerTask.run(callStack);
2200+
return ownerTask.run(callStack);
21432201
}
2144-
// $FlowFixMe[cannot-write]: We consider this part of initialization.
2145-
componentInfo.debugTask = componentTask;
2146-
return componentTask;
21472202
}
21482203

21492204
const createFakeJSXCallStack = {
@@ -2216,7 +2271,9 @@ function resolveDebugInfo(
22162271
// We eagerly initialize the fake task because this resolving happens outside any
22172272
// render phase so we're not inside a user space stack at this point. If we waited
22182273
// to initialize it when we need it, we might be inside user code.
2219-
initializeFakeTask(response, debugInfo);
2274+
const env =
2275+
debugInfo.env === undefined ? response._rootEnvironmentName : debugInfo.env;
2276+
initializeFakeTask(response, debugInfo, env);
22202277
initializeFakeStack(response, debugInfo);
22212278

22222279
const chunk = getChunk(response, id);
@@ -2266,7 +2323,7 @@ function resolveConsoleEntry(
22662323
printToConsole.bind(null, methodName, args, env),
22672324
);
22682325
if (owner != null) {
2269-
const task = initializeFakeTask(response, owner);
2326+
const task = initializeFakeTask(response, owner, env);
22702327
initializeFakeStack(response, owner);
22712328
if (task !== null) {
22722329
task.run(callStack);
@@ -2275,7 +2332,7 @@ function resolveConsoleEntry(
22752332
// TODO: Set the current owner so that captureOwnerStack() adds the component
22762333
// stack during the replay - if needed.
22772334
}
2278-
const rootTask = response._debugRootTask;
2335+
const rootTask = getRootTask(response, env);
22792336
if (rootTask != null) {
22802337
rootTask.run(callStack);
22812338
return;

packages/react-noop-renderer/src/ReactNoopFlightClient.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ function read<T>(source: Source, options: ReadOptions): Thenable<T> {
6565
undefined,
6666
options !== undefined ? options.findSourceMapURL : undefined,
6767
true,
68+
undefined,
6869
);
6970
for (let i = 0; i < source.length; i++) {
7071
processBinaryChunk(response, source[i], 0);

packages/react-server-dom-esm/src/ReactFlightDOMClientBrowser.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export type Options = {
4343
temporaryReferences?: TemporaryReferenceSet,
4444
findSourceMapURL?: FindSourceMapURLCallback,
4545
replayConsoleLogs?: boolean,
46+
environmentName?: string,
4647
};
4748

4849
function createResponseFromOptions(options: void | Options) {
@@ -59,6 +60,9 @@ function createResponseFromOptions(options: void | Options) {
5960
? options.findSourceMapURL
6061
: undefined,
6162
__DEV__ ? (options ? options.replayConsoleLogs !== false : true) : false, // defaults to true
63+
__DEV__ && options && options.environmentName
64+
? options.environmentName
65+
: undefined,
6266
);
6367
}
6468

packages/react-server-dom-esm/src/ReactFlightDOMClientNode.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export type Options = {
5151
encodeFormAction?: EncodeFormActionCallback,
5252
findSourceMapURL?: FindSourceMapURLCallback,
5353
replayConsoleLogs?: boolean,
54+
environmentName?: string,
5455
};
5556

5657
function createFromNodeStream<T>(
@@ -70,6 +71,9 @@ function createFromNodeStream<T>(
7071
? options.findSourceMapURL
7172
: undefined,
7273
__DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
74+
__DEV__ && options && options.environmentName
75+
? options.environmentName
76+
: undefined,
7377
);
7478
stream.on('data', chunk => {
7579
processBinaryChunk(response, chunk);

packages/react-server-dom-turbopack/src/ReactFlightDOMClientBrowser.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export type Options = {
4242
temporaryReferences?: TemporaryReferenceSet,
4343
findSourceMapURL?: FindSourceMapURLCallback,
4444
replayConsoleLogs?: boolean,
45+
environmentName?: string,
4546
};
4647

4748
function createResponseFromOptions(options: void | Options) {
@@ -58,6 +59,9 @@ function createResponseFromOptions(options: void | Options) {
5859
? options.findSourceMapURL
5960
: undefined,
6061
__DEV__ ? (options ? options.replayConsoleLogs !== false : true) : false, // defaults to true
62+
__DEV__ && options && options.environmentName
63+
? options.environmentName
64+
: undefined,
6165
);
6266
}
6367

packages/react-server-dom-turbopack/src/ReactFlightDOMClientEdge.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export type Options = {
7272
temporaryReferences?: TemporaryReferenceSet,
7373
findSourceMapURL?: FindSourceMapURLCallback,
7474
replayConsoleLogs?: boolean,
75+
environmentName?: string,
7576
};
7677

7778
function createResponseFromOptions(options: Options) {
@@ -88,6 +89,9 @@ function createResponseFromOptions(options: Options) {
8889
? options.findSourceMapURL
8990
: undefined,
9091
__DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
92+
__DEV__ && options && options.environmentName
93+
? options.environmentName
94+
: undefined,
9195
);
9296
}
9397

packages/react-server-dom-turbopack/src/ReactFlightDOMClientNode.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export type Options = {
6161
encodeFormAction?: EncodeFormActionCallback,
6262
findSourceMapURL?: FindSourceMapURLCallback,
6363
replayConsoleLogs?: boolean,
64+
environmentName?: string,
6465
};
6566

6667
function createFromNodeStream<T>(
@@ -79,6 +80,9 @@ function createFromNodeStream<T>(
7980
? options.findSourceMapURL
8081
: undefined,
8182
__DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
83+
__DEV__ && options && options.environmentName
84+
? options.environmentName
85+
: undefined,
8286
);
8387
stream.on('data', chunk => {
8488
processBinaryChunk(response, chunk);

packages/react-server-dom-webpack/src/ReactFlightDOMClientBrowser.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export type Options = {
4242
temporaryReferences?: TemporaryReferenceSet,
4343
findSourceMapURL?: FindSourceMapURLCallback,
4444
replayConsoleLogs?: boolean,
45+
environmentName?: string,
4546
};
4647

4748
function createResponseFromOptions(options: void | Options) {
@@ -58,6 +59,9 @@ function createResponseFromOptions(options: void | Options) {
5859
? options.findSourceMapURL
5960
: undefined,
6061
__DEV__ ? (options ? options.replayConsoleLogs !== false : true) : false, // defaults to true
62+
__DEV__ && options && options.environmentName
63+
? options.environmentName
64+
: undefined,
6165
);
6266
}
6367

packages/react-server-dom-webpack/src/ReactFlightDOMClientEdge.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export type Options = {
7272
temporaryReferences?: TemporaryReferenceSet,
7373
findSourceMapURL?: FindSourceMapURLCallback,
7474
replayConsoleLogs?: boolean,
75+
environmentName?: string,
7576
};
7677

7778
function createResponseFromOptions(options: Options) {
@@ -88,6 +89,9 @@ function createResponseFromOptions(options: Options) {
8889
? options.findSourceMapURL
8990
: undefined,
9091
__DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
92+
__DEV__ && options && options.environmentName
93+
? options.environmentName
94+
: undefined,
9195
);
9296
}
9397

packages/react-server-dom-webpack/src/ReactFlightDOMClientNode.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export type Options = {
6262
encodeFormAction?: EncodeFormActionCallback,
6363
findSourceMapURL?: FindSourceMapURLCallback,
6464
replayConsoleLogs?: boolean,
65+
environmentName?: string,
6566
};
6667

6768
function createFromNodeStream<T>(
@@ -80,6 +81,9 @@ function createFromNodeStream<T>(
8081
? options.findSourceMapURL
8182
: undefined,
8283
__DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
84+
__DEV__ && options && options.environmentName
85+
? options.environmentName
86+
: undefined,
8387
);
8488
stream.on('data', chunk => {
8589
if (typeof chunk === 'string') {

0 commit comments

Comments
 (0)