Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a1019fe

Browse files
committed
[Fizz] Support onHeadersReady option for renderTo... functions
During a render it can be useful to emit headers to start the process of preloading without waiting for the shell to complete. If provided an `onHeadersReady` callback option Fizz will call this callback with some headers. Currently this is implemented as a set of preload link headers that are generated during the first performWork pass. After this pass preloads are handled as they were preious to this change and emitted as tags. Since headers are not streamed typically we are choosing an API that provides headers once. Because of this we need to choose a point at which to provide headers once even if we could in theory wait longer to accumulate more. It is possible that a better API is to allow the caller to tell Fizz when it wants whatever headers have accumulated however in practice this would require having some secondary header outside of react that is blocking sending headers and that is considered not a likely ocurrence In this commit we add the option to pass `onHeadersReady` to static and dynamic render entrypoints. This is not yet wired up to anything so it will never be called. This will be added in a subsequent commit.
1 parent 9f37d93 commit a1019fe

File tree

8 files changed

+93
-6
lines changed

8 files changed

+93
-6
lines changed

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
* @flow
88
*/
99

10-
import type {PostponedState} from 'react-server/src/ReactFizzServer';
10+
import type {
11+
PostponedState,
12+
HeadersDescriptor,
13+
} from 'react-server/src/ReactFizzServer';
1114
import type {ReactNodeList, ReactFormState} from 'shared/ReactTypes';
1215
import type {BootstrapScriptDescriptor} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
1316
import type {ImportMap} from '../shared/ReactDOMTypes';
@@ -44,6 +47,7 @@ type Options = {
4447
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
4548
importMap?: ImportMap,
4649
formState?: ReactFormState<any, any> | null,
50+
onHeaders?: (headers: Headers) => void,
4751
};
4852

