73
74
import getComponentNameFromType from 'shared/getComponentNameFromType';
75
76
+import {getOwnerStackByComponentInfoInDev} from 'shared/ReactComponentInfoStack';
77
+
78
import isArray from 'shared/isArray';
79
80
+import * as React from 'react';
81
+
82
+// TODO: This is an unfortunate hack. We shouldn't feature detect the internals
83
+// like this. It's just that for now we support the same build of the Flight
84
+// client both in the RSC environment, in the SSR environments as well as the
85
+// browser client. We should probably have a separate RSC build. This is DEV
86
+// only though.
87
+const ReactSharedInternals =
88
+ React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE ||
89
+ React.__SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
90
+
91
export type {CallServerCallback, EncodeFormActionCallback};
92
93
interface FlightStreamController {
2309
chunkDebugInfo.push(debugInfo);
2310
}
2311
2312
+let currentOwnerInDEV: null | ReactComponentInfo = null;
2313
+function getCurrentStackInDEV(): string {
2314
+ if (__DEV__) {
2315
+ if (enableOwnerStacks) {
2316
+ const owner: null | ReactComponentInfo = currentOwnerInDEV;
2317
+ if (owner === null) {
2318
+ return '';
2319
+ }
2320
+ return getOwnerStackByComponentInfoInDev(owner);
2321
+ }
2322
+ // We don't have Parent Stacks in Flight.
2323
+ return '';
2324
+ }
2325
+ return '';
2326
+}
2327
+
2328
function resolveConsoleEntry(
2329
response: Response,
2330
value: UninitializedModel,
2353
const owner = payload[2];
2354
const env = payload[3];
2355
const args = payload.slice(4);
2327
- if (!enableOwnerStacks) {
2328
- // Printing with stack isn't really limited to owner stacks but
2329
- // we gate it behind the same flag for now while iterating.
2330
- bindToConsole(methodName, args, env)();
2331
- return;
2332
- }
2333
- const callStack = buildFakeCallStack(
2334
- response,
2335
- stackTrace,
2336
- env,
2337
- bindToConsole(methodName, args, env),
2338
- );
2339
- if (owner != null) {
2340
- const task = initializeFakeTask(response, owner, env);
2341
- initializeFakeStack(response, owner);
2342
- if (task !== null) {
2343
- task.run(callStack);
2356
+
2357
+ // There really shouldn't be anything else on the stack atm.
2358
+ const prevStack = ReactSharedInternals.getCurrentStack;
2359
+ ReactSharedInternals.getCurrentStack = getCurrentStackInDEV;
2360
+ currentOwnerInDEV = owner;
2361
+
2362
+ try {
2363
+ if (!enableOwnerStacks) {
2364
+ // Printing with stack isn't really limited to owner stacks but
2365
+ // we gate it behind the same flag for now while iterating.
2366
+ bindToConsole(methodName, args, env)();
2367
return;
2368
}
2346
- // TODO: Set the current owner so that captureOwnerStack() adds the component
2347
- // stack during the replay - if needed.
2348
- }
2349
- const rootTask = getRootTask(response, env);
2350
- if (rootTask != null) {
2351
- rootTask.run(callStack);
2352
- return;
2369
+ const callStack = buildFakeCallStack(
2370
+ response,
2371
+ stackTrace,
2372
+ env,
2373
+ bindToConsole(methodName, args, env),
2374
+ );
2375
+ if (owner != null) {
2376
+ const task = initializeFakeTask(response, owner, env);
2377
+ initializeFakeStack(response, owner);
2378
+ if (task !== null) {
2379
+ task.run(callStack);
2380
+ return;
2381
+ }
2382
+ // TODO: Set the current owner so that captureOwnerStack() adds the component
2383
+ // stack during the replay - if needed.
2384
+ }
2385
+ const rootTask = getRootTask(response, env);
2386
+ if (rootTask != null) {
2387
+ rootTask.run(callStack);
2388
+ return;
2389
+ }
2390
+ callStack();
2391
+ } finally {
2392
+ ReactSharedInternals.getCurrentStack = prevStack;
2393
}
2354
- callStack();
2394
}
2395
2396
function mergeBuffer(