diff --git a/packages/react-dom-bindings/src/server/ReactFlightServerConfigDOM.js b/packages/react-dom-bindings/src/server/ReactFlightServerConfigDOM.js index 1c9b4763f5201..e5c1c22c190cf 100644 --- a/packages/react-dom-bindings/src/server/ReactFlightServerConfigDOM.js +++ b/packages/react-dom-bindings/src/server/ReactFlightServerConfigDOM.js @@ -169,7 +169,7 @@ function processLink(props: Object, formatContext: FormatContext): void { return; } case 'stylesheet': { - preload(href, 'stylesheet', { + preload(href, 'style', { crossOrigin: props.crossOrigin, integrity: props.integrity, nonce: props.nonce, diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js index 9fe9c7aaf32fd..a2e08383264ac 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js @@ -2087,7 +2087,7 @@ describe('ReactFlightDOM', () => { media="(orientation: landscape)" /> - +

hello world

diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js index 9c7b5b62b195e..40ee397129863 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js @@ -3051,4 +3051,60 @@ describe('ReactFlightDOMBrowser', () => { `); } }); + + it('should resolve a cycle between debug info and the value it produces when using a debug channel', async () => { + // Same as `should resolve a cycle between debug info and the value it produces`, but using a debug channel. + + function Inner({style}) { + return
; + } + + function Component({style}) { + return ; + } + + const style = {}; + const element = ; + style.element = element; + + let debugReadableStreamController; + + const debugReadableStream = new ReadableStream({ + start(controller) { + debugReadableStreamController = controller; + }, + }); + + const rscStream = await serverAct(() => + ReactServerDOMServer.renderToReadableStream(element, webpackMap, { + debugChannel: { + writable: new WritableStream({ + write(chunk) { + debugReadableStreamController.enqueue(chunk); + }, + close() { + debugReadableStreamController.close(); + }, + }), + }, + }), + ); + + function ClientRoot({response}) { + return use(response); + } + + const response = ReactServerDOMClient.createFromReadableStream(rscStream, { + debugChannel: {readable: debugReadableStream}, + }); + + const container = document.createElement('div'); + const root = ReactDOMClient.createRoot(container); + + await act(() => { + root.render(); + }); + + expect(container.innerHTML).toBe('
'); + }); }); diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js index 546e1bbb64f08..152be2eecca57 100644 --- a/packages/react-server/src/ReactFlightServer.js +++ b/packages/react-server/src/ReactFlightServer.js @@ -4300,14 +4300,21 @@ function emitDebugChunk( const json: string = serializeDebugModel(request, 500, debugInfo); if (request.debugDestination !== null) { - // Outline the actual timing information to the debug channel. - const outlinedId = request.nextChunkId++; - const debugRow = outlinedId.toString(16) + ':' + json + '\n'; - request.pendingDebugChunks++; - request.completedDebugChunks.push(stringToChunk(debugRow)); - const row = - serializeRowHeader('D', id) + '"$' + outlinedId.toString(16) + '"\n'; - request.completedRegularChunks.push(stringToChunk(row)); + if (json[0] === '"' && json[1] === '$') { + // This is already an outlined reference so we can just emit it directly, + // without an unnecessary indirection. + const row = serializeRowHeader('D', id) + json + '\n'; + request.completedRegularChunks.push(stringToChunk(row)); + } else { + // Outline the debug information to the debug channel. + const outlinedId = request.nextChunkId++; + const debugRow = outlinedId.toString(16) + ':' + json + '\n'; + request.pendingDebugChunks++; + request.completedDebugChunks.push(stringToChunk(debugRow)); + const row = + serializeRowHeader('D', id) + '"$' + outlinedId.toString(16) + '"\n'; + request.completedRegularChunks.push(stringToChunk(row)); + } } else { const row = serializeRowHeader('D', id) + json + '\n'; request.completedRegularChunks.push(stringToChunk(row));