630
expect(container.innerHTML).toBe('<div></div>');
631
});
632
633
+ it('should handle references to deduped owner objects', async () => {
634
+ // This is replicating React components as generated by @svgr/webpack:
635
+ let path1a: React.ReactNode;
636
+ let path1b: React.ReactNode;
637
+ let path2: React.ReactNode;
638
+
639
+ function Svg1() {
640
+ return ReactServer.createElement(
641
+ 'svg',
642
+ {id: '1'},
643
+ path1a || (path1a = ReactServer.createElement('path', {})),
644
+ path1b || (path1b = ReactServer.createElement('path', {})),
645
+ );
646
+ }
647
+
648
+ function Svg2() {
649
+ return ReactServer.createElement(
650
+ 'svg',
651
+ {id: '2'},
652
+ path2 || (path2 = ReactServer.createElement('path', {})),
653
+ );
654
+ }
655
+
656
+ function Server() {
657
+ return ReactServer.createElement(
658
+ ReactServer.Fragment,
659
+ {},
660
+ ReactServer.createElement(Svg1),
661
+ ReactServer.createElement(Svg2),
662
+ );
663
+ }
664
+
665
+ let stream = await serverAct(() =>
666
+ ReactServerDOMServer.renderToReadableStream(<Server />, webpackMap),
667
+ );
668
+
669
+ function ClientRoot({response}) {
670
+ return use(response);
671
+ }
672
+
673
+ let response = ReactServerDOMClient.createFromReadableStream(stream);
674
+ const container = document.createElement('div');
675
+ const root = ReactDOMClient.createRoot(container);
676
+
677
+ await act(() => {
678
+ root.render(<ClientRoot response={response} />);
679
+ });
680
+
681
+ const expectedHtml =
682
+ '<svg id="1"><path></path><path></path></svg><svg id="2"><path></path></svg>';
683
+
684
+ expect(container.innerHTML).toBe(expectedHtml);
685
+
686
+ // Render a second time:
687
+
688
+ // Assigning the path elements to variables in module scope (here simulated
689
+ // with the test's function scope), and rendering a second time, prevents
690
+ // the owner of the path elements (i.e. Svg1/Svg2) to be deduped. The owner
691
+ // of the path in Svg1 is fully inlined. The owner of the owner of the path
692
+ // in Svg2 is Server, which is deduped and replaced with a reference to the
693
+ // owner of the owner of the path in Svg1. This nested owner is actually
694
+ // Server from the previous render pass, which is kinda broken and libraries
695
+ // probably shouldn't generate code like this. This reference can only be
696
+ // resolved properly if owners are specifically handled when resolving
697
+ // outlined models.
698
+
699
+ stream = await serverAct(() =>
700
+ ReactServerDOMServer.renderToReadableStream(<Server />, webpackMap),
701
+ );
702
+
703
+ response = ReactServerDOMClient.createFromReadableStream(stream);
704
+
705
+ await act(() => {
706
+ root.render(<ClientRoot response={response} />);
707
+ });
708
+
709
+ expect(container.innerHTML).toBe(expectedHtml);
710
+
711
+ if (__DEV__) {
712
+ const resolvedPath1b = await response.value[0].props.children[1]._payload;
713
+
714
+ expect(resolvedPath1b._owner).toEqual(
715
+ expect.objectContaining({
716
+ name: 'Svg1',
717
+ env: 'Server',
718
+ key: null,
719
+ owner: expect.objectContaining({
720
+ name: 'Server',
721
+ env: 'Server',
722
+ key: null,
723
+ owner: null,
724
+ }),
725
+ }),
726
+ );
727
+
728
+ const resolvedPath2 = response.value[1].props.children;
729
+
730
+ expect(resolvedPath2._owner).toEqual(
731
+ expect.objectContaining({
732
+ name: 'Svg2',
733
+ env: 'Server',
734
+ key: null,
735
+ owner: expect.objectContaining({
736
+ name: 'Server',
737
+ env: 'Server',
738
+ key: null,
739
+ owner: null,
740
+ }),
741
+ }),
742
+ );
743
+ }
744
+ });
745
+
746
it('should progressively reveal server components', async () => {
747
let reportedErrors = [];
748