Repository: facebook/react
Pull request: [Flight Server] Run Server Components in console.createTask when available

Same as #30142 but for Flight Server.

This is rarely used but it does allow seeing component stacks when inspecting the Node.js server running Flight using `--inspect` and the Chrome DevTools.

<img width="595" alt="Screenshot 2024-06-29 at 1 08 47 PM" src="https://github.com/facebook/react/assets/63648/7f643e1e-a251-4e4d-b015-22a22a47031d">


Changed files:
filename: fixtures/flight/package.json
patch: @@ -71,7 +71,7 @@
     "prebuild": "cp -r ../../build/oss-experimental/* ./node_modules/",
     "dev": "concurrently \"npm run dev:region\" \"npm run dev:global\"",
     "dev:global": "NODE_ENV=development BUILD_PATH=dist node --experimental-loader ./loader/global.js server/global",
-    "dev:region": "NODE_ENV=development BUILD_PATH=dist nodemon --watch src --watch dist -- --enable-source-maps --experimental-loader ./loader/region.js --conditions=react-server server/region",
+    "dev:region": "NODE_ENV=development BUILD_PATH=dist nodemon --watch src --watch dist -- --enable-source-maps --experimental-loader ./loader/region.js --conditions=react-server --inspect server/region",
     "start": "node scripts/build.js && concurrently \"npm run start:region\" \"npm run start:global\"",
     "start:global": "NODE_ENV=production node --experimental-loader ./loader/global.js server/global",
     "start:region": "NODE_ENV=production node --experimental-loader ./loader/region.js --conditions=react-server server/region",

filename: packages/react-server/src/ReactFlightServer.js
patch: @@ -168,7 +168,7 @@ function getStack(error: Error): string {
 
 function initCallComponentFrame(): string {
   // Extract the stack frame of the callComponentInDEV function.
-  const error = callComponentInDEV(Error, 'react-stack-top-frame', {});
+  const error = callComponentInDEV(Error, 'react-stack-top-frame', {}, null);
   const stack = getStack(error);
   const startIdx = stack.startsWith('Error: react-stack-top-frame\n') ? 29 : 0;
   const endIdx = stack.indexOf('\n', startIdx);
@@ -991,20 +991,36 @@ function callComponentInDEV<Props, R>(
   Component: (p: Props, arg: void) => R,
   props: Props,
   componentDebugInfo: ReactComponentInfo,
+  debugTask: null | ConsoleTask,
 ): R {
   // The secondArg is always undefined in Server Components since refs error early.
   const secondArg = undefined;
   setCurrentOwner(componentDebugInfo);
   try {
     if (supportsComponentStorage) {
       // Run the component in an Async Context that tracks the current owner.
+      if (enableOwnerStacks && debugTask) {
+        return debugTask.run(
+          // $FlowFixMe[method-unbinding]
+          componentStorage.run.bind(
+            componentStorage,
+            componentDebugInfo,
+            Component,
+            props,
+            secondArg,
+          ),
+        );
+      }
       return componentStorage.run(
         componentDebugInfo,
         Component,
         props,
         secondArg,
       );
     } else {
+      if (enableOwnerStacks && debugTask) {
+        return debugTask.run(Component.bind(null, props, secondArg));
+      }
       return Component(props, secondArg);
     }
   } finally {
@@ -1028,6 +1044,7 @@ function renderFunctionComponent<Props>(
   props: Props,
   owner: null | ReactComponentInfo, // DEV-only
   stack: null | string, // DEV-only
+  debugTask: null | ConsoleTask, // DEV-only
   validated: number, // DEV-only
 ): ReactJSONValue {
   // Reset the task's thenable state before continuing, so that if a later
@@ -1075,11 +1092,22 @@ function renderFunctionComponent<Props>(
       task.environmentName = componentEnv;
 
       if (enableOwnerStacks) {
-        warnForMissingKey(request, key, validated, componentDebugInfo);
+        warnForMissingKey(
+          request,
+          key,
+          validated,
+          componentDebugInfo,
+          debugTask,
+        );
       }
     }
     prepareToUseHooksForComponent(prevThenableState, componentDebugInfo);
-    result = callComponentInDEV(Component, props, componentDebugInfo);
+    result = callComponentInDEV(
+      Component,
+      props,
+      componentDebugInfo,
+      debugTask,
+    );
   } else {
     prepareToUseHooksForComponent(prevThenableState, null);
     // The secondArg is always undefined in Server Components since refs error early.
@@ -1235,6 +1263,7 @@ function warnForMissingKey(
   key: null | string,
   validated: number,
   componentDebugInfo: ReactComponentInfo,
+  debugTask: null | ConsoleTask,
 ): void {
   if (__DEV__) {
     if (validated !== 2) {
@@ -1267,6 +1296,7 @@ function warnForMissingKey(
       },
       null,
       componentDebugInfo,
+      debugTask,
     );
   }
 }
@@ -1482,6 +1512,7 @@ function renderElement(
   props: any,
   owner: null | ReactComponentInfo, // DEV only
   stack: null | string, // DEV only
+  debugTask: null | ConsoleTask, // DEV only
   validated: number, // DEV only
 ): ReactJSONValue {
   if (ref !== null && ref !== undefined) {
@@ -1514,6 +1545,7 @@ function renderElement(
       props,
       owner,
       stack,
+      debugTask,
       validated,
     );
   } else if (type === REACT_FRAGMENT_TYPE && key === null) {
@@ -1562,6 +1594,7 @@ function renderElement(
           props,
           owner,
           stack,
+          debugTask,
           validated,
         );
       }
@@ -1574,6 +1607,7 @@ function renderElement(
           props,
           owner,
           stack,
+          debugTask,
           validated,
         );
       }
@@ -1587,6 +1621,7 @@ function renderElement(
           props,
           owner,
           stack,
+          debugTask,
           validated,
         );
       }
@@ -2190,6 +2225,7 @@ function renderModelDestructive(
               ? element._debugStack
               : filterDebugStack(element._debugStack)
             : null,
+          __DEV__ && enableOwnerStacks ? element._debugTask : null,
           __DEV__ && enableOwnerStacks ? element._store.validated : 0,
         );
         if (