From c250b7d980864be49facf2306f06455e7f9e305d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Fri, 16 May 2025 14:53:40 -0400 Subject: [PATCH] [Fizz] Should be considered complete inside onShellReady callback (#33295) We decremented `allPendingTasks` after invoking `onShellReady`. Which means that in that scope it wasn't considered fully complete. Since the pattern for flushing in Node.js is to start piping in `onShellReady` and that's how you can get sync behavior, this led us to think that we had more work left to do. For example we emitted the `writeShellTimeInstruction` in this scenario before. --- .../src/__tests__/ReactDOMFizzServerNode-test.js | 15 +++++++++++++++ packages/react-server/src/ReactFizzServer.js | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js index d4f3486a1db..198ccb4f8f6 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js @@ -67,6 +67,21 @@ describe('ReactDOMFizzServerNode', () => { expect(output.result).toMatchInlineSnapshot(`"
hello world
"`); }); + it('flush fully if piping in on onShellReady', async () => { + const {writable, output} = getTestWritable(); + await act(() => { + const {pipe} = ReactDOMFizzServer.renderToPipeableStream( +
hello world
, + { + onShellReady() { + pipe(writable); + }, + }, + ); + }); + expect(output.result).toMatchInlineSnapshot(`"
hello world
"`); + }); + it('should emit DOCTYPE at the root of the document', async () => { const {writable, output} = getTestWritable(); await act(() => { diff --git a/packages/react-server/src/ReactFizzServer.js b/packages/react-server/src/ReactFizzServer.js index a0388968e82..a159771421b 100644 --- a/packages/react-server/src/ReactFizzServer.js +++ b/packages/react-server/src/ReactFizzServer.js @@ -4335,6 +4335,7 @@ function finishedTask( boundary: Root | SuspenseBoundary, segment: null | Segment, ) { + request.allPendingTasks--; if (boundary === null) { if (segment !== null && segment.parentFlushed) { if (request.completedRootSegment !== null) { @@ -4417,7 +4418,6 @@ function finishedTask( } } - request.allPendingTasks--; if (request.allPendingTasks === 0) { completeAll(request); }