4953
type ResumeOptions = {
@@ -97,6 +101,15 @@ function renderToReadableStream(
97101
allReady.catch(() => {});
98102
reject(error);
99103
}
104+
105+
const onHeaders = options ? options.onHeaders : undefined;
106+
let onHeadersImpl;
107+
if (onHeaders) {
108+
onHeadersImpl = (headersDescriptor: HeadersDescriptor) => {
109+
onHeaders(new Headers(headersDescriptor));
110+
};
111+
}
112+
100113
const resumableState = createResumableState(
101114
options ? options.identifierPrefix : undefined,
102115
options ? options.unstable_externalRuntimeSrc : undefined,
@@ -122,6 +135,7 @@ function renderToReadableStream(
122135
onFatalError,
123136
options ? options.onPostpone : undefined,
124137
options ? options.formState : undefined,
138+
onHeadersImpl,
125139
);
126140
if (options && options.signal) {
127141
const signal = options.signal;

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* @flow
88
*/
99

10+
import type {HeadersDescriptor} from 'react-server/src/ReactFizzServer';
1011
import type {ReactNodeList, ReactFormState} from 'shared/ReactTypes';
1112
import type {BootstrapScriptDescriptor} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
1213
import type {ImportMap} from '../shared/ReactDOMTypes';
@@ -41,6 +42,7 @@ type Options = {
4142
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
4243
importMap?: ImportMap,
4344
formState?: ReactFormState<any, any> | null,
45+
onHeaders?: (headers: Headers) => void,
4446
};
4547

4648
// TODO: Move to sub-classing ReadableStream.
@@ -87,6 +89,15 @@ function renderToReadableStream(
8789
allReady.catch(() => {});
8890
reject(error);
8991
}
92+
93+
const onHeaders = options ? options.onHeaders : undefined;
94+
let onHeadersImpl;
95+
if (onHeaders) {
96+
onHeadersImpl = (headersDescriptor: HeadersDescriptor) => {
97+
onHeaders(new Headers(headersDescriptor));
98+
};
99+
}
100+
90101
const resumableState = createResumableState(
91102
options ? options.identifierPrefix : undefined,
92103
options ? options.unstable_externalRuntimeSrc : undefined,
@@ -112,6 +123,7 @@ function renderToReadableStream(
112123
onFatalError,
113124
options ? options.onPostpone : undefined,
114125
options ? options.formState : undefined,
126+
onHeadersImpl,
115127
);
116128
if (options && options.signal) {
117129
const signal = options.signal;

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
* @flow
88
*/
99

10-
import type {PostponedState} from 'react-server/src/ReactFizzServer';
10+
import type {
11+
PostponedState,
12+
HeadersDescriptor,
13+
} from 'react-server/src/ReactFizzServer';
1114
import type {ReactNodeList, ReactFormState} from 'shared/ReactTypes';
1215
import type {BootstrapScriptDescriptor} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
1316
import type {ImportMap} from '../shared/ReactDOMTypes';
@@ -44,6 +47,7 @@ type Options = {
4447
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
4548
importMap?: ImportMap,
4649
formState?: ReactFormState<any, any> | null,
50+
onHeaders?: (headers: Headers) => void,
4751
};
4852

4953
type ResumeOptions = {
@@ -97,6 +101,15 @@ function renderToReadableStream(
97101
allReady.catch(() => {});
98102
reject(error);
99103
}
104+
105+
const onHeaders = options ? options.onHeaders : undefined;
106+
let onHeadersImpl;
107+
if (onHeaders) {
108+
onHeadersImpl = (headersDescriptor: HeadersDescriptor) => {
109+
onHeaders(new Headers(headersDescriptor));
110+
};
111+
}
112+
100113
const resumableState = createResumableState(
101114
options ? options.identifierPrefix : undefined,
102115
options ? options.unstable_externalRuntimeSrc : undefined,
@@ -122,6 +135,7 @@ function renderToReadableStream(
122135
onFatalError,
123136
options ? options.onPostpone : undefined,
124137
options ? options.formState : undefined,
138+
onHeadersImpl,
125139
);
126140
if (options && options.signal) {
127141
const signal = options.signal;
@@ -190,6 +204,7 @@ function resume(
190204
onShellReady,
191205
onShellError,
192206
onFatalError,
207+
undefined,
193208
options ? options.onPostpone : undefined,
194209
);
195210
if (options && options.signal) {

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
* @flow
88
*/
99

10-
import type {Request, PostponedState} from 'react-server/src/ReactFizzServer';
10+
import type {
11+
Request,
12+
PostponedState,
13+
HeadersDescriptor,
14+
} from 'react-server/src/ReactFizzServer';
1115
import type {ReactNodeList, ReactFormState} from 'shared/ReactTypes';
1216
import type {Writable} from 'stream';
1317
import type {BootstrapScriptDescriptor} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
@@ -60,6 +64,7 @@ type Options = {
6064
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
6165
importMap?: ImportMap,
6266
formState?: ReactFormState<any, any> | null,
67+
onHeaders?: (headers: HeadersDescriptor) => void,
6368
};
6469

6570
type ResumeOptions = {
@@ -104,6 +109,7 @@ function createRequestImpl(children: ReactNodeList, options: void | Options) {
104109
undefined,
105110
options ? options.onPostpone : undefined,
106111
options ? options.formState : undefined,
112+
options ? options.onHeaders : undefined,
107113
);
108114
}
109115

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99

1010
import type {ReactNodeList} from 'shared/ReactTypes';
1111
import type {BootstrapScriptDescriptor} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
12-
import type {PostponedState} from 'react-server/src/ReactFizzServer';
12+
import type {
13+
PostponedState,
14+
HeadersDescriptor,
15+
} from 'react-server/src/ReactFizzServer';
1316
import type {ImportMap} from '../shared/ReactDOMTypes';
1417

1518
import ReactVersion from 'shared/ReactVersion';
@@ -41,6 +44,7 @@ type Options = {
4144
onPostpone?: (reason: string) => void,
4245
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
4346
importMap?: ImportMap,
47+
onHeaders?: (headers: Headers) => void,
4448
};
4549

4650
type StaticResult = {
@@ -77,6 +81,15 @@ function prerender(
7781
};
7882
resolve(result);
7983
}
84+
85+
const onHeaders = options ? options.onHeaders : undefined;
86+
let onHeadersImpl;
87+
if (onHeaders) {
88+
onHeadersImpl = (headersDescriptor: HeadersDescriptor) => {
89+
onHeaders(new Headers(headersDescriptor));
90+
};
91+
}
92+
8093
const resources = createResumableState(
8194
options ? options.identifierPrefix : undefined,
8295
options ? options.unstable_externalRuntimeSrc : undefined,
@@ -101,6 +114,7 @@ function prerender(
101114
undefined,
102115
onFatalError,
103116
options ? options.onPostpone : undefined,
117+
onHeadersImpl,
104118
);
105119
if (options && options.signal) {
106120
const signal = options.signal;

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99

1010
import type {ReactNodeList} from 'shared/ReactTypes';
1111
import type {BootstrapScriptDescriptor} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
12-
import type {PostponedState} from 'react-server/src/ReactFizzServer';
12+
import type {
13+
PostponedState,
14+
HeadersDescriptor,
15+
} from 'react-server/src/ReactFizzServer';
1316
import type {ImportMap} from '../shared/ReactDOMTypes';
1417

1518
import ReactVersion from 'shared/ReactVersion';
@@ -41,6 +44,7 @@ type Options = {
4144
onPostpone?: (reason: string) => void,
4245
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
4346
importMap?: ImportMap,
47+
onHeaders?: (headers: Headers) => void,
4448
};
4549

4650
type StaticResult = {
@@ -77,6 +81,14 @@ function prerender(
7781
};
7882
resolve(result);
7983
}
84+
85+
const onHeaders = options ? options.onHeaders : undefined;
86+
let onHeadersImpl;
87+
if (onHeaders) {
88+
onHeadersImpl = (headersDescriptor: HeadersDescriptor) => {
89+
onHeaders(new Headers(headersDescriptor));
90+
};
91+
}
8092
const resources = createResumableState(
8193
options ? options.identifierPrefix : undefined,
8294
options ? options.unstable_externalRuntimeSrc : undefined,
@@ -101,6 +113,7 @@ function prerender(
101113
undefined,
102114
onFatalError,
103115
options ? options.onPostpone : undefined,
116+
onHeadersImpl,
104117
);
105118
if (options && options.signal) {
106119
const signal = options.signal;

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99

1010
import type {ReactNodeList} from 'shared/ReactTypes';
1111
import type {BootstrapScriptDescriptor} from 'react-dom-bindings/src/server/ReactFizzConfigDOM';
12-
import type {PostponedState} from 'react-server/src/ReactFizzServer';
12+
import type {
13+
PostponedState,
14+
HeadersDescriptor,
15+
} from 'react-server/src/ReactFizzServer';
1316
import type {ImportMap} from '../shared/ReactDOMTypes';
1417

1518
import {Writable, Readable} from 'stream';
@@ -42,6 +45,7 @@ type Options = {
4245
onPostpone?: (reason: string) => void,
4346
unstable_externalRuntimeSrc?: string | BootstrapScriptDescriptor,
4447
importMap?: ImportMap,
48+
onHeaders?: (headers: HeadersDescriptor) => void,
4549
};
4650

4751
type StaticResult = {
@@ -110,6 +114,7 @@ function prerenderToNodeStream(
110114
undefined,
111115
onFatalError,
112116
options ? options.onPostpone : undefined,
117+
options ? options.onHeaders : undefined,
113118
);
114119
if (options && options.signal) {
115120
const signal = options.signal;

packages/react-server/src/ReactFizzServer.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,10 @@ function defaultErrorHandler(error: mixed) {
353353

354354
function noop(): void {}
355355

356+
export type HeadersDescriptor = {
357+
Link: string,
358+
};
359+
356360
export function createRequest(
357361
children: ReactNodeList,
358362
resumableState: ResumableState,
@@ -366,6 +370,7 @@ export function createRequest(
366370
onFatalError: void | ((error: mixed) => void),
367371
onPostpone: void | ((reason: string) => void),
368372
formState: void | null | ReactFormState<any, any>,
373+
onHeaders: void | ((headers: HeadersDescriptor) => void),
369374
): Request {
370375
prepareHostDispatcher();
371376
const pingedTasks: Array<Task> = [];
@@ -442,6 +447,7 @@ export function createPrerenderRequest(
442447
onShellError: void | ((error: mixed) => void),
443448
onFatalError: void | ((error: mixed) => void),
444449
onPostpone: void | ((reason: string) => void),
450+
onHeaders: void | ((headers: HeadersDescriptor) => void),
445451
): Request {
446452
const request = createRequest(
447453
children,
@@ -455,6 +461,8 @@ export function createPrerenderRequest(
455461
onShellError,
456462
onFatalError,
457463
onPostpone,
464+
undefined,
465+
onHeaders,
458466
);
459467
// Start tracking postponed holes during this render.
460468
request.trackedPostpones = {

0 commit comments

Comments
 (0)