@samitouri / QOS-React-2 / commits / ff93c4448c

[Flight] Track Debug Info from Synchronously Unwrapped Promises (#33485)

Stacked on #33482. There's a flaw with getting information from the execution context of the ping. For the soft-deprecated "throw a promise" technique, this is a bit unreliable because you could in theory throw the same one multiple times. Similarly, a more fundamental flaw with that API is that it doesn't allow for tracking the information of Promises that are already synchronously able to resolve. This stops tracking the async debug info in the case of throwing a Promise and only when you render a Promise. That means some loss of data but we should just warn for throwing a Promise anyway. Instead, this also adds support for tracking `use()`d thenables and forwarding `_debugInfo` from then. This is done by extracting the info from the Promise after the fact instead of in the resolve so that it only happens once at the end after the pings are done. This also supports passing the same Promise in multiple places and tracking the debug info at each location, even if it was already instrumented with a synchronous value by the time of the second use.

Sebastian Markbåge committed Jun 11, 2025 at 12:07 UTC ff93c4448c44e8e5562a4102394ebf9f2b0ec847
11 files changed +845 -161
packages/react-client/src/__tests__/ReactFlight-test.js
+58
@@ -2991,6 +2991,64 @@ describe('ReactFlight', () => {
2991 );
2992 });
2993
2994 + // @gate !__DEV__ || enableComponentPerformanceTrack
2995 + it('preserves debug info for server-to-server through use()', async () => {
2996 + function ThirdPartyComponent() {
2997 + return 'hi';
2998 + }
2999 +
3000 + function ServerComponent({transport}) {
3001 + // This is a Server Component that receives other Server Components from a third party.
3002 + const text = ReactServer.use(ReactNoopFlightClient.read(transport));
3003 + return <div>{text.toUpperCase()}</div>;
3004 + }
3005 +
3006 + const thirdPartyTransport = ReactNoopFlightServer.render(
3007 + <ThirdPartyComponent />,
3008 + {
3009 + environmentName: 'third-party',
3010 + },
3011 + );
3012 +
3013 + const transport = ReactNoopFlightServer.render(
3014 + <ServerComponent transport={thirdPartyTransport} />,
3015 + );
3016 +
3017 + await act(async () => {
3018 + const promise = ReactNoopFlightClient.read(transport);
3019 + expect(getDebugInfo(promise)).toEqual(
3020 + __DEV__
3021 + ? [
3022 + {time: 16},
3023 + {
3024 + name: 'ServerComponent',
3025 + env: 'Server',
3026 + key: null,
3027 + stack: ' in Object.<anonymous> (at **)',
3028 + props: {
3029 + transport: expect.arrayContaining([]),
3030 + },
3031 + },
3032 + {time: 16},
3033 + {
3034 + name: 'ThirdPartyComponent',
3035 + env: 'third-party',
3036 + key: null,
3037 + stack: ' in Object.<anonymous> (at **)',
3038 + props: {},
3039 + },
3040 + {time: 16},
3041 + {time: 17},
3042 + ]
3043 + : undefined,
3044 + );
3045 + const result = await promise;
3046 + ReactNoop.render(result);
3047 + });
3048 +
3049 + expect(ReactNoop).toMatchRenderedOutput(<div>HI</div>);
3050 + });
3051 +
3052 it('preserves error stacks passed through server-to-server with source maps', async () => {
3053 async function ServerComponent({transport}) {
3054 // This is a Server Component that receives other Server Components from a third party.
packages/react-server-dom-turbopack/src/ReactFlightTurbopackReferences.js
+6
@@ -161,6 +161,9 @@ const deepProxyHandlers = {
161 // reference.
162 case 'defaultProps':
163 return undefined;
164 + // React looks for debugInfo on thenables.
165 + case '_debugInfo':
166 + return undefined;
167 // Avoid this attempting to be serialized.
168 case 'toJSON':
169 return undefined;
@@ -210,6 +213,9 @@ function getReference(target: Function, name: string | symbol): $FlowFixMe {
213 // reference.
214 case 'defaultProps':
215 return undefined;
216 + // React looks for debugInfo on thenables.
217 + case '_debugInfo':
218 + return undefined;
219 // Avoid this attempting to be serialized.
220 case 'toJSON':
221 return undefined;
packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js
+6
@@ -162,6 +162,9 @@ const deepProxyHandlers = {
162 // reference.
163 case 'defaultProps':
164 return undefined;
165 + // React looks for debugInfo on thenables.
166 + case '_debugInfo':
167 + return undefined;
168 // Avoid this attempting to be serialized.
169 case 'toJSON':
170 return undefined;
@@ -211,6 +214,9 @@ function getReference(target: Function, name: string | symbol): $FlowFixMe {
214 // reference.
215 case 'defaultProps':
216 return undefined;
217 + // React looks for debugInfo on thenables.
218 + case '_debugInfo':
219 + return undefined;
220 // Avoid this attempting to be serialized.
221 case 'toJSON':
222 return undefined;
packages/react-server/src/ReactFlightHooks.js
+6
@@ -58,6 +58,12 @@ export function getThenableStateAfterSuspending(): ThenableState {
58 return state;
59 }
60
61 +export function getTrackedThenablesAfterRendering(): null | Array<
62 + Thenable<any>,
63 +> {
64 + return thenableState;
65 +}
66 +
67 export const HooksDispatcher: Dispatcher = {
68 readContext: (unsupportedContext: any),
69
packages/react-server/src/ReactFlightServer.js
+125 -51
@@ -91,6 +91,7 @@ import {
91 initAsyncDebugInfo,
92 markAsyncSequenceRootTask,
93 getCurrentAsyncSequence,
94 + getAsyncSequenceFromPromise,
95 parseStackTrace,
96 supportsComponentStorage,
97 componentStorage,
@@ -106,6 +107,7 @@ import {
107 prepareToUseHooksForRequest,
108 prepareToUseHooksForComponent,
109 getThenableStateAfterSuspending,
110 + getTrackedThenablesAfterRendering,
111 resetHooksForRequest,
112 } from './ReactFlightHooks';
113 import {DefaultAsyncDispatcher} from './flight/ReactFlightAsyncDispatcher';
@@ -690,26 +692,14 @@ function serializeThenable(
692
693 switch (thenable.status) {
694 case 'fulfilled': {
693 - if (__DEV__) {
694 - // If this came from Flight, forward any debug info into this new row.
695 - const debugInfo: ?ReactDebugInfo = (thenable: any)._debugInfo;
696 - if (debugInfo) {
697 - forwardDebugInfo(request, newTask, debugInfo);
698 - }
699 - }
695 + forwardDebugInfoFromThenable(request, newTask, thenable, null, null);
696 // We have the resolved value, we can go ahead and schedule it for serialization.
697 newTask.model = thenable.value;
698 pingTask(request, newTask);
699 return newTask.id;
700 }
701 case 'rejected': {
706 - if (__DEV__) {
707 - // If this came from Flight, forward any debug info into this new row.
708 - const debugInfo: ?ReactDebugInfo = (thenable: any)._debugInfo;
709 - if (debugInfo) {
710 - forwardDebugInfo(request, newTask, debugInfo);
711 - }
712 - }
702 + forwardDebugInfoFromThenable(request, newTask, thenable, null, null);
703 const x = thenable.reason;
704 erroredTask(request, newTask, x);
705 return newTask.id;
@@ -758,24 +748,11 @@ function serializeThenable(
748
749 thenable.then(
750 value => {
761 - if (__DEV__) {
762 - // If this came from Flight, forward any debug info into this new row.
763 - const debugInfo: ?ReactDebugInfo = (thenable: any)._debugInfo;
764 - if (debugInfo) {
765 - forwardDebugInfo(request, newTask, debugInfo);
766 - }
767 - }
751 + forwardDebugInfoFromCurrentContext(request, newTask, thenable);
752 newTask.model = value;
753 pingTask(request, newTask);
754 },
755 reason => {
772 - if (__DEV__) {
773 - // If this came from Flight, forward any debug info into this new row.
774 - const debugInfo: ?ReactDebugInfo = (thenable: any)._debugInfo;
775 - if (debugInfo) {
776 - forwardDebugInfo(request, newTask, debugInfo);
777 - }
778 - }
756 if (newTask.status === PENDING) {
757 if (enableProfilerTimer && enableComponentPerformanceTrack) {
758 // If this is async we need to time when this task finishes.
@@ -1055,13 +1032,21 @@ function readThenable<T>(thenable: Thenable<T>): T {
1032 throw thenable;
1033 }
1034
1058 -function createLazyWrapperAroundWakeable(wakeable: Wakeable) {
1035 +function createLazyWrapperAroundWakeable(
1036 + request: Request,
1037 + task: Task,
1038 + wakeable: Wakeable,
1039 +) {
1040 // This is a temporary fork of the `use` implementation until we accept
1041 // promises everywhere.
1042 const thenable: Thenable<mixed> = (wakeable: any);
1043 switch (thenable.status) {
1063 - case 'fulfilled':
1044 + case 'fulfilled': {
1045 + forwardDebugInfoFromThenable(request, task, thenable, null, null);
1046 + return thenable.value;
1047 + }
1048 case 'rejected':
1049 + forwardDebugInfoFromThenable(request, task, thenable, null, null);
1050 break;
1051 default: {
1052 if (typeof thenable.status === 'string') {
@@ -1074,6 +1059,7 @@ function createLazyWrapperAroundWakeable(wakeable: Wakeable) {
1059 pendingThenable.status = 'pending';
1060 pendingThenable.then(
1061 fulfilledValue => {
1062 + forwardDebugInfoFromCurrentContext(request, task, thenable);
1063 if (thenable.status === 'pending') {
1064 const fulfilledThenable: FulfilledThenable<mixed> = (thenable: any);
1065 fulfilledThenable.status = 'fulfilled';
@@ -1081,6 +1067,7 @@ function createLazyWrapperAroundWakeable(wakeable: Wakeable) {
1067 }
1068 },
1069 (error: mixed) => {
1070 + forwardDebugInfoFromCurrentContext(request, task, thenable);
1071 if (thenable.status === 'pending') {
1072 const rejectedThenable: RejectedThenable<mixed> = (thenable: any);
1073 rejectedThenable.status = 'rejected';
@@ -1096,10 +1083,6 @@ function createLazyWrapperAroundWakeable(wakeable: Wakeable) {
1083 _payload: thenable,
1084 _init: readThenable,
1085 };
1099 - if (__DEV__) {
1100 - // If this came from React, transfer the debug info.
1101 - lazyType._debugInfo = (thenable: any)._debugInfo || [];
1102 - }
1086 return lazyType;
1087 }
1088
@@ -1178,12 +1161,9 @@ function processServerComponentReturnValue(
1161 }
1162 }, voidHandler);
1163 }
1181 - if (thenable.status === 'fulfilled') {
1182 - return thenable.value;
1183 - }
1164 // TODO: Once we accept Promises as children on the client, we can just return
1165 // the thenable here.
1186 - return createLazyWrapperAroundWakeable(result);
1166 + return createLazyWrapperAroundWakeable(request, task, result);
1167 }
1168
1169 if (__DEV__) {
@@ -1386,6 +1366,7 @@ function renderFunctionComponent<Props>(
1366 }
1367 }
1368 } else {
1369 + componentDebugInfo = (null: any);
1370 prepareToUseHooksForComponent(prevThenableState, null);
1371 // The secondArg is always undefined in Server Components since refs error early.
1372 const secondArg = undefined;
@@ -1408,6 +1389,34 @@ function renderFunctionComponent<Props>(
1389 throw null;
1390 }
1391
1392 + if (
1393 + __DEV__ ||
1394 + (enableProfilerTimer &&
1395 + enableComponentPerformanceTrack &&
1396 + enableAsyncDebugInfo)
1397 + ) {
1398 + // Forward any debug information for any Promises that we use():ed during the render.
1399 + // We do this at the end so that we don't keep doing this for each retry.
1400 + const trackedThenables = getTrackedThenablesAfterRendering();
1401 + if (trackedThenables !== null) {
1402 + const stacks: Array<Error> =
1403 + __DEV__ && enableAsyncDebugInfo
1404 + ? (trackedThenables: any)._stacks ||
1405 + ((trackedThenables: any)._stacks = [])
1406 + : (null: any);
1407 + for (let i = 0; i < trackedThenables.length; i++) {
1408 + const stack = __DEV__ && enableAsyncDebugInfo ? stacks[i] : null;
1409 + forwardDebugInfoFromThenable(
1410 + request,
1411 + task,
1412 + trackedThenables[i],
1413 + __DEV__ ? componentDebugInfo : null,
1414 + stack,
1415 + );
1416 + }
1417 + }
1418 + }
1419 +
1420 // Apply special cases.
1421 result = processServerComponentReturnValue(request, task, Component, result);
1422
@@ -1884,7 +1893,7 @@ function visitAsyncNode(
1893 request: Request,
1894 task: Task,
1895 node: AsyncSequence,
1887 - visited: Set<AsyncSequence>,
1896 + visited: Set<AsyncSequence | ReactDebugInfo>,
1897 cutOff: number,
1898 ): null | PromiseNode | IONode {
1899 if (visited.has(node)) {
@@ -1943,7 +1952,8 @@ function visitAsyncNode(
1952 // We need to forward after we visit awaited nodes because what ever I/O we requested that's
1953 // the thing that generated this node and its virtual children.
1954 const debugInfo = node.debugInfo;
1946 - if (debugInfo !== null) {
1955 + if (debugInfo !== null && !visited.has(debugInfo)) {
1956 + visited.add(debugInfo);
1957 forwardDebugInfo(request, task, debugInfo);
1958 }
1959 return match;
@@ -2003,8 +2013,9 @@ function visitAsyncNode(
2013 }
2014 // We need to forward after we visit awaited nodes because what ever I/O we requested that's
2015 // the thing that generated this node and its virtual children.
2006 - const debugInfo: null | ReactDebugInfo = node.debugInfo;
2007 - if (debugInfo !== null) {
2016 + const debugInfo = node.debugInfo;
2017 + if (debugInfo !== null && !visited.has(debugInfo)) {
2018 + visited.add(debugInfo);
2019 forwardDebugInfo(request, task, debugInfo);
2020 }
2021 return match;
@@ -2020,8 +2031,14 @@ function emitAsyncSequence(
2031 request: Request,
2032 task: Task,
2033 node: AsyncSequence,
2034 + alreadyForwardedDebugInfo: ?ReactDebugInfo,
2035 + owner: null | ReactComponentInfo,
2036 + stack: null | Error,
2037 ): void {
2024 - const visited: Set<AsyncSequence> = new Set();
2038 + const visited: Set<AsyncSequence | ReactDebugInfo> = new Set();
2039 + if (__DEV__ && alreadyForwardedDebugInfo) {
2040 + visited.add(alreadyForwardedDebugInfo);
2041 + }
2042 const awaitedNode = visitAsyncNode(request, task, node, visited, task.time);
2043 if (awaitedNode !== null) {
2044 // Nothing in user space (unfiltered stack) awaited this.
@@ -2032,10 +2049,21 @@ function emitAsyncSequence(
2049 const env = (0, request.environmentName)();
2050 // If we don't have any thing awaited, the time we started awaiting was internal
2051 // when we yielded after rendering. The current task time is basically that.
2035 - emitDebugChunk(request, task.id, {
2052 + const debugInfo: ReactAsyncInfo = {
2053 awaited: ((awaitedNode: any): ReactIOInfo), // This is deduped by this reference.
2054 env: env,
2038 - });
2055 + };
2056 + if (__DEV__) {
2057 + if (owner != null) {
2058 + // $FlowFixMe[cannot-write]
2059 + debugInfo.owner = owner;
2060 + }
2061 + if (stack != null) {
2062 + // $FlowFixMe[cannot-write]
2063 + debugInfo.stack = filterStackTrace(request, parseStackTrace(stack, 1));
2064 + }
2065 + }
2066 + emitDebugChunk(request, task.id, debugInfo);
2067 markOperationEndTime(request, task, awaitedNode.end);
2068 }
2069 }
@@ -2044,12 +2072,6 @@ function pingTask(request: Request, task: Task): void {
2072 if (enableProfilerTimer && enableComponentPerformanceTrack) {
2073 // If this was async we need to emit the time when it completes.
2074 task.timed = true;
2047 - if (enableAsyncDebugInfo) {
2048 - const sequence = getCurrentAsyncSequence();
2049 - if (sequence !== null) {
2050 - emitAsyncSequence(request, task, sequence);
2051 - }
2052 - }
2075 }
2076 const pingedTasks = request.pingedTasks;
2077 pingedTasks.push(task);
@@ -4316,6 +4338,58 @@ function forwardDebugInfo(
4338 }
4339 }
4340
4341 +function forwardDebugInfoFromThenable(
4342 + request: Request,
4343 + task: Task,
4344 + thenable: Thenable<any>,
4345 + owner: null | ReactComponentInfo, // DEV-only
4346 + stack: null | Error, // DEV-only
4347 +): void {
4348 + let debugInfo: ?ReactDebugInfo;
4349 + if (__DEV__) {
4350 + // If this came from Flight, forward any debug info into this new row.
4351 + debugInfo = thenable._debugInfo;
4352 + if (debugInfo) {
4353 + forwardDebugInfo(request, task, debugInfo);
4354 + }
4355 + }
4356 + if (
4357 + enableProfilerTimer &&
4358 + enableComponentPerformanceTrack &&
4359 + enableAsyncDebugInfo
4360 + ) {
4361 + const sequence = getAsyncSequenceFromPromise(thenable);
4362 + if (sequence !== null) {
4363 + emitAsyncSequence(request, task, sequence, debugInfo, owner, stack);
4364 + }
4365 + }
4366 +}
4367 +
4368 +function forwardDebugInfoFromCurrentContext(
4369 + request: Request,
4370 + task: Task,
4371 + thenable: Thenable<any>,
4372 +): void {
4373 + let debugInfo: ?ReactDebugInfo;
4374 + if (__DEV__) {
4375 + // If this came from Flight, forward any debug info into this new row.
4376 + debugInfo = thenable._debugInfo;
4377 + if (debugInfo) {
4378 + forwardDebugInfo(request, task, debugInfo);
4379 + }
4380 + }
4381 + if (
4382 + enableProfilerTimer &&
4383 + enableComponentPerformanceTrack &&
4384 + enableAsyncDebugInfo
4385 + ) {
4386 + const sequence = getCurrentAsyncSequence();
4387 + if (sequence !== null) {
4388 + emitAsyncSequence(request, task, sequence, debugInfo, null, null);
4389 + }
4390 + }
4391 +}
4392 +
4393 function emitTimingChunk(
4394 request: Request,
4395 id: number,
packages/react-server/src/ReactFlightServerConfigDebugNode.js
+30 -1
@@ -24,9 +24,12 @@ import {
24 UNRESOLVED_AWAIT_NODE,
25 } from './ReactFlightAsyncSequence';
26 import {resolveOwner} from './flight/ReactFlightCurrentOwner';
27 -import {createHook, executionAsyncId} from 'async_hooks';
27 +import {createHook, executionAsyncId, AsyncResource} from 'async_hooks';
28 import {enableAsyncDebugInfo} from 'shared/ReactFeatureFlags';
29
30 +// $FlowFixMe[method-unbinding]
31 +const getAsyncId = AsyncResource.prototype.asyncId;
32 +
33 const pendingOperations: Map<number, AsyncSequence> =
34 __DEV__ && enableAsyncDebugInfo ? new Map() : (null: any);
35
@@ -260,3 +263,29 @@ export function getCurrentAsyncSequence(): null | AsyncSequence {
263 }
264 return currentNode;
265 }
266 +
267 +export function getAsyncSequenceFromPromise(
268 + promise: any,
269 +): null | AsyncSequence {
270 + if (!__DEV__ || !enableAsyncDebugInfo) {
271 + return null;
272 + }
273 + // A Promise is conceptually an AsyncResource but doesn't have its own methods.
274 + // We use this hack to extract the internal asyncId off the Promise.
275 + let asyncId: void | number;
276 + try {
277 + asyncId = getAsyncId.call(promise);
278 + } catch (x) {
279 + // Ignore errors extracting the ID. We treat it as missing.
280 + // This could happen if our hack stops working or in the case where this is
281 + // a Proxy that throws such as our own ClientReference proxies.
282 + }
283 + if (asyncId === undefined) {
284 + return null;
285 + }
286 + const node = pendingOperations.get(asyncId);
287 + if (node === undefined) {
288 + return null;
289 + }
290 + return node;
291 +}
packages/react-server/src/ReactFlightServerConfigDebugNoop.js
+5
@@ -15,3 +15,8 @@ export function markAsyncSequenceRootTask(): void {}
15 export function getCurrentAsyncSequence(): null | AsyncSequence {
16 return null;
17 }
18 +export function getAsyncSequenceFromPromise(
19 + promise: any,
20 +): null | AsyncSequence {
21 + return null;
22 +}
packages/react-server/src/ReactFlightServerTemporaryReferences.js
+3
@@ -52,6 +52,9 @@ const proxyHandlers = {
52 // reference.
53 case 'defaultProps':
54 return undefined;
55 + // React looks for debugInfo on thenables.
56 + case '_debugInfo':
57 + return undefined;
58 // Avoid this attempting to be serialized.
59 case 'toJSON':
60 return undefined;
packages/react-server/src/ReactFlightThenable.js
+8 -1
@@ -20,9 +20,11 @@ import type {
20 RejectedThenable,
21 } from 'shared/ReactTypes';
22
23 +import {enableAsyncDebugInfo} from 'shared/ReactFeatureFlags';
24 +
25 import noop from 'shared/noop';
26
25 -export opaque type ThenableState = Array<Thenable<any>>;
27 +export type ThenableState = Array<Thenable<any>>;
28
29 // An error that is thrown (e.g. by `use`) to trigger Suspense. If we
30 // detect this is caught by userspace, we'll log a warning in development.
@@ -50,6 +52,11 @@ export function trackUsedThenable<T>(
52 const previous = thenableState[index];
53 if (previous === undefined) {
54 thenableState.push(thenable);
55 + if (__DEV__ && enableAsyncDebugInfo) {
56 + const stacks: Array<Error> =
57 + (thenableState: any)._stacks || ((thenableState: any)._stacks = []);
58 + stacks.push(new Error());
59 + }
60 } else {
61 if (previous !== thenable) {
62 // Reuse the previous thenable, and drop the new one. We can assume
packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js
+595 -107
@@ -495,6 +495,267 @@ describe('ReactFlightAsyncDebugInfo', () => {
495 }
496 });
497
498 + it('can track async information when use()d', async () => {
499 + async function getData(text) {
500 + await delay(1);
501 + return text.toUpperCase();
502 + }
503 +
504 + function Component() {
505 + const result = ReactServer.use(getData('hi'));
506 + const moreData = getData('seb');
507 + return <InnerComponent text={result} promise={moreData} />;
508 + }
509 +
510 + function InnerComponent({text, promise}) {
511 + // This async function depends on the I/O in parent components but it should not
512 + // include that I/O as part of its own meta data.
513 + return text + ', ' + ReactServer.use(promise);
514 + }
515 +
516 + const stream = ReactServerDOMServer.renderToPipeableStream(
517 + <Component />,
518 + {},
519 + {
520 + filterStackFrame,
521 + },
522 + );
523 +
524 + const readable = new Stream.PassThrough(streamOptions);
525 +
526 + const result = ReactServerDOMClient.createFromNodeStream(readable, {
527 + moduleMap: {},
528 + moduleLoading: {},
529 + });
530 + stream.pipe(readable);
531 +
532 + expect(await result).toBe('HI, SEB');
533 + if (
534 + __DEV__ &&
535 + gate(
536 + flags =>
537 + flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
538 + )
539 + ) {
540 + expect(getDebugInfo(result)).toMatchInlineSnapshot(`
541 + [
542 + {
543 + "time": 0,
544 + },
545 + {
546 + "env": "Server",
547 + "key": null,
548 + "name": "Component",
549 + "props": {},
550 + "stack": [
551 + [
552 + "Object.<anonymous>",
553 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
554 + 517,
555 + 40,
556 + 498,
557 + 49,
558 + ],
559 + ],
560 + },
561 + {
562 + "time": 0,
563 + },
564 + {
565 + "awaited": {
566 + "end": 0,
567 + "env": "Server",
568 + "name": "delay",
569 + "owner": {
570 + "env": "Server",
571 + "key": null,
572 + "name": "Component",
573 + "props": {},
574 + "stack": [
575 + [
576 + "Object.<anonymous>",
577 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
578 + 517,
579 + 40,
580 + 498,
581 + 49,
582 + ],
583 + ],
584 + },
585 + "stack": [
586 + [
587 + "delay",
588 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
589 + 133,
590 + 12,
591 + 132,
592 + 3,
593 + ],
594 + [
595 + "getData",
596 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
597 + 500,
598 + 13,
599 + 499,
600 + 5,
601 + ],
602 + [
603 + "Component",
604 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
605 + 505,
606 + 36,
607 + 504,
608 + 5,
609 + ],
610 + ],
611 + "start": 0,
612 + },
613 + "env": "Server",
614 + "owner": {
615 + "env": "Server",
616 + "key": null,
617 + "name": "Component",
618 + "props": {},
619 + "stack": [
620 + [
621 + "Object.<anonymous>",
622 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
623 + 517,
624 + 40,
625 + 498,
626 + 49,
627 + ],
628 + ],
629 + },
630 + "stack": [
631 + [
632 + "getData",
633 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
634 + 500,
635 + 13,
636 + 499,
637 + 5,
638 + ],
639 + [
640 + "Component",
641 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
642 + 505,
643 + 36,
644 + 504,
645 + 5,
646 + ],
647 + ],
648 + },
649 + {
650 + "time": 0,
651 + },
652 + {
653 + "time": 0,
654 + },
655 + {
656 + "env": "Server",
657 + "key": null,
658 + "name": "InnerComponent",
659 + "props": {},
660 + "stack": [
661 + [
662 + "Component",
663 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
664 + 507,
665 + 60,
666 + 504,
667 + 5,
668 + ],
669 + ],
670 + },
671 + {
672 + "awaited": {
673 + "end": 0,
674 + "env": "Server",
675 + "name": "delay",
676 + "owner": {
677 + "env": "Server",
678 + "key": null,
679 + "name": "Component",
680 + "props": {},
681 + "stack": [
682 + [
683 + "Object.<anonymous>",
684 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
685 + 517,
686 + 40,
687 + 498,
688 + 49,
689 + ],
690 + ],
691 + },
692 + "stack": [
693 + [
694 + "delay",
695 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
696 + 133,
697 + 12,
698 + 132,
699 + 3,
700 + ],
701 + [
702 + "getData",
703 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
704 + 500,
705 + 13,
706 + 499,
707 + 5,
708 + ],
709 + [
710 + "Component",
711 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
712 + 506,
713 + 22,
714 + 504,
715 + 5,
716 + ],
717 + ],
718 + "start": 0,
719 + },
720 + "env": "Server",
721 + "owner": {
722 + "env": "Server",
723 + "key": null,
724 + "name": "InnerComponent",
725 + "props": {},
726 + "stack": [
727 + [
728 + "Component",
729 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
730 + 507,
731 + 60,
732 + 504,
733 + 5,
734 + ],
735 + ],
736 + },
737 + "stack": [
738 + [
739 + "InnerComponent",
740 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
741 + 513,
742 + 40,
743 + 510,
744 + 5,
745 + ],
746 + ],
747 + },
748 + {
749 + "time": 0,
750 + },
751 + {
752 + "time": 0,
753 + },
754 + ]
755 + `);
756 + }
757 + });
758 +
759 it('can track the start of I/O when no native promise is used', async () => {
760 function Component() {
761 const callbacks = [];
@@ -540,9 +801,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
801 [
802 "Object.<anonymous>",
803 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
543 - 511,
804 + 772,
805 109,
545 - 498,
806 + 759,
807 67,
808 ],
809 ],
@@ -561,9 +822,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
822 [
823 "Object.<anonymous>",
824 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
564 - 511,
825 + 772,
826 109,
566 - 498,
827 + 759,
828 67,
829 ],
830 ],
@@ -572,9 +833,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
833 [
834 "Component",
835 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
575 - 501,
836 + 762,
837 7,
577 - 499,
838 + 760,
839 5,
840 ],
841 ],
@@ -634,9 +895,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
895 [
896 "Object.<anonymous>",
897 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
637 - 605,
898 + 866,
899 109,
639 - 596,
900 + 857,
901 94,
902 ],
903 ],
@@ -705,9 +966,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
966 [
967 "Object.<anonymous>",
968 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
708 - 676,
969 + 937,
970 109,
710 - 652,
971 + 913,
972 50,
973 ],
974 ],
@@ -787,9 +1048,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1048 [
1049 "Object.<anonymous>",
1050 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
790 - 758,
1051 + 1019,
1052 109,
792 - 741,
1053 + 1002,
1054 63,
1055 ],
1056 ],
@@ -814,9 +1075,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1075 [
1076 "Component",
1077 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
817 - 754,
1078 + 1015,
1079 24,
819 - 753,
1080 + 1014,
1081 5,
1082 ],
1083 ],
@@ -846,9 +1107,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1107 [
1108 "Component",
1109 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
849 - 754,
1110 + 1015,
1111 24,
851 - 753,
1112 + 1014,
1113 5,
1114 ],
1115 ],
@@ -865,17 +1126,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
1126 [
1127 "getData",
1128 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
868 - 743,
1129 + 1004,
1130 13,
870 - 742,
1131 + 1003,
1132 5,
1133 ],
1134 [
1135 "ThirdPartyComponent",
1136 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
876 - 749,
1137 + 1010,
1138 24,
878 - 748,
1139 + 1009,
1140 5,
1141 ],
1142 ],
@@ -899,9 +1160,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1160 [
1161 "Component",
1162 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
902 - 754,
1163 + 1015,
1164 24,
904 - 753,
1165 + 1014,
1166 5,
1167 ],
1168 ],
@@ -910,17 +1171,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
1171 [
1172 "getData",
1173 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
913 - 743,
1174 + 1004,
1175 13,
915 - 742,
1176 + 1003,
1177 5,
1178 ],
1179 [
1180 "ThirdPartyComponent",
1181 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
921 - 749,
1182 + 1010,
1183 24,
923 - 748,
1184 + 1009,
1185 5,
1186 ],
1187 ],
@@ -953,9 +1214,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1214 [
1215 "Component",
1216 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
956 - 754,
1217 + 1015,
1218 24,
958 - 753,
1219 + 1014,
1220 5,
1221 ],
1222 ],
@@ -972,17 +1233,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
1233 [
1234 "getData",
1235 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
975 - 744,
1236 + 1005,
1237 13,
977 - 742,
1238 + 1003,
1239 5,
1240 ],
1241 [
1242 "ThirdPartyComponent",
1243 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
983 - 749,
1244 + 1010,
1245 18,
985 - 748,
1246 + 1009,
1247 5,
1248 ],
1249 ],
@@ -1006,9 +1267,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1267 [
1268 "Component",
1269 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1009 - 754,
1270 + 1015,
1271 24,
1011 - 753,
1272 + 1014,
1273 5,
1274 ],
1275 ],
@@ -1017,17 +1278,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
1278 [
1279 "getData",
1280 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1020 - 744,
1281 + 1005,
1282 13,
1022 - 742,
1283 + 1003,
1284 5,
1285 ],
1286 [
1287 "ThirdPartyComponent",
1288 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1028 - 749,
1289 + 1010,
1290 18,
1030 - 748,
1291 + 1009,
1292 5,
1293 ],
1294 ],
@@ -1047,12 +1308,7 @@ describe('ReactFlightAsyncDebugInfo', () => {
1308 });
1309
1310 it('can track cached entries awaited in later components', async () => {
1050 - let cacheKey;
1051 - let cacheValue;
1311 const getData = cache(async function getData(text) {
1053 - if (cacheKey === text) {
1054 - return cacheValue;
1055 - }
1312 await delay(1);
1313 return text.toUpperCase();
1314 });
@@ -1105,9 +1361,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1361 [
1362 "Object.<anonymous>",
1363 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1108 - 1071,
1364 + 1327,
1365 40,
1110 - 1049,
1366 + 1310,
1367 62,
1368 ],
1369 ],
@@ -1129,9 +1385,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1385 [
1386 "Object.<anonymous>",
1387 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1132 - 1071,
1388 + 1327,
1389 40,
1134 - 1049,
1390 + 1310,
1391 62,
1392 ],
1393 ],
@@ -1148,17 +1404,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
1404 [
1405 "getData",
1406 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1151 - 1056,
1407 + 1312,
1408 13,
1153 - 1052,
1409 + 1311,
1410 25,
1411 ],
1412 [
1413 "Component",
1414 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1159 - 1066,
1415 + 1322,
1416 13,
1161 - 1065,
1417 + 1321,
1418 5,
1419 ],
1420 ],
@@ -1174,9 +1430,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1430 [
1431 "Object.<anonymous>",
1432 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1177 - 1071,
1433 + 1327,
1434 40,
1179 - 1049,
1435 + 1310,
1436 62,
1437 ],
1438 ],
@@ -1185,17 +1441,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
1441 [
1442 "getData",
1443 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1188 - 1056,
1444 + 1312,
1445 13,
1190 - 1052,
1446 + 1311,
1447 25,
1448 ],
1449 [
1450 "Component",
1451 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1196 - 1066,
1452 + 1322,
1453 13,
1198 - 1065,
1454 + 1321,
1455 5,
1456 ],
1457 ],
@@ -1215,9 +1471,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1471 [
1472 "Component",
1473 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1218 - 1067,
1474 + 1323,
1475 60,
1220 - 1065,
1476 + 1321,
1477 5,
1478 ],
1479 ],
@@ -1239,9 +1495,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1495 [
1496 "Object.<anonymous>",
1497 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1242 - 1071,
1498 + 1327,
1499 40,
1244 - 1049,
1500 + 1310,
1501 62,
1502 ],
1503 ],
@@ -1258,17 +1514,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
1514 [
1515 "getData",
1516 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1261 - 1056,
1517 + 1312,
1518 13,
1263 - 1052,
1519 + 1311,
1520 25,
1521 ],
1522 [
1523 "Component",
1524 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1269 - 1066,
1525 + 1322,
1526 13,
1271 - 1065,
1527 + 1321,
1528 5,
1529 ],
1530 ],
@@ -1284,9 +1540,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1540 [
1541 "Component",
1542 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1287 - 1067,
1543 + 1323,
1544 60,
1289 - 1065,
1545 + 1321,
1546 5,
1547 ],
1548 ],
@@ -1295,9 +1551,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1551 [
1552 "Child",
1553 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1298 - 1061,
1554 + 1317,
1555 28,
1300 - 1060,
1556 + 1316,
1557 5,
1558 ],
1559 ],
@@ -1313,6 +1569,238 @@ describe('ReactFlightAsyncDebugInfo', () => {
1569 }
1570 });
1571
1572 + it('can track cached entries used in child position', async () => {
1573 + const getData = cache(async function getData(text) {
1574 + await delay(1);
1575 + return text.toUpperCase();
1576 + });
1577 +
1578 + function Child() {
1579 + return getData('hi');
1580 + }
1581 +
1582 + function Component() {
1583 + ReactServer.use(getData('hi'));
1584 + return <Child />;
1585 + }
1586 +
1587 + const stream = ReactServerDOMServer.renderToPipeableStream(
1588 + <Component />,
1589 + {},
1590 + {
1591 + filterStackFrame,
1592 + },
1593 + );
1594 +
1595 + const readable = new Stream.PassThrough(streamOptions);
1596 +
1597 + const result = ReactServerDOMClient.createFromNodeStream(readable, {
1598 + moduleMap: {},
1599 + moduleLoading: {},
1600 + });
1601 + stream.pipe(readable);
1602 +
1603 + expect(await result).toBe('HI');
1604 + if (
1605 + __DEV__ &&
1606 + gate(
1607 + flags =>
1608 + flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
1609 + )
1610 + ) {
1611 + expect(getDebugInfo(result)).toMatchInlineSnapshot(`
1612 + [
1613 + {
1614 + "time": 0,
1615 + },
1616 + {
1617 + "env": "Server",
1618 + "key": null,
1619 + "name": "Component",
1620 + "props": {},
1621 + "stack": [
1622 + [
1623 + "Object.<anonymous>",
1624 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1625 + 1588,
1626 + 40,
1627 + 1572,
1628 + 57,
1629 + ],
1630 + ],
1631 + },
1632 + {
1633 + "time": 0,
1634 + },
1635 + {
1636 + "awaited": {
1637 + "end": 0,
1638 + "env": "Server",
1639 + "name": "delay",
1640 + "owner": {
1641 + "env": "Server",
1642 + "key": null,
1643 + "name": "Component",
1644 + "props": {},
1645 + "stack": [
1646 + [
1647 + "Object.<anonymous>",
1648 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1649 + 1588,
1650 + 40,
1651 + 1572,
1652 + 57,
1653 + ],
1654 + ],
1655 + },
1656 + "stack": [
1657 + [
1658 + "delay",
1659 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1660 + 133,
1661 + 12,
1662 + 132,
1663 + 3,
1664 + ],
1665 + [
1666 + "getData",
1667 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1668 + 1574,
1669 + 13,
1670 + 1573,
1671 + 25,
1672 + ],
1673 + [
1674 + "Component",
1675 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1676 + 1583,
1677 + 23,
1678 + 1582,
1679 + 5,
1680 + ],
1681 + ],
1682 + "start": 0,
1683 + },
1684 + "env": "Server",
1685 + "owner": {
1686 + "env": "Server",
1687 + "key": null,
1688 + "name": "Component",
1689 + "props": {},
1690 + "stack": [
1691 + [
1692 + "Object.<anonymous>",
1693 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1694 + 1588,
1695 + 40,
1696 + 1572,
1697 + 57,
1698 + ],
1699 + ],
1700 + },
1701 + "stack": [
1702 + [
1703 + "getData",
1704 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1705 + 1574,
1706 + 13,
1707 + 1573,
1708 + 25,
1709 + ],
1710 + [
1711 + "Component",
1712 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1713 + 1583,
1714 + 23,
1715 + 1582,
1716 + 5,
1717 + ],
1718 + ],
1719 + },
1720 + {
1721 + "time": 0,
1722 + },
1723 + {
1724 + "time": 0,
1725 + },
1726 + {
1727 + "env": "Server",
1728 + "key": null,
1729 + "name": "Child",
1730 + "props": {},
1731 + "stack": [
1732 + [
1733 + "Component",
1734 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1735 + 1584,
1736 + 60,
1737 + 1582,
1738 + 5,
1739 + ],
1740 + ],
1741 + },
1742 + {
1743 + "awaited": {
1744 + "end": 0,
1745 + "env": "Server",
1746 + "name": "delay",
1747 + "owner": {
1748 + "env": "Server",
1749 + "key": null,
1750 + "name": "Component",
1751 + "props": {},
1752 + "stack": [
1753 + [
1754 + "Object.<anonymous>",
1755 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1756 + 1588,
1757 + 40,
1758 + 1572,
1759 + 57,
1760 + ],
1761 + ],
1762 + },
1763 + "stack": [
1764 + [
1765 + "delay",
1766 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1767 + 133,
1768 + 12,
1769 + 132,
1770 + 3,
1771 + ],
1772 + [
1773 + "getData",
1774 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1775 + 1574,
1776 + 13,
1777 + 1573,
1778 + 25,
1779 + ],
1780 + [
1781 + "Component",
1782 + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1783 + 1583,
1784 + 23,
1785 + 1582,
1786 + 5,
1787 + ],
1788 + ],
1789 + "start": 0,
1790 + },
1791 + "env": "Server",
1792 + },
1793 + {
1794 + "time": 0,
1795 + },
1796 + {
1797 + "time": 0,
1798 + },
1799 + ]
1800 + `);
1801 + }
1802 + });
1803 +
1804 it('can track implicit returned promises that are blocked by previous data', async () => {
1805 async function delayTwice() {
1806 await delay('', 20);
@@ -1368,9 +1856,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1856 [
1857 "Object.<anonymous>",
1858 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1371 - 1334,
1859 + 1822,
1860 40,
1373 - 1316,
1861 + 1804,
1862 80,
1863 ],
1864 ],
@@ -1392,9 +1880,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1880 [
1881 "Object.<anonymous>",
1882 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1395 - 1334,
1883 + 1822,
1884 40,
1397 - 1316,
1885 + 1804,
1886 80,
1887 ],
1888 ],
@@ -1411,17 +1899,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
1899 [
1900 "delayTrice",
1901 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1414 - 1324,
1902 + 1812,
1903 13,
1416 - 1322,
1904 + 1810,
1905 5,
1906 ],
1907 [
1908 "Bar",
1909 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1422 - 1329,
1910 + 1817,
1911 13,
1424 - 1328,
1912 + 1816,
1913 5,
1914 ],
1915 ],
@@ -1437,9 +1925,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1925 [
1926 "Object.<anonymous>",
1927 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1440 - 1334,
1928 + 1822,
1929 40,
1442 - 1316,
1930 + 1804,
1931 80,
1932 ],
1933 ],
@@ -1448,17 +1936,17 @@ describe('ReactFlightAsyncDebugInfo', () => {
1936 [
1937 "delayTrice",
1938 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1451 - 1324,
1939 + 1812,
1940 13,
1453 - 1322,
1941 + 1810,
1942 5,
1943 ],
1944 [
1945 "Bar",
1946 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1459 - 1329,
1947 + 1817,
1948 13,
1461 - 1328,
1949 + 1816,
1950 5,
1951 ],
1952 ],
@@ -1480,9 +1968,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
1968 [
1969 "Object.<anonymous>",
1970 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1483 - 1334,
1971 + 1822,
1972 40,
1485 - 1316,
1973 + 1804,
1974 80,
1975 ],
1976 ],
@@ -1499,25 +1987,25 @@ describe('ReactFlightAsyncDebugInfo', () => {
1987 [
1988 "delayTwice",
1989 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1502 - 1318,
1990 + 1806,
1991 13,
1504 - 1317,
1992 + 1805,
1993 5,
1994 ],
1995 [
1996 "delayTrice",
1997 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1510 - 1323,
1998 + 1811,
1999 15,
1512 - 1322,
2000 + 1810,
2001 5,
2002 ],
2003 [
2004 "Bar",
2005 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1518 - 1329,
2006 + 1817,
2007 13,
1520 - 1328,
2008 + 1816,
2009 5,
2010 ],
2011 ],
@@ -1533,9 +2021,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
2021 [
2022 "Object.<anonymous>",
2023 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1536 - 1334,
2024 + 1822,
2025 40,
1538 - 1316,
2026 + 1804,
2027 80,
2028 ],
2029 ],
@@ -1544,25 +2032,25 @@ describe('ReactFlightAsyncDebugInfo', () => {
2032 [
2033 "delayTwice",
2034 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1547 - 1318,
2035 + 1806,
2036 13,
1549 - 1317,
2037 + 1805,
2038 5,
2039 ],
2040 [
2041 "delayTrice",
2042 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1555 - 1323,
2043 + 1811,
2044 15,
1557 - 1322,
2045 + 1810,
2046 5,
2047 ],
2048 [
2049 "Bar",
2050 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1563 - 1329,
2051 + 1817,
2052 13,
1565 - 1328,
2053 + 1816,
2054 5,
2055 ],
2056 ],
@@ -1584,9 +2072,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
2072 [
2073 "Object.<anonymous>",
2074 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1587 - 1334,
2075 + 1822,
2076 40,
1589 - 1316,
2077 + 1804,
2078 80,
2079 ],
2080 ],
@@ -1603,9 +2091,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
2091 [
2092 "delayTwice",
2093 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1606 - 1319,
2094 + 1807,
2095 13,
1608 - 1317,
2096 + 1805,
2097 5,
2098 ],
2099 ],
@@ -1621,9 +2109,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
2109 [
2110 "Object.<anonymous>",
2111 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1624 - 1334,
2112 + 1822,
2113 40,
1626 - 1316,
2114 + 1804,
2115 80,
2116 ],
2117 ],
@@ -1632,9 +2120,9 @@ describe('ReactFlightAsyncDebugInfo', () => {
2120 [
2121 "delayTwice",
2122 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1635 - 1319,
2123 + 1807,
2124 13,
1637 - 1317,
2125 + 1805,
2126 5,
2127 ],
2128 ],
scripts/flow/environment.js
+3 -1
@@ -356,7 +356,9 @@ declare module 'async_hooks' {
356 run<R>(store: T, callback: (...args: any[]) => R, ...args: any[]): R;
357 enterWith(store: T): void;
358 }
359 - declare interface AsyncResource {}
359 + declare class AsyncResource {
360 + asyncId(): number;
361 + }
362 declare function executionAsyncId(): number;
363 declare function executionAsyncResource(): AsyncResource;
364 declare function triggerAsyncId(): number;