main
js 4,163 lines 108 KB
Raw
1 /**
2 * @jest-environment node
3 */
4 'use strict';
5
6 import {patchSetImmediate} from '../../../../scripts/jest/patchSetImmediate';
7
8 import crypto from 'crypto';
9 import fs from 'fs/promises';
10 import path from 'path';
11
12 let React;
13 let ReactServer;
14 let cache;
15 let ReactServerDOMServer;
16 let ReactServerDOMClient;
17 let Stream;
18 let observer;
19 let getDebugInfo;
20
21 const streamOptions = {
22 objectMode: true,
23 };
24
25 function filterStackFrame(filename, functionName) {
26 return (
27 !filename.startsWith('node:') &&
28 !filename.includes('node_modules') &&
29 // Filter out our own internal source code since it'll typically be in node_modules
30 (!filename.includes('/packages/') || filename.includes('/__tests__/')) &&
31 !filename.includes('/build/') &&
32 !functionName.includes('internal_')
33 );
34 }
35
36 describe('ReactFlightAsyncDebugInfo', () => {
37 beforeEach(() => {
38 jest.resetModules();
39 jest.useRealTimers();
40 patchSetImmediate();
41 global.console = require('console');
42
43 jest.mock('react', () => require('react/react.react-server'));
44 jest.mock('react-server-dom-webpack/server', () =>
45 jest.requireActual('react-server-dom-webpack/server.node'),
46 );
47 ReactServer = require('react');
48 ReactServerDOMServer = require('react-server-dom-webpack/server');
49 cache = ReactServer.cache;
50
51 jest.resetModules();
52 jest.useRealTimers();
53 patchSetImmediate();
54
55 __unmockReact();
56 jest.unmock('react-server-dom-webpack/server');
57 jest.mock('react-server-dom-webpack/client', () =>
58 jest.requireActual('react-server-dom-webpack/client.node'),
59 );
60
61 React = require('react');
62 ReactServerDOMClient = require('react-server-dom-webpack/client');
63 Stream = require('stream');
64
65 getDebugInfo = require('internal-test-utils').getDebugInfo.bind(null, {
66 ignoreProps: true,
67 useFixedTime: true,
68 });
69 });
70
71 afterEach(() => {
72 observer?.disconnect();
73 observer = undefined;
74 });
75
76 function finishLoadingStream(readable) {
77 return new Promise(resolve => {
78 if (readable.readableEnded) {
79 resolve();
80 } else {
81 readable.on('end', () => resolve());
82 }
83 });
84 }
85
86 function delay(timeout) {
87 return new Promise(resolve => {
88 setTimeout(resolve, timeout);
89 });
90 }
91
92 function fetchThirdParty(Component) {
93 const stream = ReactServerDOMServer.renderToPipeableStream(
94 <Component />,
95 {},
96 {
97 environmentName: 'third-party',
98 },
99 );
100 const readable = new Stream.PassThrough(streamOptions);
101 const result = ReactServerDOMClient.createFromNodeStream(readable, {
102 moduleMap: {},
103 moduleLoading: {},
104 });
105 stream.pipe(readable);
106 return result;
107 }
108
109 it('can track async information when awaited', async () => {
110 async function getData(text) {
111 await delay(1);
112 const promise = delay(2);
113 promise.displayName = 'hello';
114 await Promise.all([promise]);
115 return text.toUpperCase();
116 }
117
118 async function Component() {
119 const result = await getData('hi');
120 const moreData = getData('seb');
121 return <InnerComponent text={result} promise={moreData} />;
122 }
123
124 async function InnerComponent({text, promise}) {
125 // This async function depends on the I/O in parent components but it should not
126 // include that I/O as part of its own meta data.
127 return text + ', ' + (await promise);
128 }
129
130 const stream = ReactServerDOMServer.renderToPipeableStream(<Component />);
131
132 const readable = new Stream.PassThrough(streamOptions);
133
134 const result = ReactServerDOMClient.createFromNodeStream(readable, {
135 moduleMap: {},
136 moduleLoading: {},
137 });
138 stream.pipe(readable);
139
140 expect(await result).toBe('HI, SEB');
141
142 await finishLoadingStream(readable);
143 if (
144 __DEV__ &&
145 gate(
146 flags =>
147 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
148 )
149 ) {
150 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
151 [
152 {
153 "time": 0,
154 },
155 {
156 "env": "Server",
157 "key": null,
158 "name": "Component",
159 "props": {},
160 "stack": [
161 [
162 "Object.<anonymous>",
163 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
164 130,
165 109,
166 109,
167 50,
168 ],
169 ],
170 },
171 {
172 "time": 0,
173 },
174 {
175 "awaited": {
176 "end": 0,
177 "env": "Server",
178 "name": "delay",
179 "owner": {
180 "env": "Server",
181 "key": null,
182 "name": "Component",
183 "props": {},
184 "stack": [
185 [
186 "Object.<anonymous>",
187 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
188 130,
189 109,
190 109,
191 50,
192 ],
193 ],
194 },
195 "stack": [
196 [
197 "delay",
198 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
199 87,
200 12,
201 86,
202 3,
203 ],
204 [
205 "getData",
206 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
207 111,
208 13,
209 110,
210 5,
211 ],
212 [
213 "Component",
214 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
215 119,
216 26,
217 118,
218 5,
219 ],
220 ],
221 "start": 0,
222 "value": {
223 "value": undefined,
224 },
225 },
226 "env": "Server",
227 "owner": {
228 "env": "Server",
229 "key": null,
230 "name": "Component",
231 "props": {},
232 "stack": [
233 [
234 "Object.<anonymous>",
235 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
236 130,
237 109,
238 109,
239 50,
240 ],
241 ],
242 },
243 "stack": [
244 [
245 "getData",
246 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
247 111,
248 13,
249 110,
250 5,
251 ],
252 [
253 "Component",
254 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
255 119,
256 26,
257 118,
258 5,
259 ],
260 ],
261 },
262 {
263 "time": 0,
264 },
265 {
266 "time": 0,
267 },
268 {
269 "awaited": {
270 "end": 0,
271 "env": "Server",
272 "name": "hello",
273 "owner": {
274 "env": "Server",
275 "key": null,
276 "name": "Component",
277 "props": {},
278 "stack": [
279 [
280 "Object.<anonymous>",
281 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
282 130,
283 109,
284 109,
285 50,
286 ],
287 ],
288 },
289 "stack": [
290 [
291 "delay",
292 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
293 87,
294 12,
295 86,
296 3,
297 ],
298 [
299 "getData",
300 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
301 112,
302 21,
303 110,
304 5,
305 ],
306 [
307 "Component",
308 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
309 119,
310 20,
311 118,
312 5,
313 ],
314 ],
315 "start": 0,
316 "value": {
317 "value": undefined,
318 },
319 },
320 "env": "Server",
321 "owner": {
322 "env": "Server",
323 "key": null,
324 "name": "Component",
325 "props": {},
326 "stack": [
327 [
328 "Object.<anonymous>",
329 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
330 130,
331 109,
332 109,
333 50,
334 ],
335 ],
336 },
337 "stack": [
338 [
339 "getData",
340 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
341 114,
342 21,
343 110,
344 5,
345 ],
346 [
347 "Component",
348 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
349 119,
350 20,
351 118,
352 5,
353 ],
354 ],
355 },
356 {
357 "time": 0,
358 },
359 {
360 "time": 0,
361 },
362 {
363 "env": "Server",
364 "key": null,
365 "name": "InnerComponent",
366 "props": {},
367 "stack": [
368 [
369 "Component",
370 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
371 121,
372 60,
373 118,
374 5,
375 ],
376 ],
377 },
378 {
379 "time": 0,
380 },
381 {
382 "awaited": {
383 "end": 0,
384 "env": "Server",
385 "name": "hello",
386 "owner": {
387 "env": "Server",
388 "key": null,
389 "name": "Component",
390 "props": {},
391 "stack": [
392 [
393 "Object.<anonymous>",
394 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
395 130,
396 109,
397 109,
398 50,
399 ],
400 ],
401 },
402 "stack": [
403 [
404 "delay",
405 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
406 87,
407 12,
408 86,
409 3,
410 ],
411 [
412 "getData",
413 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
414 112,
415 21,
416 110,
417 5,
418 ],
419 ],
420 "start": 0,
421 "value": {
422 "value": undefined,
423 },
424 },
425 "env": "Server",
426 "owner": {
427 "env": "Server",
428 "key": null,
429 "name": "InnerComponent",
430 "props": {},
431 "stack": [
432 [
433 "Component",
434 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
435 121,
436 60,
437 118,
438 5,
439 ],
440 ],
441 },
442 "stack": [
443 [
444 "InnerComponent",
445 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
446 127,
447 35,
448 124,
449 5,
450 ],
451 ],
452 },
453 {
454 "time": 0,
455 },
456 {
457 "time": 0,
458 },
459 {
460 "awaited": {
461 "byteSize": 0,
462 "end": 0,
463 "name": "rsc stream",
464 "owner": null,
465 "start": 0,
466 "value": {
467 "value": "stream",
468 },
469 },
470 },
471 ]
472 `);
473 }
474 });
475
476 it('adds a description to I/O', async () => {
477 async function getData(url) {
478 // just wait a macrotask for this call to get picked up
479 await new Promise(resolve => {
480 setTimeout(() => {
481 const fakeResponse = {url};
482 resolve(fakeResponse);
483 }, 1);
484 });
485 }
486
487 async function Component() {
488 await getData('http://github.com/facebook/react/pulls');
489 await getData('http://github.com/facebook/react/pulls/');
490 await getData(
491 'https://this-is-a-very-long-domain-name-what-happens.app/test',
492 );
493 await getData(
494 'https://github.com/facebook/react/commit/75897c2dcd1dd3a6ca46284dd37e13d22b4b16b4',
495 );
496 await getData('/this-is-a-very-long-directory-name-what-happens/');
497 await getData('/this-is-not');
498 return 'Hi, Sebbie';
499 }
500
501 const stream = ReactServerDOMServer.renderToPipeableStream(<Component />);
502
503 const readable = new Stream.PassThrough(streamOptions);
504
505 const result = ReactServerDOMClient.createFromNodeStream(
506 readable,
507 {
508 moduleMap: {},
509 moduleLoading: {},
510 },
511 {replayConsoleLogs: true},
512 );
513 stream.pipe(readable);
514
515 expect(await result).toBe('Hi, Sebbie');
516
517 if (
518 __DEV__ &&
519 gate(
520 flags =>
521 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
522 )
523 ) {
524 let gotEntries;
525 const hasEntries = new Promise(resolve => {
526 gotEntries = resolve;
527 });
528 const entries = [];
529 observer = new PerformanceObserver(list => {
530 // eslint-disable-next-line no-for-of-loops/no-for-of-loops
531 for (const entry of list.getEntries()) {
532 const {name} = entry;
533 entries.push({name});
534 }
535 gotEntries();
536 }).observe({type: 'measure'});
537
538 await hasEntries;
539 await finishLoadingStream(readable);
540
541 expect(entries).toMatchInlineSnapshot(`
542 [
543 {
544 "name": "\u200bComponent",
545 },
546 {
547 "name": "await getData (…/pulls)",
548 },
549 {
550 "name": "await getData (…/pulls)",
551 },
552 {
553 "name": "await getData (…/test)",
554 },
555 {
556 "name": "await getData (…/75897c2dcd…13d22b4b16b4)",
557 },
558 {
559 "name": "await getData (/this-is-a-…what-happens)",
560 },
561 {
562 "name": "await getData (/this-is-not)",
563 },
564 ]
565 `);
566 } else {
567 await finishLoadingStream(readable);
568 }
569 });
570
571 it('can track async information when use()d', async () => {
572 async function getData(text) {
573 await delay(1);
574 return text.toUpperCase();
575 }
576
577 function Component() {
578 const result = ReactServer.use(getData('hi'));
579 const moreData = getData('seb');
580 return <InnerComponent text={result} promise={moreData} />;
581 }
582
583 function InnerComponent({text, promise}) {
584 // This async function depends on the I/O in parent components but it should not
585 // include that I/O as part of its own meta data.
586 return text + ', ' + ReactServer.use(promise);
587 }
588
589 const stream = ReactServerDOMServer.renderToPipeableStream(
590 <Component />,
591 {},
592 {
593 filterStackFrame,
594 },
595 );
596
597 const readable = new Stream.PassThrough(streamOptions);
598
599 const result = ReactServerDOMClient.createFromNodeStream(readable, {
600 moduleMap: {},
601 moduleLoading: {},
602 });
603 stream.pipe(readable);
604
605 expect(await result).toBe('HI, SEB');
606
607 await finishLoadingStream(readable);
608 if (
609 __DEV__ &&
610 gate(
611 flags =>
612 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
613 )
614 ) {
615 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
616 [
617 {
618 "time": 0,
619 },
620 {
621 "env": "Server",
622 "key": null,
623 "name": "Component",
624 "props": {},
625 "stack": [
626 [
627 "Object.<anonymous>",
628 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
629 590,
630 40,
631 571,
632 49,
633 ],
634 [
635 "new Promise",
636 "",
637 0,
638 0,
639 0,
640 0,
641 ],
642 ],
643 },
644 {
645 "time": 0,
646 },
647 {
648 "awaited": {
649 "end": 0,
650 "env": "Server",
651 "name": "delay",
652 "owner": {
653 "env": "Server",
654 "key": null,
655 "name": "Component",
656 "props": {},
657 "stack": [
658 [
659 "Object.<anonymous>",
660 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
661 590,
662 40,
663 571,
664 49,
665 ],
666 [
667 "new Promise",
668 "",
669 0,
670 0,
671 0,
672 0,
673 ],
674 ],
675 },
676 "stack": [
677 [
678 "delay",
679 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
680 87,
681 12,
682 86,
683 3,
684 ],
685 [
686 "getData",
687 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
688 573,
689 13,
690 572,
691 5,
692 ],
693 [
694 "Component",
695 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
696 578,
697 36,
698 577,
699 5,
700 ],
701 ],
702 "start": 0,
703 "value": {
704 "value": undefined,
705 },
706 },
707 "env": "Server",
708 "owner": {
709 "env": "Server",
710 "key": null,
711 "name": "Component",
712 "props": {},
713 "stack": [
714 [
715 "Object.<anonymous>",
716 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
717 590,
718 40,
719 571,
720 49,
721 ],
722 [
723 "new Promise",
724 "",
725 0,
726 0,
727 0,
728 0,
729 ],
730 ],
731 },
732 "stack": [
733 [
734 "getData",
735 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
736 573,
737 13,
738 572,
739 5,
740 ],
741 [
742 "Component",
743 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
744 578,
745 36,
746 577,
747 5,
748 ],
749 ],
750 },
751 {
752 "time": 0,
753 },
754 {
755 "time": 0,
756 },
757 {
758 "env": "Server",
759 "key": null,
760 "name": "InnerComponent",
761 "props": {},
762 "stack": [
763 [
764 "Component",
765 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
766 580,
767 60,
768 577,
769 5,
770 ],
771 ],
772 },
773 {
774 "awaited": {
775 "end": 0,
776 "env": "Server",
777 "name": "delay",
778 "owner": {
779 "env": "Server",
780 "key": null,
781 "name": "Component",
782 "props": {},
783 "stack": [
784 [
785 "Object.<anonymous>",
786 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
787 590,
788 40,
789 571,
790 49,
791 ],
792 [
793 "new Promise",
794 "",
795 0,
796 0,
797 0,
798 0,
799 ],
800 ],
801 },
802 "stack": [
803 [
804 "delay",
805 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
806 87,
807 12,
808 86,
809 3,
810 ],
811 [
812 "getData",
813 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
814 573,
815 13,
816 572,
817 5,
818 ],
819 [
820 "Component",
821 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
822 579,
823 22,
824 577,
825 5,
826 ],
827 ],
828 "start": 0,
829 "value": {
830 "value": undefined,
831 },
832 },
833 "env": "Server",
834 "owner": {
835 "env": "Server",
836 "key": null,
837 "name": "InnerComponent",
838 "props": {},
839 "stack": [
840 [
841 "Component",
842 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
843 580,
844 60,
845 577,
846 5,
847 ],
848 ],
849 },
850 "stack": [
851 [
852 "InnerComponent",
853 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
854 586,
855 40,
856 583,
857 5,
858 ],
859 ],
860 },
861 {
862 "time": 0,
863 },
864 {
865 "time": 0,
866 },
867 {
868 "awaited": {
869 "byteSize": 0,
870 "end": 0,
871 "name": "rsc stream",
872 "owner": null,
873 "start": 0,
874 "value": {
875 "value": "stream",
876 },
877 },
878 },
879 ]
880 `);
881 }
882 });
883
884 it('cannot currently track the start of I/O when no native promise is used', async () => {
885 function Component() {
886 const callbacks = [];
887 setTimeout(function timer() {
888 callbacks.forEach(callback => callback('hi'));
889 }, 5);
890 return {
891 then(callback) {
892 callbacks.push(callback);
893 },
894 };
895 }
896
897 const stream = ReactServerDOMServer.renderToPipeableStream(<Component />);
898
899 const readable = new Stream.PassThrough(streamOptions);
900
901 const result = ReactServerDOMClient.createFromNodeStream(readable, {
902 moduleMap: {},
903 moduleLoading: {},
904 });
905 stream.pipe(readable);
906
907 expect(await result).toBe('hi');
908
909 await finishLoadingStream(readable);
910 if (
911 __DEV__ &&
912 gate(
913 flags =>
914 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
915 )
916 ) {
917 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
918 [
919 {
920 "time": 0,
921 },
922 {
923 "env": "Server",
924 "key": null,
925 "name": "Component",
926 "props": {},
927 "stack": [
928 [
929 "Object.<anonymous>",
930 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
931 897,
932 109,
933 884,
934 80,
935 ],
936 ],
937 },
938 {
939 "awaited": {
940 "end": 0,
941 "env": "Server",
942 "name": "",
943 "owner": {
944 "env": "Server",
945 "key": null,
946 "name": "Component",
947 "props": {},
948 "stack": [
949 [
950 "Object.<anonymous>",
951 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
952 897,
953 109,
954 884,
955 80,
956 ],
957 ],
958 },
959 "start": 0,
960 },
961 "env": "Server",
962 "owner": {
963 "env": "Server",
964 "key": null,
965 "name": "Component",
966 "props": {},
967 "stack": [
968 [
969 "Object.<anonymous>",
970 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
971 897,
972 109,
973 884,
974 80,
975 ],
976 ],
977 },
978 },
979 {
980 "time": 0,
981 },
982 {
983 "time": 0,
984 },
985 {
986 "awaited": {
987 "byteSize": 0,
988 "end": 0,
989 "name": "rsc stream",
990 "owner": null,
991 "start": 0,
992 "value": {
993 "value": "stream",
994 },
995 },
996 },
997 ]
998 `);
999 }
1000 });
1001
1002 it('can ingores the start of I/O when immediately resolved non-native promise is awaited', async () => {
1003 async function Component() {
1004 return await {
1005 then(callback) {
1006 callback('hi');
1007 },
1008 };
1009 }
1010
1011 const stream = ReactServerDOMServer.renderToPipeableStream(<Component />);
1012
1013 const readable = new Stream.PassThrough(streamOptions);
1014
1015 const result = ReactServerDOMClient.createFromNodeStream(readable, {
1016 moduleMap: {},
1017 moduleLoading: {},
1018 });
1019 stream.pipe(readable);
1020
1021 expect(await result).toBe('hi');
1022
1023 await finishLoadingStream(readable);
1024 if (
1025 __DEV__ &&
1026 gate(
1027 flags =>
1028 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
1029 )
1030 ) {
1031 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
1032 [
1033 {
1034 "time": 0,
1035 },
1036 {
1037 "env": "Server",
1038 "key": null,
1039 "name": "Component",
1040 "props": {},
1041 "stack": [
1042 [
1043 "Object.<anonymous>",
1044 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1045 1011,
1046 109,
1047 1002,
1048 94,
1049 ],
1050 ],
1051 },
1052 {
1053 "time": 0,
1054 },
1055 ]
1056 `);
1057 }
1058 });
1059
1060 it('forwards debugInfo from awaited Promises', async () => {
1061 async function Component() {
1062 let resolve;
1063 const promise = new Promise(r => (resolve = r));
1064 promise._debugInfo = [
1065 {time: performance.now()},
1066 {
1067 name: 'Virtual Component',
1068 },
1069 {time: performance.now()},
1070 ];
1071 const promise2 = promise.then(value => value);
1072 promise2._debugInfo = [
1073 {time: performance.now()},
1074 {
1075 name: 'Virtual Component2',
1076 },
1077 {time: performance.now()},
1078 ];
1079 resolve('hi');
1080 const result = await promise2;
1081 return result.toUpperCase();
1082 }
1083
1084 const stream = ReactServerDOMServer.renderToPipeableStream(<Component />);
1085
1086 const readable = new Stream.PassThrough(streamOptions);
1087
1088 const result = ReactServerDOMClient.createFromNodeStream(readable, {
1089 moduleMap: {},
1090 moduleLoading: {},
1091 });
1092 stream.pipe(readable);
1093
1094 expect(await result).toBe('HI');
1095
1096 await finishLoadingStream(readable);
1097 if (
1098 __DEV__ &&
1099 gate(
1100 flags =>
1101 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
1102 )
1103 ) {
1104 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
1105 [
1106 {
1107 "time": 0,
1108 },
1109 {
1110 "env": "Server",
1111 "key": null,
1112 "name": "Component",
1113 "props": {},
1114 "stack": [
1115 [
1116 "Object.<anonymous>",
1117 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1118 1084,
1119 109,
1120 1060,
1121 50,
1122 ],
1123 ],
1124 },
1125 {
1126 "time": 0,
1127 },
1128 {
1129 "name": "Virtual Component",
1130 },
1131 {
1132 "time": 0,
1133 },
1134 {
1135 "time": 0,
1136 },
1137 {
1138 "name": "Virtual Component2",
1139 },
1140 {
1141 "time": 0,
1142 },
1143 {
1144 "time": 0,
1145 },
1146 ]
1147 `);
1148 }
1149 });
1150
1151 it('forwards async debug info one environment to the next', async () => {
1152 async function getData() {
1153 await delay(1);
1154 await delay(2);
1155 return 'hi';
1156 }
1157
1158 async function ThirdPartyComponent() {
1159 const data = await getData();
1160 return data;
1161 }
1162
1163 async function Component() {
1164 const data = await fetchThirdParty(ThirdPartyComponent);
1165 return data.toUpperCase();
1166 }
1167
1168 const stream = ReactServerDOMServer.renderToPipeableStream(<Component />);
1169
1170 const readable = new Stream.PassThrough(streamOptions);
1171
1172 const result = ReactServerDOMClient.createFromNodeStream(readable, {
1173 moduleMap: {},
1174 moduleLoading: {},
1175 });
1176 stream.pipe(readable);
1177
1178 expect(await result).toBe('HI');
1179
1180 await finishLoadingStream(readable);
1181 if (
1182 __DEV__ &&
1183 gate(
1184 flags =>
1185 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
1186 )
1187 ) {
1188 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
1189 [
1190 {
1191 "time": 0,
1192 },
1193 {
1194 "env": "Server",
1195 "key": null,
1196 "name": "Component",
1197 "props": {},
1198 "stack": [
1199 [
1200 "Object.<anonymous>",
1201 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1202 1168,
1203 109,
1204 1151,
1205 63,
1206 ],
1207 ],
1208 },
1209 {
1210 "time": 0,
1211 },
1212 {
1213 "env": "third-party",
1214 "key": null,
1215 "name": "ThirdPartyComponent",
1216 "props": {},
1217 "stack": [
1218 [
1219 "fetchThirdParty",
1220 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1221 94,
1222 40,
1223 92,
1224 3,
1225 ],
1226 [
1227 "Component",
1228 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1229 1164,
1230 24,
1231 1163,
1232 5,
1233 ],
1234 ],
1235 },
1236 {
1237 "time": 0,
1238 },
1239 {
1240 "awaited": {
1241 "end": 0,
1242 "env": "third-party",
1243 "name": "delay",
1244 "owner": {
1245 "env": "third-party",
1246 "key": null,
1247 "name": "ThirdPartyComponent",
1248 "props": {},
1249 "stack": [
1250 [
1251 "fetchThirdParty",
1252 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1253 94,
1254 40,
1255 92,
1256 3,
1257 ],
1258 [
1259 "Component",
1260 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1261 1164,
1262 24,
1263 1163,
1264 5,
1265 ],
1266 ],
1267 },
1268 "stack": [
1269 [
1270 "delay",
1271 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1272 87,
1273 12,
1274 86,
1275 3,
1276 ],
1277 [
1278 "getData",
1279 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1280 1153,
1281 13,
1282 1152,
1283 5,
1284 ],
1285 [
1286 "ThirdPartyComponent",
1287 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1288 1159,
1289 24,
1290 1158,
1291 5,
1292 ],
1293 ],
1294 "start": 0,
1295 "value": {
1296 "value": undefined,
1297 },
1298 },
1299 "env": "third-party",
1300 "owner": {
1301 "env": "third-party",
1302 "key": null,
1303 "name": "ThirdPartyComponent",
1304 "props": {},
1305 "stack": [
1306 [
1307 "fetchThirdParty",
1308 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1309 94,
1310 40,
1311 92,
1312 3,
1313 ],
1314 [
1315 "Component",
1316 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1317 1164,
1318 24,
1319 1163,
1320 5,
1321 ],
1322 ],
1323 },
1324 "stack": [
1325 [
1326 "getData",
1327 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1328 1153,
1329 13,
1330 1152,
1331 5,
1332 ],
1333 [
1334 "ThirdPartyComponent",
1335 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1336 1159,
1337 24,
1338 1158,
1339 5,
1340 ],
1341 ],
1342 },
1343 {
1344 "time": 0,
1345 },
1346 {
1347 "time": 0,
1348 },
1349 {
1350 "awaited": {
1351 "end": 0,
1352 "env": "third-party",
1353 "name": "delay",
1354 "owner": {
1355 "env": "third-party",
1356 "key": null,
1357 "name": "ThirdPartyComponent",
1358 "props": {},
1359 "stack": [
1360 [
1361 "fetchThirdParty",
1362 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1363 94,
1364 40,
1365 92,
1366 3,
1367 ],
1368 [
1369 "Component",
1370 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1371 1164,
1372 24,
1373 1163,
1374 5,
1375 ],
1376 ],
1377 },
1378 "stack": [
1379 [
1380 "delay",
1381 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1382 87,
1383 12,
1384 86,
1385 3,
1386 ],
1387 [
1388 "getData",
1389 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1390 1154,
1391 13,
1392 1152,
1393 5,
1394 ],
1395 [
1396 "ThirdPartyComponent",
1397 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1398 1159,
1399 18,
1400 1158,
1401 5,
1402 ],
1403 ],
1404 "start": 0,
1405 "value": {
1406 "value": undefined,
1407 },
1408 },
1409 "env": "third-party",
1410 "owner": {
1411 "env": "third-party",
1412 "key": null,
1413 "name": "ThirdPartyComponent",
1414 "props": {},
1415 "stack": [
1416 [
1417 "fetchThirdParty",
1418 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1419 94,
1420 40,
1421 92,
1422 3,
1423 ],
1424 [
1425 "Component",
1426 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1427 1164,
1428 24,
1429 1163,
1430 5,
1431 ],
1432 ],
1433 },
1434 "stack": [
1435 [
1436 "getData",
1437 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1438 1154,
1439 13,
1440 1152,
1441 5,
1442 ],
1443 [
1444 "ThirdPartyComponent",
1445 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1446 1159,
1447 18,
1448 1158,
1449 5,
1450 ],
1451 ],
1452 },
1453 {
1454 "time": 0,
1455 },
1456 {
1457 "time": 0,
1458 },
1459 {
1460 "awaited": {
1461 "byteSize": 0,
1462 "end": 0,
1463 "env": "Server",
1464 "name": "rsc stream",
1465 "start": 0,
1466 "value": {
1467 "value": "stream",
1468 },
1469 },
1470 "env": "Server",
1471 },
1472 {
1473 "time": 0,
1474 },
1475 {
1476 "awaited": {
1477 "byteSize": 0,
1478 "end": 0,
1479 "name": "rsc stream",
1480 "owner": null,
1481 "start": 0,
1482 "value": {
1483 "value": "stream",
1484 },
1485 },
1486 },
1487 ]
1488 `);
1489 }
1490 });
1491
1492 it('can track cached entries awaited in later components', async () => {
1493 const getData = cache(async function getData(text) {
1494 await delay(1);
1495 return text.toUpperCase();
1496 });
1497
1498 async function Child() {
1499 const greeting = await getData('hi');
1500 return greeting + ', Seb';
1501 }
1502
1503 async function Component() {
1504 await getData('hi');
1505 return <Child />;
1506 }
1507
1508 const stream = ReactServerDOMServer.renderToPipeableStream(
1509 <Component />,
1510 {},
1511 {
1512 filterStackFrame,
1513 },
1514 );
1515
1516 const readable = new Stream.PassThrough(streamOptions);
1517
1518 const result = ReactServerDOMClient.createFromNodeStream(readable, {
1519 moduleMap: {},
1520 moduleLoading: {},
1521 });
1522 stream.pipe(readable);
1523
1524 expect(await result).toBe('HI, Seb');
1525
1526 await finishLoadingStream(readable);
1527 if (
1528 __DEV__ &&
1529 gate(
1530 flags =>
1531 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
1532 )
1533 ) {
1534 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
1535 [
1536 {
1537 "time": 0,
1538 },
1539 {
1540 "env": "Server",
1541 "key": null,
1542 "name": "Component",
1543 "props": {},
1544 "stack": [
1545 [
1546 "Object.<anonymous>",
1547 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1548 1509,
1549 40,
1550 1492,
1551 62,
1552 ],
1553 [
1554 "new Promise",
1555 "",
1556 0,
1557 0,
1558 0,
1559 0,
1560 ],
1561 ],
1562 },
1563 {
1564 "time": 0,
1565 },
1566 {
1567 "awaited": {
1568 "end": 0,
1569 "env": "Server",
1570 "name": "delay",
1571 "owner": {
1572 "env": "Server",
1573 "key": null,
1574 "name": "Component",
1575 "props": {},
1576 "stack": [
1577 [
1578 "Object.<anonymous>",
1579 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1580 1509,
1581 40,
1582 1492,
1583 62,
1584 ],
1585 [
1586 "new Promise",
1587 "",
1588 0,
1589 0,
1590 0,
1591 0,
1592 ],
1593 ],
1594 },
1595 "stack": [
1596 [
1597 "delay",
1598 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1599 87,
1600 12,
1601 86,
1602 3,
1603 ],
1604 [
1605 "getData",
1606 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1607 1494,
1608 13,
1609 1493,
1610 25,
1611 ],
1612 [
1613 "Component",
1614 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1615 1504,
1616 13,
1617 1503,
1618 5,
1619 ],
1620 ],
1621 "start": 0,
1622 "value": {
1623 "value": undefined,
1624 },
1625 },
1626 "env": "Server",
1627 "owner": {
1628 "env": "Server",
1629 "key": null,
1630 "name": "Component",
1631 "props": {},
1632 "stack": [
1633 [
1634 "Object.<anonymous>",
1635 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1636 1509,
1637 40,
1638 1492,
1639 62,
1640 ],
1641 [
1642 "new Promise",
1643 "",
1644 0,
1645 0,
1646 0,
1647 0,
1648 ],
1649 ],
1650 },
1651 "stack": [
1652 [
1653 "getData",
1654 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1655 1494,
1656 13,
1657 1493,
1658 25,
1659 ],
1660 [
1661 "Component",
1662 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1663 1504,
1664 13,
1665 1503,
1666 5,
1667 ],
1668 ],
1669 },
1670 {
1671 "time": 0,
1672 },
1673 {
1674 "time": 0,
1675 },
1676 {
1677 "env": "Server",
1678 "key": null,
1679 "name": "Child",
1680 "props": {},
1681 "stack": [
1682 [
1683 "Component",
1684 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1685 1505,
1686 60,
1687 1503,
1688 5,
1689 ],
1690 ],
1691 },
1692 {
1693 "time": 0,
1694 },
1695 {
1696 "awaited": {
1697 "end": 0,
1698 "env": "Server",
1699 "name": "delay",
1700 "owner": {
1701 "env": "Server",
1702 "key": null,
1703 "name": "Component",
1704 "props": {},
1705 "stack": [
1706 [
1707 "Object.<anonymous>",
1708 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1709 1509,
1710 40,
1711 1492,
1712 62,
1713 ],
1714 [
1715 "new Promise",
1716 "",
1717 0,
1718 0,
1719 0,
1720 0,
1721 ],
1722 ],
1723 },
1724 "stack": [
1725 [
1726 "delay",
1727 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1728 87,
1729 12,
1730 86,
1731 3,
1732 ],
1733 [
1734 "getData",
1735 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1736 1494,
1737 13,
1738 1493,
1739 25,
1740 ],
1741 [
1742 "Component",
1743 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1744 1504,
1745 13,
1746 1503,
1747 5,
1748 ],
1749 ],
1750 "start": 0,
1751 "value": {
1752 "value": undefined,
1753 },
1754 },
1755 "env": "Server",
1756 "owner": {
1757 "env": "Server",
1758 "key": null,
1759 "name": "Child",
1760 "props": {},
1761 "stack": [
1762 [
1763 "Component",
1764 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1765 1505,
1766 60,
1767 1503,
1768 5,
1769 ],
1770 ],
1771 },
1772 "stack": [
1773 [
1774 "Child",
1775 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1776 1499,
1777 28,
1778 1498,
1779 5,
1780 ],
1781 ],
1782 },
1783 {
1784 "time": 0,
1785 },
1786 {
1787 "time": 0,
1788 },
1789 {
1790 "awaited": {
1791 "byteSize": 0,
1792 "end": 0,
1793 "name": "rsc stream",
1794 "owner": null,
1795 "start": 0,
1796 "value": {
1797 "value": "stream",
1798 },
1799 },
1800 },
1801 ]
1802 `);
1803 }
1804 });
1805
1806 it('can track cached entries used in child position', async () => {
1807 const getData = cache(async function getData(text) {
1808 await delay(1);
1809 return text.toUpperCase();
1810 });
1811
1812 function Child() {
1813 return getData('hi');
1814 }
1815
1816 function Component() {
1817 ReactServer.use(getData('hi'));
1818 return <Child />;
1819 }
1820
1821 const stream = ReactServerDOMServer.renderToPipeableStream(
1822 <Component />,
1823 {},
1824 {
1825 filterStackFrame,
1826 },
1827 );
1828
1829 const readable = new Stream.PassThrough(streamOptions);
1830
1831 const result = ReactServerDOMClient.createFromNodeStream(readable, {
1832 moduleMap: {},
1833 moduleLoading: {},
1834 });
1835 stream.pipe(readable);
1836
1837 expect(await result).toBe('HI');
1838
1839 await finishLoadingStream(readable);
1840 if (
1841 __DEV__ &&
1842 gate(
1843 flags =>
1844 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
1845 )
1846 ) {
1847 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
1848 [
1849 {
1850 "time": 0,
1851 },
1852 {
1853 "env": "Server",
1854 "key": null,
1855 "name": "Component",
1856 "props": {},
1857 "stack": [
1858 [
1859 "Object.<anonymous>",
1860 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1861 1822,
1862 40,
1863 1806,
1864 57,
1865 ],
1866 [
1867 "new Promise",
1868 "",
1869 0,
1870 0,
1871 0,
1872 0,
1873 ],
1874 ],
1875 },
1876 {
1877 "time": 0,
1878 },
1879 {
1880 "awaited": {
1881 "end": 0,
1882 "env": "Server",
1883 "name": "delay",
1884 "owner": {
1885 "env": "Server",
1886 "key": null,
1887 "name": "Component",
1888 "props": {},
1889 "stack": [
1890 [
1891 "Object.<anonymous>",
1892 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1893 1822,
1894 40,
1895 1806,
1896 57,
1897 ],
1898 [
1899 "new Promise",
1900 "",
1901 0,
1902 0,
1903 0,
1904 0,
1905 ],
1906 ],
1907 },
1908 "stack": [
1909 [
1910 "delay",
1911 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1912 87,
1913 12,
1914 86,
1915 3,
1916 ],
1917 [
1918 "getData",
1919 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1920 1808,
1921 13,
1922 1807,
1923 25,
1924 ],
1925 [
1926 "Component",
1927 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1928 1817,
1929 23,
1930 1816,
1931 5,
1932 ],
1933 ],
1934 "start": 0,
1935 "value": {
1936 "value": undefined,
1937 },
1938 },
1939 "env": "Server",
1940 "owner": {
1941 "env": "Server",
1942 "key": null,
1943 "name": "Component",
1944 "props": {},
1945 "stack": [
1946 [
1947 "Object.<anonymous>",
1948 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1949 1822,
1950 40,
1951 1806,
1952 57,
1953 ],
1954 [
1955 "new Promise",
1956 "",
1957 0,
1958 0,
1959 0,
1960 0,
1961 ],
1962 ],
1963 },
1964 "stack": [
1965 [
1966 "getData",
1967 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1968 1808,
1969 13,
1970 1807,
1971 25,
1972 ],
1973 [
1974 "Component",
1975 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1976 1817,
1977 23,
1978 1816,
1979 5,
1980 ],
1981 ],
1982 },
1983 {
1984 "time": 0,
1985 },
1986 {
1987 "time": 0,
1988 },
1989 {
1990 "env": "Server",
1991 "key": null,
1992 "name": "Child",
1993 "props": {},
1994 "stack": [
1995 [
1996 "Component",
1997 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
1998 1818,
1999 60,
2000 1816,
2001 5,
2002 ],
2003 ],
2004 },
2005 {
2006 "awaited": {
2007 "end": 0,
2008 "env": "Server",
2009 "name": "delay",
2010 "owner": {
2011 "env": "Server",
2012 "key": null,
2013 "name": "Component",
2014 "props": {},
2015 "stack": [
2016 [
2017 "Object.<anonymous>",
2018 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2019 1822,
2020 40,
2021 1806,
2022 57,
2023 ],
2024 [
2025 "new Promise",
2026 "",
2027 0,
2028 0,
2029 0,
2030 0,
2031 ],
2032 ],
2033 },
2034 "stack": [
2035 [
2036 "delay",
2037 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2038 87,
2039 12,
2040 86,
2041 3,
2042 ],
2043 [
2044 "getData",
2045 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2046 1808,
2047 13,
2048 1807,
2049 25,
2050 ],
2051 [
2052 "Component",
2053 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2054 1817,
2055 23,
2056 1816,
2057 5,
2058 ],
2059 ],
2060 "start": 0,
2061 "value": {
2062 "value": undefined,
2063 },
2064 },
2065 "env": "Server",
2066 "stack": [
2067 [
2068 "Component",
2069 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2070 1818,
2071 60,
2072 1816,
2073 5,
2074 ],
2075 ],
2076 },
2077 {
2078 "time": 0,
2079 },
2080 {
2081 "time": 0,
2082 },
2083 {
2084 "awaited": {
2085 "byteSize": 0,
2086 "end": 0,
2087 "name": "rsc stream",
2088 "owner": null,
2089 "start": 0,
2090 "value": {
2091 "value": "stream",
2092 },
2093 },
2094 },
2095 ]
2096 `);
2097 }
2098 });
2099
2100 it('can track implicit returned promises that are blocked by previous data', async () => {
2101 async function delayTwice() {
2102 await delay('', 20);
2103 await delay('', 10);
2104 }
2105
2106 async function delayTrice() {
2107 const p = delayTwice();
2108 await delay('', 40);
2109 return p;
2110 }
2111
2112 async function Bar({children}) {
2113 await delayTrice();
2114 return 'hi';
2115 }
2116
2117 const stream = ReactServerDOMServer.renderToPipeableStream(
2118 <Bar />,
2119 {},
2120 {
2121 filterStackFrame,
2122 },
2123 );
2124
2125 const readable = new Stream.PassThrough(streamOptions);
2126
2127 const result = ReactServerDOMClient.createFromNodeStream(readable, {
2128 moduleMap: {},
2129 moduleLoading: {},
2130 });
2131 stream.pipe(readable);
2132
2133 expect(await result).toBe('hi');
2134
2135 await finishLoadingStream(readable);
2136 if (
2137 __DEV__ &&
2138 gate(
2139 flags =>
2140 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
2141 )
2142 ) {
2143 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
2144 [
2145 {
2146 "time": 0,
2147 },
2148 {
2149 "env": "Server",
2150 "key": null,
2151 "name": "Bar",
2152 "props": {},
2153 "stack": [
2154 [
2155 "Object.<anonymous>",
2156 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2157 2118,
2158 40,
2159 2100,
2160 80,
2161 ],
2162 [
2163 "new Promise",
2164 "",
2165 0,
2166 0,
2167 0,
2168 0,
2169 ],
2170 ],
2171 },
2172 {
2173 "time": 0,
2174 },
2175 {
2176 "awaited": {
2177 "end": 0,
2178 "env": "Server",
2179 "name": "delay",
2180 "owner": {
2181 "env": "Server",
2182 "key": null,
2183 "name": "Bar",
2184 "props": {},
2185 "stack": [
2186 [
2187 "Object.<anonymous>",
2188 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2189 2118,
2190 40,
2191 2100,
2192 80,
2193 ],
2194 [
2195 "new Promise",
2196 "",
2197 0,
2198 0,
2199 0,
2200 0,
2201 ],
2202 ],
2203 },
2204 "stack": [
2205 [
2206 "delay",
2207 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2208 87,
2209 12,
2210 86,
2211 3,
2212 ],
2213 [
2214 "delayTrice",
2215 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2216 2108,
2217 13,
2218 2106,
2219 5,
2220 ],
2221 [
2222 "Bar",
2223 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2224 2113,
2225 13,
2226 2112,
2227 5,
2228 ],
2229 ],
2230 "start": 0,
2231 "value": {
2232 "value": undefined,
2233 },
2234 },
2235 "env": "Server",
2236 "owner": {
2237 "env": "Server",
2238 "key": null,
2239 "name": "Bar",
2240 "props": {},
2241 "stack": [
2242 [
2243 "Object.<anonymous>",
2244 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2245 2118,
2246 40,
2247 2100,
2248 80,
2249 ],
2250 [
2251 "new Promise",
2252 "",
2253 0,
2254 0,
2255 0,
2256 0,
2257 ],
2258 ],
2259 },
2260 "stack": [
2261 [
2262 "delayTrice",
2263 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2264 2108,
2265 13,
2266 2106,
2267 5,
2268 ],
2269 [
2270 "Bar",
2271 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2272 2113,
2273 13,
2274 2112,
2275 5,
2276 ],
2277 ],
2278 },
2279 {
2280 "time": 0,
2281 },
2282 {
2283 "awaited": {
2284 "end": 0,
2285 "env": "Server",
2286 "name": "delay",
2287 "owner": {
2288 "env": "Server",
2289 "key": null,
2290 "name": "Bar",
2291 "props": {},
2292 "stack": [
2293 [
2294 "Object.<anonymous>",
2295 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2296 2118,
2297 40,
2298 2100,
2299 80,
2300 ],
2301 [
2302 "new Promise",
2303 "",
2304 0,
2305 0,
2306 0,
2307 0,
2308 ],
2309 ],
2310 },
2311 "stack": [
2312 [
2313 "delay",
2314 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2315 87,
2316 12,
2317 86,
2318 3,
2319 ],
2320 [
2321 "delayTwice",
2322 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2323 2102,
2324 13,
2325 2101,
2326 5,
2327 ],
2328 [
2329 "delayTrice",
2330 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2331 2107,
2332 15,
2333 2106,
2334 5,
2335 ],
2336 [
2337 "Bar",
2338 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2339 2113,
2340 13,
2341 2112,
2342 5,
2343 ],
2344 ],
2345 "start": 0,
2346 "value": {
2347 "value": undefined,
2348 },
2349 },
2350 "env": "Server",
2351 "owner": {
2352 "env": "Server",
2353 "key": null,
2354 "name": "Bar",
2355 "props": {},
2356 "stack": [
2357 [
2358 "Object.<anonymous>",
2359 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2360 2118,
2361 40,
2362 2100,
2363 80,
2364 ],
2365 [
2366 "new Promise",
2367 "",
2368 0,
2369 0,
2370 0,
2371 0,
2372 ],
2373 ],
2374 },
2375 "stack": [
2376 [
2377 "delayTwice",
2378 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2379 2102,
2380 13,
2381 2101,
2382 5,
2383 ],
2384 [
2385 "delayTrice",
2386 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2387 2107,
2388 15,
2389 2106,
2390 5,
2391 ],
2392 [
2393 "Bar",
2394 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2395 2113,
2396 13,
2397 2112,
2398 5,
2399 ],
2400 ],
2401 },
2402 {
2403 "time": 0,
2404 },
2405 {
2406 "awaited": {
2407 "end": 0,
2408 "env": "Server",
2409 "name": "delay",
2410 "owner": {
2411 "env": "Server",
2412 "key": null,
2413 "name": "Bar",
2414 "props": {},
2415 "stack": [
2416 [
2417 "Object.<anonymous>",
2418 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2419 2118,
2420 40,
2421 2100,
2422 80,
2423 ],
2424 [
2425 "new Promise",
2426 "",
2427 0,
2428 0,
2429 0,
2430 0,
2431 ],
2432 ],
2433 },
2434 "stack": [
2435 [
2436 "delay",
2437 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2438 87,
2439 12,
2440 86,
2441 3,
2442 ],
2443 [
2444 "delayTwice",
2445 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2446 2103,
2447 13,
2448 2101,
2449 5,
2450 ],
2451 ],
2452 "start": 0,
2453 "value": {
2454 "value": undefined,
2455 },
2456 },
2457 "env": "Server",
2458 "owner": {
2459 "env": "Server",
2460 "key": null,
2461 "name": "Bar",
2462 "props": {},
2463 "stack": [
2464 [
2465 "Object.<anonymous>",
2466 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2467 2118,
2468 40,
2469 2100,
2470 80,
2471 ],
2472 [
2473 "new Promise",
2474 "",
2475 0,
2476 0,
2477 0,
2478 0,
2479 ],
2480 ],
2481 },
2482 "stack": [
2483 [
2484 "delayTwice",
2485 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2486 2103,
2487 13,
2488 2101,
2489 5,
2490 ],
2491 ],
2492 },
2493 {
2494 "time": 0,
2495 },
2496 {
2497 "time": 0,
2498 },
2499 {
2500 "awaited": {
2501 "byteSize": 0,
2502 "end": 0,
2503 "name": "rsc stream",
2504 "owner": null,
2505 "start": 0,
2506 "value": {
2507 "value": "stream",
2508 },
2509 },
2510 },
2511 ]
2512 `);
2513 }
2514 });
2515
2516 it('can track IO that is chained via then(async ...)', async () => {
2517 function getData(text) {
2518 return delay(1).then(async () => {
2519 return text.toUpperCase();
2520 });
2521 }
2522
2523 async function Component({text, promise}) {
2524 return await getData('hi, sebbie');
2525 }
2526
2527 const stream = ReactServerDOMServer.renderToPipeableStream(<Component />);
2528
2529 const readable = new Stream.PassThrough(streamOptions);
2530
2531 const result = ReactServerDOMClient.createFromNodeStream(readable, {
2532 moduleMap: {},
2533 moduleLoading: {},
2534 });
2535 stream.pipe(readable);
2536
2537 expect(await result).toBe('HI, SEBBIE');
2538
2539 await finishLoadingStream(readable);
2540 if (
2541 __DEV__ &&
2542 gate(
2543 flags =>
2544 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
2545 )
2546 ) {
2547 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
2548 [
2549 {
2550 "time": 0,
2551 },
2552 {
2553 "env": "Server",
2554 "key": null,
2555 "name": "Component",
2556 "props": {},
2557 "stack": [
2558 [
2559 "Object.<anonymous>",
2560 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2561 2527,
2562 109,
2563 2516,
2564 58,
2565 ],
2566 ],
2567 },
2568 {
2569 "time": 0,
2570 },
2571 {
2572 "awaited": {
2573 "end": 0,
2574 "env": "Server",
2575 "name": "delay",
2576 "owner": {
2577 "env": "Server",
2578 "key": null,
2579 "name": "Component",
2580 "props": {},
2581 "stack": [
2582 [
2583 "Object.<anonymous>",
2584 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2585 2527,
2586 109,
2587 2516,
2588 58,
2589 ],
2590 ],
2591 },
2592 "stack": [
2593 [
2594 "delay",
2595 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2596 87,
2597 12,
2598 86,
2599 3,
2600 ],
2601 [
2602 "getData",
2603 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2604 2518,
2605 14,
2606 2517,
2607 5,
2608 ],
2609 [
2610 "Component",
2611 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2612 2524,
2613 20,
2614 2523,
2615 5,
2616 ],
2617 ],
2618 "start": 0,
2619 "value": {
2620 "value": undefined,
2621 },
2622 },
2623 "env": "Server",
2624 "owner": {
2625 "env": "Server",
2626 "key": null,
2627 "name": "Component",
2628 "props": {},
2629 "stack": [
2630 [
2631 "Object.<anonymous>",
2632 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2633 2527,
2634 109,
2635 2516,
2636 58,
2637 ],
2638 ],
2639 },
2640 "stack": [
2641 [
2642 "getData",
2643 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2644 2518,
2645 23,
2646 2517,
2647 5,
2648 ],
2649 [
2650 "Component",
2651 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2652 2524,
2653 20,
2654 2523,
2655 5,
2656 ],
2657 ],
2658 },
2659 {
2660 "time": 0,
2661 },
2662 {
2663 "time": 0,
2664 },
2665 {
2666 "awaited": {
2667 "byteSize": 0,
2668 "end": 0,
2669 "name": "rsc stream",
2670 "owner": null,
2671 "start": 0,
2672 "value": {
2673 "value": "stream",
2674 },
2675 },
2676 },
2677 ]
2678 `);
2679 }
2680 });
2681
2682 it('can track IO that is not awaited in user space', async () => {
2683 function internal_API(text) {
2684 return delay(1).then(async () => {
2685 return text.toUpperCase();
2686 });
2687 }
2688
2689 async function Component({text, promise}) {
2690 return await internal_API('hi, seb');
2691 }
2692
2693 const stream = ReactServerDOMServer.renderToPipeableStream(
2694 <Component />,
2695 {},
2696 {
2697 filterStackFrame,
2698 },
2699 );
2700
2701 const readable = new Stream.PassThrough(streamOptions);
2702
2703 const result = ReactServerDOMClient.createFromNodeStream(readable, {
2704 moduleMap: {},
2705 moduleLoading: {},
2706 });
2707 stream.pipe(readable);
2708
2709 expect(await result).toBe('HI, SEB');
2710
2711 await finishLoadingStream(readable);
2712 if (
2713 __DEV__ &&
2714 gate(
2715 flags =>
2716 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
2717 )
2718 ) {
2719 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
2720 [
2721 {
2722 "time": 0,
2723 },
2724 {
2725 "env": "Server",
2726 "key": null,
2727 "name": "Component",
2728 "props": {},
2729 "stack": [
2730 [
2731 "Object.<anonymous>",
2732 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2733 2694,
2734 40,
2735 2682,
2736 56,
2737 ],
2738 [
2739 "new Promise",
2740 "",
2741 0,
2742 0,
2743 0,
2744 0,
2745 ],
2746 ],
2747 },
2748 {
2749 "time": 0,
2750 },
2751 {
2752 "awaited": {
2753 "end": 0,
2754 "env": "Server",
2755 "name": "delay",
2756 "owner": {
2757 "env": "Server",
2758 "key": null,
2759 "name": "Component",
2760 "props": {},
2761 "stack": [
2762 [
2763 "Object.<anonymous>",
2764 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2765 2694,
2766 40,
2767 2682,
2768 56,
2769 ],
2770 [
2771 "new Promise",
2772 "",
2773 0,
2774 0,
2775 0,
2776 0,
2777 ],
2778 ],
2779 },
2780 "stack": [
2781 [
2782 "delay",
2783 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2784 87,
2785 12,
2786 86,
2787 3,
2788 ],
2789 [
2790 "Component",
2791 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2792 2690,
2793 20,
2794 2689,
2795 5,
2796 ],
2797 ],
2798 "start": 0,
2799 "value": {
2800 "value": "HI, SEB",
2801 },
2802 },
2803 "env": "Server",
2804 "owner": {
2805 "env": "Server",
2806 "key": null,
2807 "name": "Component",
2808 "props": {},
2809 "stack": [
2810 [
2811 "Object.<anonymous>",
2812 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2813 2694,
2814 40,
2815 2682,
2816 56,
2817 ],
2818 [
2819 "new Promise",
2820 "",
2821 0,
2822 0,
2823 0,
2824 0,
2825 ],
2826 ],
2827 },
2828 "stack": [
2829 [
2830 "Component",
2831 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2832 2690,
2833 20,
2834 2689,
2835 5,
2836 ],
2837 ],
2838 },
2839 {
2840 "time": 0,
2841 },
2842 {
2843 "time": 0,
2844 },
2845 {
2846 "awaited": {
2847 "byteSize": 0,
2848 "end": 0,
2849 "name": "rsc stream",
2850 "owner": null,
2851 "start": 0,
2852 "value": {
2853 "value": "stream",
2854 },
2855 },
2856 },
2857 ]
2858 `);
2859 }
2860 });
2861
2862 it('can track IO in third-party code', async () => {
2863 async function thirdParty(endpoint) {
2864 return new Promise(resolve => {
2865 setTimeout(() => {
2866 resolve('third-party ' + endpoint);
2867 }, 10);
2868 }).then(async value => {
2869 await new Promise(resolve => {
2870 setTimeout(resolve, 10);
2871 });
2872
2873 return value;
2874 });
2875 }
2876
2877 async function Component() {
2878 const value = await thirdParty('hi');
2879 return value;
2880 }
2881
2882 const stream = ReactServerDOMServer.renderToPipeableStream(
2883 <Component />,
2884 {},
2885 {
2886 filterStackFrame(filename, functionName) {
2887 if (functionName === 'thirdParty') {
2888 return false;
2889 }
2890 return filterStackFrame(filename, functionName);
2891 },
2892 },
2893 );
2894
2895 const readable = new Stream.PassThrough(streamOptions);
2896
2897 const result = ReactServerDOMClient.createFromNodeStream(readable, {
2898 moduleMap: {},
2899 moduleLoading: {},
2900 });
2901 stream.pipe(readable);
2902
2903 expect(await result).toBe('third-party hi');
2904
2905 await finishLoadingStream(readable);
2906 if (
2907 __DEV__ &&
2908 gate(
2909 flags =>
2910 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
2911 )
2912 ) {
2913 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
2914 [
2915 {
2916 "time": 0,
2917 },
2918 {
2919 "env": "Server",
2920 "key": null,
2921 "name": "Component",
2922 "props": {},
2923 "stack": [
2924 [
2925 "Object.<anonymous>",
2926 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2927 2883,
2928 40,
2929 2862,
2930 42,
2931 ],
2932 [
2933 "new Promise",
2934 "",
2935 0,
2936 0,
2937 0,
2938 0,
2939 ],
2940 ],
2941 },
2942 {
2943 "time": 0,
2944 },
2945 {
2946 "awaited": {
2947 "end": 0,
2948 "env": "Server",
2949 "name": "",
2950 "owner": {
2951 "env": "Server",
2952 "key": null,
2953 "name": "Component",
2954 "props": {},
2955 "stack": [
2956 [
2957 "Object.<anonymous>",
2958 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2959 2883,
2960 40,
2961 2862,
2962 42,
2963 ],
2964 [
2965 "new Promise",
2966 "",
2967 0,
2968 0,
2969 0,
2970 0,
2971 ],
2972 ],
2973 },
2974 "stack": [
2975 [
2976 "",
2977 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2978 2869,
2979 15,
2980 2868,
2981 15,
2982 ],
2983 [
2984 "Component",
2985 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
2986 2878,
2987 19,
2988 2877,
2989 5,
2990 ],
2991 ],
2992 "start": 0,
2993 "value": {
2994 "value": undefined,
2995 },
2996 },
2997 "env": "Server",
2998 "owner": {
2999 "env": "Server",
3000 "key": null,
3001 "name": "Component",
3002 "props": {},
3003 "stack": [
3004 [
3005 "Object.<anonymous>",
3006 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3007 2883,
3008 40,
3009 2862,
3010 42,
3011 ],
3012 [
3013 "new Promise",
3014 "",
3015 0,
3016 0,
3017 0,
3018 0,
3019 ],
3020 ],
3021 },
3022 "stack": [
3023 [
3024 "",
3025 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3026 2869,
3027 15,
3028 2868,
3029 15,
3030 ],
3031 [
3032 "Component",
3033 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3034 2878,
3035 19,
3036 2877,
3037 5,
3038 ],
3039 ],
3040 },
3041 {
3042 "time": 0,
3043 },
3044 {
3045 "awaited": {
3046 "end": 0,
3047 "env": "Server",
3048 "name": "thirdParty",
3049 "owner": {
3050 "env": "Server",
3051 "key": null,
3052 "name": "Component",
3053 "props": {},
3054 "stack": [
3055 [
3056 "Object.<anonymous>",
3057 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3058 2883,
3059 40,
3060 2862,
3061 42,
3062 ],
3063 [
3064 "new Promise",
3065 "",
3066 0,
3067 0,
3068 0,
3069 0,
3070 ],
3071 ],
3072 },
3073 "stack": [
3074 [
3075 "Component",
3076 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3077 2878,
3078 25,
3079 2877,
3080 5,
3081 ],
3082 ],
3083 "start": 0,
3084 "value": {
3085 "value": "third-party hi",
3086 },
3087 },
3088 "env": "Server",
3089 "owner": {
3090 "env": "Server",
3091 "key": null,
3092 "name": "Component",
3093 "props": {},
3094 "stack": [
3095 [
3096 "Object.<anonymous>",
3097 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3098 2883,
3099 40,
3100 2862,
3101 42,
3102 ],
3103 [
3104 "new Promise",
3105 "",
3106 0,
3107 0,
3108 0,
3109 0,
3110 ],
3111 ],
3112 },
3113 "stack": [
3114 [
3115 "Component",
3116 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3117 2878,
3118 25,
3119 2877,
3120 5,
3121 ],
3122 ],
3123 },
3124 {
3125 "time": 0,
3126 },
3127 {
3128 "time": 0,
3129 },
3130 {
3131 "awaited": {
3132 "byteSize": 0,
3133 "end": 0,
3134 "name": "rsc stream",
3135 "owner": null,
3136 "start": 0,
3137 "value": {
3138 "value": "stream",
3139 },
3140 },
3141 },
3142 ]
3143 `);
3144 }
3145 });
3146
3147 it('can track async file reads', async () => {
3148 const filename = path.join(__dirname, 'test-file.txt');
3149 async function Component() {
3150 const buffer = await fs
3151 .readFile(filename) // This loads a Buffer.
3152 // TODO: For some reason, without this we're extracting the wrong promise.
3153 .then(v => v);
3154 const text = buffer.toString('utf8');
3155 return text.slice(0, 26);
3156 }
3157
3158 const stream = ReactServerDOMServer.renderToPipeableStream(
3159 ReactServer.createElement(Component),
3160 {},
3161 );
3162
3163 const readable = new Stream.PassThrough(streamOptions);
3164
3165 const result = ReactServerDOMClient.createFromNodeStream(readable, {
3166 moduleMap: {},
3167 moduleLoading: {},
3168 });
3169 stream.pipe(readable);
3170
3171 expect(await result).toBe('Lorem ipsum dolor sit amet');
3172
3173 await finishLoadingStream(readable);
3174 if (
3175 __DEV__ &&
3176 gate(
3177 flags =>
3178 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
3179 )
3180 ) {
3181 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
3182 [
3183 {
3184 "time": 0,
3185 },
3186 {
3187 "env": "Server",
3188 "key": null,
3189 "name": "Component",
3190 "props": {},
3191 "stack": [
3192 [
3193 "Object.<anonymous>",
3194 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3195 3159,
3196 19,
3197 3147,
3198 36,
3199 ],
3200 ],
3201 },
3202 {
3203 "time": 0,
3204 },
3205 {
3206 "awaited": {
3207 "end": 0,
3208 "env": "Server",
3209 "name": "Object.readFile",
3210 "owner": {
3211 "env": "Server",
3212 "key": null,
3213 "name": "Component",
3214 "props": {},
3215 "stack": [
3216 [
3217 "Object.<anonymous>",
3218 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3219 3159,
3220 19,
3221 3147,
3222 36,
3223 ],
3224 ],
3225 },
3226 "stack": [
3227 [
3228 "Component",
3229 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3230 3151,
3231 7,
3232 3149,
3233 5,
3234 ],
3235 ],
3236 "start": 0,
3237 "value": {
3238 "status": "halted",
3239 },
3240 },
3241 "env": "Server",
3242 "owner": {
3243 "env": "Server",
3244 "key": null,
3245 "name": "Component",
3246 "props": {},
3247 "stack": [
3248 [
3249 "Object.<anonymous>",
3250 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3251 3159,
3252 19,
3253 3147,
3254 36,
3255 ],
3256 ],
3257 },
3258 "stack": [
3259 [
3260 "Component",
3261 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3262 3153,
3263 7,
3264 3149,
3265 5,
3266 ],
3267 ],
3268 },
3269 {
3270 "time": 0,
3271 },
3272 {
3273 "time": 0,
3274 },
3275 {
3276 "awaited": {
3277 "byteSize": 0,
3278 "end": 0,
3279 "name": "rsc stream",
3280 "owner": null,
3281 "start": 0,
3282 "value": {
3283 "value": "stream",
3284 },
3285 },
3286 },
3287 ]
3288 `);
3289 }
3290 });
3291
3292 it('can track a promise created fully outside first party code', async function internal_test() {
3293 async function internal_API(text, timeout) {
3294 let resolve;
3295 const promise = new Promise(r => {
3296 resolve = r;
3297 });
3298 promise.displayName = 'greeting';
3299 setTimeout(() => resolve(text), timeout);
3300 return promise;
3301 }
3302
3303 async function Component({promise}) {
3304 const result = await promise;
3305 return result;
3306 }
3307
3308 const stream = ReactServerDOMServer.renderToPipeableStream(
3309 <Component promise={internal_API('hello', 1)} />,
3310 {},
3311 {
3312 filterStackFrame,
3313 },
3314 );
3315
3316 const readable = new Stream.PassThrough(streamOptions);
3317
3318 const result = ReactServerDOMClient.createFromNodeStream(readable, {
3319 moduleMap: {},
3320 moduleLoading: {},
3321 });
3322 stream.pipe(readable);
3323
3324 expect(await result).toBe('hello');
3325
3326 await finishLoadingStream(readable);
3327 if (
3328 __DEV__ &&
3329 gate(
3330 flags =>
3331 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
3332 )
3333 ) {
3334 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
3335 [
3336 {
3337 "time": 0,
3338 },
3339 {
3340 "env": "Server",
3341 "key": null,
3342 "name": "Component",
3343 "props": {},
3344 "stack": [
3345 [
3346 "new Promise",
3347 "",
3348 0,
3349 0,
3350 0,
3351 0,
3352 ],
3353 ],
3354 },
3355 {
3356 "time": 0,
3357 },
3358 {
3359 "awaited": {
3360 "end": 0,
3361 "env": "Server",
3362 "name": "greeting",
3363 "start": 0,
3364 "value": {
3365 "status": "halted",
3366 },
3367 },
3368 "env": "Server",
3369 "owner": {
3370 "env": "Server",
3371 "key": null,
3372 "name": "Component",
3373 "props": {},
3374 "stack": [
3375 [
3376 "new Promise",
3377 "",
3378 0,
3379 0,
3380 0,
3381 0,
3382 ],
3383 ],
3384 },
3385 "stack": [
3386 [
3387 "Component",
3388 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3389 3304,
3390 20,
3391 3303,
3392 5,
3393 ],
3394 ],
3395 },
3396 {
3397 "time": 0,
3398 },
3399 {
3400 "time": 0,
3401 },
3402 ]
3403 `);
3404 }
3405 });
3406
3407 // Regression test: Database clients like Gel/EdgeDB with connection pools can
3408 // create very long chains of async nodes linked via `previous` pointers.
3409 // visitAsyncNode must handle chains of thousands of nodes without stack
3410 // overflow.
3411 //
3412 // The pattern that creates deep chains (Event/messageWaiter):
3413 // 1. Create a Promise resolved by an I/O callback
3414 // 2. Start I/O, await the Promise
3415 // 3. When I/O resolves, code continues in the callback context
3416 // 4. The next iteration's async nodes link via `previous` to the current
3417 // context
3418 it('handles deep linear async chains from connection pool patterns', async () => {
3419 // Replicate Gel's Event class pattern, a Promise resolved externally by I/O
3420 class Event {
3421 constructor() {
3422 this._resolve = null;
3423 this._promise = new Promise(resolve => {
3424 this._resolve = resolve;
3425 });
3426 }
3427
3428 wait() {
3429 return this._promise;
3430 }
3431
3432 set() {
3433 this._resolve(true);
3434 }
3435 }
3436
3437 // Replicate Gel's _waitForMessage pattern:
3438 // Each iteration creates an Event, schedules I/O to resolve it, and awaits.
3439 // The next iteration runs in the context of the previous I/O callback,
3440 // creating linear chains of previous pointers.
3441 async function buildLinearChain(depth) {
3442 for (let i = 0; i < depth; i++) {
3443 const event = new Event();
3444 // crypto.randomBytes uses the thread pool and is recognized as I/O
3445 // (type='RANDOMBYTESREQUEST'). It's much faster than setTimeout.
3446 crypto.randomBytes(1, () => event.set());
3447 await event.wait();
3448 // After this await resolves, we're in the crypto callback's context
3449 // The next Event will be created in this context, linking prev pointers
3450 }
3451 }
3452
3453 async function Component() {
3454 // Use 2000 iterations to ensure regression would be caught. Using
3455 // crypto.randomBytes keeps the test fast.
3456 await buildLinearChain(2000);
3457 return 'done';
3458 }
3459
3460 const stream = ReactServerDOMServer.renderToPipeableStream(
3461 <Component />,
3462 {},
3463 {
3464 filterStackFrame: (filename, functionName) => {
3465 // Custom filter that treats Event and buildLinearChain as library
3466 // code. This simulates how real DB libraries like Gel/EdgeDB would be
3467 // filtered.
3468 if (
3469 functionName === 'new Event' ||
3470 functionName === 'buildLinearChain' ||
3471 functionName === '_loop' // Generated name for the for-loop
3472 ) {
3473 return false;
3474 }
3475 return filterStackFrame(filename, functionName);
3476 },
3477 },
3478 );
3479
3480 const readable = new Stream.PassThrough(streamOptions);
3481
3482 const result = ReactServerDOMClient.createFromNodeStream(readable, {
3483 moduleMap: {},
3484 moduleLoading: {},
3485 });
3486 stream.pipe(readable);
3487
3488 // This should not throw "Maximum call stack size exceeded"
3489 expect(await result).toBe('done');
3490
3491 await finishLoadingStream(readable);
3492 if (
3493 __DEV__ &&
3494 gate(
3495 flags =>
3496 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
3497 )
3498 ) {
3499 // With library code filtered out, we should only see the Component's
3500 // debug info, not thousands of entries from the internal
3501 // Event/buildLinearChain operations.
3502 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
3503 [
3504 {
3505 "time": 0,
3506 },
3507 {
3508 "env": "Server",
3509 "key": null,
3510 "name": "Component",
3511 "props": {},
3512 "stack": [
3513 [
3514 "Object.<anonymous>",
3515 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3516 3461,
3517 40,
3518 3418,
3519 72,
3520 ],
3521 [
3522 "new Promise",
3523 "",
3524 0,
3525 0,
3526 0,
3527 0,
3528 ],
3529 ],
3530 },
3531 {
3532 "time": 0,
3533 },
3534 {
3535 "awaited": {
3536 "end": 0,
3537 "env": "Server",
3538 "name": "buildLinearChain",
3539 "owner": {
3540 "env": "Server",
3541 "key": null,
3542 "name": "Component",
3543 "props": {},
3544 "stack": [
3545 [
3546 "Object.<anonymous>",
3547 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3548 3461,
3549 40,
3550 3418,
3551 72,
3552 ],
3553 [
3554 "new Promise",
3555 "",
3556 0,
3557 0,
3558 0,
3559 0,
3560 ],
3561 ],
3562 },
3563 "stack": [
3564 [
3565 "Component",
3566 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3567 3456,
3568 13,
3569 3453,
3570 5,
3571 ],
3572 ],
3573 "start": 0,
3574 "value": {
3575 "value": undefined,
3576 },
3577 },
3578 "env": "Server",
3579 "owner": {
3580 "env": "Server",
3581 "key": null,
3582 "name": "Component",
3583 "props": {},
3584 "stack": [
3585 [
3586 "Object.<anonymous>",
3587 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3588 3461,
3589 40,
3590 3418,
3591 72,
3592 ],
3593 [
3594 "new Promise",
3595 "",
3596 0,
3597 0,
3598 0,
3599 0,
3600 ],
3601 ],
3602 },
3603 "stack": [
3604 [
3605 "Component",
3606 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3607 3456,
3608 13,
3609 3453,
3610 5,
3611 ],
3612 ],
3613 },
3614 {
3615 "time": 0,
3616 },
3617 {
3618 "time": 0,
3619 },
3620 {
3621 "awaited": {
3622 "byteSize": 0,
3623 "end": 0,
3624 "name": "rsc stream",
3625 "owner": null,
3626 "start": 0,
3627 "value": {
3628 "value": "stream",
3629 },
3630 },
3631 },
3632 ]
3633 `);
3634 }
3635 });
3636
3637 it('should not exponentially accumulate debug info on outlined debug chunks', async () => {
3638 // Regression test: Each Level wraps its received `context` prop in a new
3639 // object before passing it down. This creates props deduplication
3640 // references to the parent's outlined chunk alongside the owner reference,
3641 // giving 2 references per level to the direct parent's chunk. Without
3642 // skipping transferReferencedDebugInfo during debug info resolution, this
3643 // test would fail with an infinite loop detection error.
3644 async function Level({depth, context}) {
3645 await delay(0);
3646 if (depth === 0) {
3647 return <div>Hello, World!</div>;
3648 }
3649 const newContext = {prev: context, id: depth};
3650 return ReactServer.createElement(Level, {
3651 depth: depth - 1,
3652 context: newContext,
3653 });
3654 }
3655
3656 const stream = ReactServerDOMServer.renderToPipeableStream(
3657 ReactServer.createElement(Level, {depth: 20, context: {root: true}}),
3658 );
3659
3660 const readable = new Stream.PassThrough(streamOptions);
3661 const result = ReactServerDOMClient.createFromNodeStream(readable, {
3662 moduleMap: {},
3663 moduleLoading: {},
3664 });
3665 stream.pipe(readable);
3666
3667 const resolved = await result;
3668 expect(resolved.type).toBe('div');
3669
3670 await finishLoadingStream(readable);
3671 });
3672
3673 it('omits large debug strings to avoid blocking the main thread when parsing', async () => {
3674 async function Component() {
3675 // This promise's value is expected to show up in the debug info below.
3676 const small = await new Promise(resolve => {
3677 setTimeout(() => resolve('hello'), 1);
3678 });
3679
3680 // This promise's value exceeds the threshold for debug string length and
3681 // is expected to show up as a placeholder in the debug info below.
3682 // Reconstructing a multi-megabyte string on the client would block the
3683 // main thread for too long.
3684 const large = await new Promise(resolve => {
3685 setTimeout(() => resolve('x'.repeat(1000001)), 1);
3686 });
3687
3688 return small + ' ' + large.length;
3689 }
3690
3691 const stream = ReactServerDOMServer.renderToPipeableStream(
3692 ReactServer.createElement(Component),
3693 {},
3694 {filterStackFrame},
3695 );
3696
3697 const readable = new Stream.PassThrough(streamOptions);
3698
3699 const result = ReactServerDOMClient.createFromNodeStream(readable, {
3700 moduleMap: {},
3701 moduleLoading: {},
3702 });
3703 stream.pipe(readable);
3704
3705 expect(await result).toBe('hello 1000001');
3706
3707 await finishLoadingStream(readable);
3708 if (
3709 __DEV__ &&
3710 gate(
3711 flags =>
3712 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
3713 )
3714 ) {
3715 expect(getDebugInfo(result)).toMatchInlineSnapshot(`
3716 [
3717 {
3718 "time": 0,
3719 },
3720 {
3721 "env": "Server",
3722 "key": null,
3723 "name": "Component",
3724 "props": {},
3725 "stack": [
3726 [
3727 "Object.<anonymous>",
3728 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3729 3692,
3730 19,
3731 3673,
3732 82,
3733 ],
3734 [
3735 "new Promise",
3736 "",
3737 0,
3738 0,
3739 0,
3740 0,
3741 ],
3742 ],
3743 },
3744 {
3745 "time": 0,
3746 },
3747 {
3748 "awaited": {
3749 "end": 0,
3750 "env": "Server",
3751 "name": "Component",
3752 "owner": {
3753 "env": "Server",
3754 "key": null,
3755 "name": "Component",
3756 "props": {},
3757 "stack": [
3758 [
3759 "Object.<anonymous>",
3760 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3761 3692,
3762 19,
3763 3673,
3764 82,
3765 ],
3766 [
3767 "new Promise",
3768 "",
3769 0,
3770 0,
3771 0,
3772 0,
3773 ],
3774 ],
3775 },
3776 "stack": [
3777 [
3778 "Component",
3779 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3780 3676,
3781 25,
3782 3674,
3783 5,
3784 ],
3785 ],
3786 "start": 0,
3787 "value": {
3788 "value": "hello",
3789 },
3790 },
3791 "env": "Server",
3792 "owner": {
3793 "env": "Server",
3794 "key": null,
3795 "name": "Component",
3796 "props": {},
3797 "stack": [
3798 [
3799 "Object.<anonymous>",
3800 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3801 3692,
3802 19,
3803 3673,
3804 82,
3805 ],
3806 [
3807 "new Promise",
3808 "",
3809 0,
3810 0,
3811 0,
3812 0,
3813 ],
3814 ],
3815 },
3816 "stack": [
3817 [
3818 "Component",
3819 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3820 3676,
3821 25,
3822 3674,
3823 5,
3824 ],
3825 ],
3826 },
3827 {
3828 "time": 0,
3829 },
3830 {
3831 "time": 0,
3832 },
3833 {
3834 "awaited": {
3835 "end": 0,
3836 "env": "Server",
3837 "name": "Component",
3838 "owner": {
3839 "env": "Server",
3840 "key": null,
3841 "name": "Component",
3842 "props": {},
3843 "stack": [
3844 [
3845 "Object.<anonymous>",
3846 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3847 3692,
3848 19,
3849 3673,
3850 82,
3851 ],
3852 [
3853 "new Promise",
3854 "",
3855 0,
3856 0,
3857 0,
3858 0,
3859 ],
3860 ],
3861 },
3862 "stack": [
3863 [
3864 "Component",
3865 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3866 3684,
3867 25,
3868 3674,
3869 5,
3870 ],
3871 ],
3872 "start": 0,
3873 "value": {
3874 "value": "This string of length 1000001 has been omitted by React to avoid sending too much data from the server.",
3875 },
3876 },
3877 "env": "Server",
3878 "owner": {
3879 "env": "Server",
3880 "key": null,
3881 "name": "Component",
3882 "props": {},
3883 "stack": [
3884 [
3885 "Object.<anonymous>",
3886 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3887 3692,
3888 19,
3889 3673,
3890 82,
3891 ],
3892 [
3893 "new Promise",
3894 "",
3895 0,
3896 0,
3897 0,
3898 0,
3899 ],
3900 ],
3901 },
3902 "stack": [
3903 [
3904 "Component",
3905 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
3906 3684,
3907 25,
3908 3674,
3909 5,
3910 ],
3911 ],
3912 },
3913 {
3914 "time": 0,
3915 },
3916 {
3917 "time": 0,
3918 },
3919 {
3920 "awaited": {
3921 "byteSize": 0,
3922 "end": 0,
3923 "name": "rsc stream",
3924 "owner": null,
3925 "start": 0,
3926 "value": {
3927 "value": "stream",
3928 },
3929 },
3930 },
3931 ]
3932 `);
3933 }
3934 });
3935
3936 it('does not lose I/O debug info when intermediate promises are garbage collected', async () => {
3937 // Get a handle on the garbage collector without running the test with --expose-gc.
3938 const v8 = require('v8');
3939 const vm = require('vm');
3940 v8.setFlagsFromString('--expose-gc');
3941 const gc = vm.runInNewContext('gc');
3942 v8.setFlagsFromString('--no-expose-gc');
3943
3944 // The global setImmediate is patched to setTimeout in this test which
3945 // registers as new I/O in async_hooks. Use the real setImmediate for
3946 // yielding to the event loop while waiting for GC so that it doesn't add
3947 // I/O entries to the debug info of the component below.
3948 const {setImmediate: realSetImmediate} = require('timers');
3949 function tick() {
3950 return new Promise(resolve => realSetImmediate(resolve));
3951 }
3952
3953 let ioPromiseRef = null;
3954 let collectedIntermediatePromises = false;
3955
3956 async function getData(text) {
3957 const promise = delay(1);
3958 ioPromiseRef = new WeakRef(promise);
3959 await promise;
3960 return text.toUpperCase();
3961 }
3962
3963 async function waitForGarbageCollection(weakRef) {
3964 // deref() keeps the target alive until the end of the current task, so
3965 // check it on a later tick than the gc() call.
3966 let collected = false;
3967 for (let i = 0; !collected && i < 100; i++) {
3968 gc();
3969 await tick();
3970 collected = weakRef.deref() === undefined;
3971 await tick();
3972 }
3973 // The destroy() hooks of collected promises fire asynchronously. Yield
3974 // a few more times to ensure they have all run.
3975 for (let i = 0; i < 5; i++) {
3976 gc();
3977 await tick();
3978 }
3979 return collected;
3980 }
3981
3982 async function Component() {
3983 const result = await getData('hi');
3984 // At this point the intermediate promises (the delay() promise and
3985 // getData's own async function promise) are unreachable. The async
3986 // debug info graph holds them only weakly through WeakRefs. Force them
3987 // to be garbage collected, which fires their async_hooks destroy()
3988 // hooks, before this component resolves, which is when React walks the
3989 // async graph to emit the component's debug info.
3990 collectedIntermediatePromises =
3991 await waitForGarbageCollection(ioPromiseRef);
3992 return result;
3993 }
3994
3995 const stream = ReactServerDOMServer.renderToPipeableStream(<Component />);
3996
3997 const readable = new Stream.PassThrough(streamOptions);
3998
3999 const result = ReactServerDOMClient.createFromNodeStream(readable, {
4000 moduleMap: {},
4001 moduleLoading: {},
4002 });
4003 stream.pipe(readable);
4004
4005 expect(await result).toBe('HI');
4006 // If this fails, the GC helper above no longer actually collects the
4007 // promises and this test is not testing anything.
4008 expect(collectedIntermediatePromises).toBe(true);
4009
4010 await finishLoadingStream(readable);
4011 if (
4012 __DEV__ &&
4013 gate(
4014 flags =>
4015 flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo,
4016 )
4017 ) {
4018 const debugInfo = getDebugInfo(result);
4019 // The I/O entry for delay() must survive the garbage collection of the
4020 // intermediate promises. The graph nodes are intentionally held
4021 // strongly (only the promises themselves are held weakly through
4022 // WeakRefs) so that the originating I/O is still reachable when the
4023 // debug info is emitted after the promises are gone.
4024 expect(debugInfo).toContainEqual(
4025 expect.objectContaining({
4026 awaited: expect.objectContaining({name: 'delay'}),
4027 }),
4028 );
4029 expect(debugInfo).toMatchInlineSnapshot(`
4030 [
4031 {
4032 "time": 0,
4033 },
4034 {
4035 "env": "Server",
4036 "key": null,
4037 "name": "Component",
4038 "props": {},
4039 "stack": [
4040 [
4041 "Object.<anonymous>",
4042 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
4043 3995,
4044 109,
4045 3936,
4046 87,
4047 ],
4048 ],
4049 },
4050 {
4051 "time": 0,
4052 },
4053 {
4054 "awaited": {
4055 "end": 0,
4056 "env": "Server",
4057 "name": "delay",
4058 "owner": {
4059 "env": "Server",
4060 "key": null,
4061 "name": "Component",
4062 "props": {},
4063 "stack": [
4064 [
4065 "Object.<anonymous>",
4066 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
4067 3995,
4068 109,
4069 3936,
4070 87,
4071 ],
4072 ],
4073 },
4074 "stack": [
4075 [
4076 "delay",
4077 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
4078 87,
4079 12,
4080 86,
4081 3,
4082 ],
4083 [
4084 "getData",
4085 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
4086 3957,
4087 21,
4088 3956,
4089 5,
4090 ],
4091 [
4092 "Component",
4093 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
4094 3983,
4095 26,
4096 3982,
4097 5,
4098 ],
4099 ],
4100 "start": 0,
4101 "value": {
4102 "value": undefined,
4103 },
4104 },
4105 "env": "Server",
4106 "owner": {
4107 "env": "Server",
4108 "key": null,
4109 "name": "Component",
4110 "props": {},
4111 "stack": [
4112 [
4113 "Object.<anonymous>",
4114 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
4115 3995,
4116 109,
4117 3936,
4118 87,
4119 ],
4120 ],
4121 },
4122 "stack": [
4123 [
4124 "getData",
4125 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
4126 3959,
4127 7,
4128 3956,
4129 5,
4130 ],
4131 [
4132 "Component",
4133 "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js",
4134 3983,
4135 26,
4136 3982,
4137 5,
4138 ],
4139 ],
4140 },
4141 {
4142 "time": 0,
4143 },
4144 {
4145 "time": 0,
4146 },
4147 {
4148 "awaited": {
4149 "byteSize": 0,
4150 "end": 0,
4151 "name": "rsc stream",
4152 "owner": null,
4153 "start": 0,
4154 "value": {
4155 "value": "stream",
4156 },
4157 },
4158 },
4159 ]
4160 `);
4161 }
4162 });
4163 });