21
if (typeof File === 'undefined') {
22
global.File = require('buffer').File;
23
}
24
+// Patch for Edge environments for global scope
25
+global.AsyncLocalStorage = require('async_hooks').AsyncLocalStorage;
26
27
// Don't wait before processing work on the server.
28
// TODO: we can replace this with FlightServer.act().
34
let webpackModules;
35
let webpackModuleLoading;
36
let React;
37
+let ReactServer;
38
let ReactDOMServer;
39
let ReactServerDOMServer;
40
let ReactServerDOMClient;
58
webpackModules = WebpackMock.webpackModules;
59
webpackModuleLoading = WebpackMock.moduleLoading;
60
61
+ ReactServer = require('react');
62
ReactServerDOMServer = require('react-server-dom-webpack/server');
63
64
jest.resetModules();
696
),
697
);
698
});
699
+
700
+ it('supports async server component debug info as the element owner in DEV', async () => {
701
+ function Container({children}) {
702
+ return children;
703
+ }
704
+
705
+ const promise = Promise.resolve(true);
706
+ async function Greeting({firstName}) {
707
+ // We can't use JSX here because it'll use the Client React.
708
+ const child = ReactServer.createElement(
709
+ 'span',
710
+ null,
711
+ 'Hello, ' + firstName,
712
+ );
713
+ // Yield the synchronous pass
714
+ await promise;
715
+ // We should still be able to track owner using AsyncLocalStorage.
716
+ return ReactServer.createElement(Container, null, child);
717
+ }
718
+
719
+ const model = {
720
+ greeting: ReactServer.createElement(Greeting, {firstName: 'Seb'}),
721
+ };
722
+
723
+ const stream = ReactServerDOMServer.renderToReadableStream(
724
+ model,
725
+ webpackMap,
726
+ );
727
+
728
+ const rootModel = await ReactServerDOMClient.createFromReadableStream(
729
+ stream,
730
+ {
731
+ ssrManifest: {
732
+ moduleMap: null,
733
+ moduleLoading: null,
734
+ },
735
+ },
736
+ );
737
+
738
+ const ssrStream = await ReactDOMServer.renderToReadableStream(
739
+ rootModel.greeting,
740
+ );
741
+ const result = await readResult(ssrStream);
742
+ expect(result).toEqual('<span>Hello, Seb</span>');
743
+
744
+ // Resolve the React Lazy wrapper which must have resolved by now.
745
+ const lazyWrapper = rootModel.greeting;
746
+ const greeting = lazyWrapper._init(lazyWrapper._payload);
747
+
748
+ // We've rendered down to the span.
749
+ expect(greeting.type).toBe('span');
750
+ if (__DEV__) {
751
+ const greetInfo = {name: 'Greeting', env: 'Server', owner: null};
752
+ expect(lazyWrapper._debugInfo).toEqual([
753
+ greetInfo,
754
+ {name: 'Container', env: 'Server', owner: greetInfo},
755
+ ]);
756
+ // The owner that created the span was the outer server component.
757
+ // We expect the debug info to be referentially equal to the owner.
758
+ expect(greeting._owner).toBe(lazyWrapper._debugInfo[0]);
759
+ } else {
760
+ expect(lazyWrapper._debugInfo).toBe(undefined);
761
+ expect(greeting._owner).toBe(
762
+ gate(flags => flags.disableStringRefs) ? undefined : null,
763
+ );
764
+ }
765
+ });
766
});