@@ -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
260261function 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,26 +2106,43 @@ 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+
21012130function 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;
2145+ <<<<<<< HEAD
21212146 const env = componentInfo.env == null ? '' : componentInfo.env;
21222147 const ownerTask =
21232148 componentInfo.owner == null
@@ -2131,19 +2156,65 @@ function initializeFakeTask(
21312156 const callStack = buildFakeCallStack(response, stack, env, createTaskFn);
21322157
21332158 let componentTask;
2159+ =======
2160+ const env: string =
2161+ componentInfo.env == null
2162+ ? response._rootEnvironmentName
2163+ : componentInfo.env;
2164+ if (env !== childEnvironmentName) {
2165+ // This is the boundary between two environments so we'll annotate the task name.
2166+ // That is unusual so we don't cache it.
2167+ const ownerTask =
2168+ componentInfo.owner == null
2169+ ? null
2170+ : initializeFakeTask(response, componentInfo.owner, env);
2171+ return buildFakeTask(
2172+ response,
2173+ ownerTask,
2174+ stack,
2175+ '"use ' + childEnvironmentName.toLowerCase() + '"',
2176+ env,
2177+ );
2178+ } else {
2179+ const cachedEntry = componentInfo.debugTask;
2180+ if (cachedEntry !== undefined) {
2181+ return cachedEntry;
2182+ }
2183+ const ownerTask =
2184+ componentInfo.owner == null
2185+ ? null
2186+ : initializeFakeTask(response, componentInfo.owner, env);
2187+ // $FlowFixMe[cannot-write]: We consider this part of initialization.
2188+ return (componentInfo.debugTask = buildFakeTask(
2189+ response,
2190+ ownerTask,
2191+ stack,
2192+ getServerComponentTaskName(componentInfo),
2193+ env,
2194+ ));
2195+ }
2196+ }
2197+
2198+ function buildFakeTask(
2199+ response: Response,
2200+ ownerTask: null | ConsoleTask,
2201+ stack: ReactStackTrace,
2202+ taskName: string,
2203+ env: string,
2204+ ): ConsoleTask {
2205+ const createTaskFn = (console: any).createTask.bind(console, taskName);
2206+ const callStack = buildFakeCallStack(response, stack, createTaskFn);
2207+ >>>>>>> abb7ae765f (Configure the requested environment and annotate tasks at boundary between environments)
21342208 if (ownerTask === null) {
2135- const rootTask = response . _debugRootTask ;
2209+ const rootTask = getRootTask( response, env) ;
21362210 if (rootTask != null) {
2137- componentTask = rootTask . run ( callStack ) ;
2211+ return rootTask.run(callStack);
21382212 } else {
2139- componentTask = callStack ( ) ;
2213+ return callStack();
21402214 }
21412215 } else {
2142- componentTask = ownerTask . run ( callStack ) ;
2216+ return ownerTask.run(callStack);
21432217 }
2144- // $FlowFixMe[cannot-write]: We consider this part of initialization.
2145- componentInfo.debugTask = componentTask;
2146- return componentTask;
21472218}
21482219
21492220const createFakeJSXCallStack = {
@@ -2216,7 +2287,9 @@ function resolveDebugInfo(
22162287 // We eagerly initialize the fake task because this resolving happens outside any
22172288 // render phase so we're not inside a user space stack at this point. If we waited
22182289 // to initialize it when we need it, we might be inside user code.
2219- initializeFakeTask ( response , debugInfo ) ;
2290+ const env =
2291+ debugInfo.env === undefined ? response._rootEnvironmentName : debugInfo.env;
2292+ initializeFakeTask(response, debugInfo, env);
22202293 initializeFakeStack(response, debugInfo);
22212294
22222295 const chunk = getChunk(response, id);
@@ -2266,7 +2339,7 @@ function resolveConsoleEntry(
22662339 printToConsole.bind(null, methodName, args, env),
22672340 );
22682341 if (owner != null) {
2269- const task = initializeFakeTask ( response , owner ) ;
2342+ const task = initializeFakeTask(response, owner, env );
22702343 initializeFakeStack(response, owner);
22712344 if (task !== null) {
22722345 task.run(callStack);
@@ -2275,7 +2348,7 @@ function resolveConsoleEntry(
22752348 // TODO: Set the current owner so that captureOwnerStack() adds the component
22762349 // stack during the replay - if needed.
22772350 }
2278- const rootTask = response . _debugRootTask ;
2351+ const rootTask = getRootTask( response, env) ;
22792352 if (rootTask != null) {
22802353 rootTask.run(callStack);
22812354 return;
0 commit comments