Skip to content

Commit c256a81

Browse files
committed
Expose an explicit point when to start writing in the Node API
1 parent 5d8cdc8 commit c256a81

File tree

5 files changed

+33
-10
lines changed

5 files changed

+33
-10
lines changed

packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,14 +196,15 @@ describe('ReactDOMFizzServer', () => {
196196
// @gate experimental
197197
it('should asynchronously load the suspense boundary', async () => {
198198
await act(async () => {
199-
ReactDOMFizzServer.pipeToNodeWritable(
199+
const {startWriting} = ReactDOMFizzServer.pipeToNodeWritable(
200200
<div>
201201
<Suspense fallback={<Text text="Loading..." />}>
202202
<AsyncText text="Hello World" />
203203
</Suspense>
204204
</div>,
205205
writable,
206206
);
207+
startWriting();
207208
});
208209
expect(getVisibleChildren(container)).toEqual(<div>Loading...</div>);
209210
await act(async () => {
@@ -229,7 +230,11 @@ describe('ReactDOMFizzServer', () => {
229230
}
230231

231232
await act(async () => {
232-
ReactDOMFizzServer.pipeToNodeWritable(<App />, writable);
233+
const {startWriting} = ReactDOMFizzServer.pipeToNodeWritable(
234+
<App />,
235+
writable,
236+
);
237+
startWriting();
233238
});
234239

235240
// We're still showing a fallback.
@@ -281,6 +286,7 @@ describe('ReactDOMFizzServer', () => {
281286
let controls;
282287
await act(async () => {
283288
controls = ReactDOMFizzServer.pipeToNodeWritable(<App />, writable);
289+
controls.startWriting();
284290
});
285291

286292
// We're still showing a fallback.

packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,11 @@ describe('ReactDOMFizzServer', () => {
5959
// @gate experimental
6060
it('should call pipeToNodeWritable', () => {
6161
const {writable, output} = getTestWritable();
62-
ReactDOMFizzServer.pipeToNodeWritable(<div>hello world</div>, writable);
62+
const {startWriting} = ReactDOMFizzServer.pipeToNodeWritable(
63+
<div>hello world</div>,
64+
writable,
65+
);
66+
startWriting();
6367
jest.runAllTimers();
6468
expect(output.result).toBe('<div>hello world</div>');
6569
});
@@ -74,6 +78,8 @@ describe('ReactDOMFizzServer', () => {
7478
writable,
7579
);
7680

81+
// The stream is errored even if we haven't started writing.
82+
7783
await completed;
7884

7985
expect(output.error).toBe(theError);
@@ -83,14 +89,15 @@ describe('ReactDOMFizzServer', () => {
8389
// @gate experimental
8490
it('should error the stream when an error is thrown inside a fallback', async () => {
8591
const {writable, output, completed} = getTestWritable();
86-
ReactDOMFizzServer.pipeToNodeWritable(
92+
const {startWriting} = ReactDOMFizzServer.pipeToNodeWritable(
8793
<div>
8894
<Suspense fallback={<Throw />}>
8995
<InfiniteSuspend />
9096
</Suspense>
9197
</div>,
9298
writable,
9399
);
100+
startWriting();
94101

95102
await completed;
96103

@@ -101,14 +108,15 @@ describe('ReactDOMFizzServer', () => {
101108
// @gate experimental
102109
it('should not error the stream when an error is thrown inside suspense boundary', async () => {
103110
const {writable, output, completed} = getTestWritable();
104-
ReactDOMFizzServer.pipeToNodeWritable(
111+
const {startWriting} = ReactDOMFizzServer.pipeToNodeWritable(
105112
<div>
106113
<Suspense fallback={<div>Loading</div>}>
107114
<Throw />
108115
</Suspense>
109116
</div>,
110117
writable,
111118
);
119+
startWriting();
112120

113121
await completed;
114122

@@ -128,12 +136,13 @@ describe('ReactDOMFizzServer', () => {
128136
function Content() {
129137
return 'Hi';
130138
}
131-
ReactDOMFizzServer.pipeToNodeWritable(
139+
const {startWriting} = ReactDOMFizzServer.pipeToNodeWritable(
132140
<Suspense fallback={<Fallback />}>
133141
<Content />
134142
</Suspense>,
135143
writable,
136144
);
145+
startWriting();
137146

138147
await completed;
139148

@@ -145,14 +154,15 @@ describe('ReactDOMFizzServer', () => {
145154
// @gate experimental
146155
it('should be able to complete by aborting even if the promise never resolves', async () => {
147156
const {writable, output, completed} = getTestWritable();
148-
const {abort} = ReactDOMFizzServer.pipeToNodeWritable(
157+
const {startWriting, abort} = ReactDOMFizzServer.pipeToNodeWritable(
149158
<div>
150159
<Suspense fallback={<div>Loading</div>}>
151160
<InfiniteSuspend />
152161
</Suspense>
153162
</div>,
154163
writable,
155164
);
165+
startWriting();
156166

157167
jest.runAllTimers();
158168

packages/react-dom/src/server/ReactDOMFizzServerNode.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,17 @@ function pipeToNodeWritable(
3232
destination: Writable,
3333
): Controls {
3434
const request = createRequest(children, destination);
35-
destination.on('drain', createDrainHandler(destination, request));
35+
let hasStartedFlowing = false;
3636
startWork(request);
3737
return {
38+
startWriting() {
39+
if (hasStartedFlowing) {
40+
return;
41+
}
42+
hasStartedFlowing = true;
43+
startFlowing(request);
44+
destination.on('drain', createDrainHandler(destination, request));
45+
},
3846
abort() {
3947
abort(request);
4048
},

packages/react-noop-renderer/src/ReactNoopServer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ function render(children: React$Element<any>): Destination {
222222
};
223223
const request = ReactNoopServer.createRequest(children, destination);
224224
ReactNoopServer.startWork(request);
225+
ReactNoopServer.startFlowing(request);
225226
return destination;
226227
}
227228

packages/react-server/src/ReactFizzServer.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -894,8 +894,6 @@ function flushCompletedQueues(request: Request): void {
894894
// This would put all waiting boundaries into client-only mode.
895895

896896
export function startWork(request: Request): void {
897-
// TODO: Don't automatically start flowing. Expose an explicit signal. Auto-start once everything is done.
898-
request.status = FLOWING;
899897
scheduleWork(() => performWork(request));
900898
}
901899

0 commit comments

Comments
 (0)