Skip to content

Commit 2365024

Browse files
committed
Flight support for Float
Supporting Float methods such as ReactDOM.preload() are challenging for flight because it does not have an easy means to convey direct executions in other environments. Because the flight wire format is a JSON-like serialization that is expected to be rendered it currently only describes renderable elements. We need a way to convey a function invocation that gets run in the context of the client environment whether that is Fizz or Fiber. Fiber is somewhat straightforward because the HostDispatcher is always active and we can just have the FlightClient dispatch the serialized directive. Fizz is much more challenging becaue the dispatcher is always scoped but the specific request the dispatch belongs to is not readily available. Environments that support AsyncLocalStorage (or in the future AsyncContext) we will use this to be able to resolve directives in Fizz to the appropriate Request. For other environments directives will be elided. Right now this is pragmatic and non-breaking because all directives are opportunistic and non-critical. If this changes in the future we will need to reconsider how widespread support for async context tracking is. For Flight, if AsyncLocalStorage is available Float methods can be called before and after await points and be expected to work. If AsyncLocalStorage is not available float methods called in the sync phase of a component render will be captured but anything after an await point will be a noop. If a float call is dropped in this manner a DEV warning should help you realize your code may need to be modified.
1 parent b5934f2 commit 2365024

File tree

56 files changed

+927
-105
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+927
-105
lines changed

packages/react-client/src/ReactFlightClient.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
preloadModule,
2424
requireModule,
2525
parseModel,
26+
dispatchDirective,
2627
} from './ReactFlightClientHostConfig';
2728

2829
import {knownServerReferences} from './ReactFlightServerReferenceRegistry';
@@ -758,6 +759,15 @@ export function resolveErrorDev(
758759
}
759760
}
760761

762+
export function resolveDirective(
763+
response: Response,
764+
id: number,
765+
model: string,
766+
): void {
767+
const payload = JSON.parse(model);
768+
dispatchDirective(payload);
769+
}
770+
761771
export function close(response: Response): void {
762772
// In case there are any remaining unresolved chunks, they won't
763773
// be resolved now. So we need to issue an error to those.

packages/react-client/src/ReactFlightClientStream.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
resolveModel,
1717
resolveErrorProd,
1818
resolveErrorDev,
19+
resolveDirective,
1920
createResponse as createResponseBase,
2021
parseModelString,
2122
parseModelTuple,
@@ -46,6 +47,10 @@ function processFullRow(response: Response, row: string): void {
4647
resolveModule(response, id, row.substring(colon + 2));
4748
return;
4849
}
50+
case 'D': {
51+
resolveDirective(response, id, row.substring(colon + 2));
52+
return;
53+
}
4954
case 'E': {
5055
const errorInfo = JSON.parse(row.substring(colon + 2));
5156
if (__DEV__) {

packages/react-client/src/forks/ReactFlightClientHostConfig.custom.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const resolveClientReference = $$$hostConfig.resolveClientReference;
3535
export const resolveServerReference = $$$hostConfig.resolveServerReference;
3636
export const preloadModule = $$$hostConfig.preloadModule;
3737
export const requireModule = $$$hostConfig.requireModule;
38+
export const dispatchDirective = $$$hostConfig.dispatchDirective;
3839

3940
export opaque type Source = mixed;
4041

packages/react-client/src/forks/ReactFlightClientHostConfig.dom-browser.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
export * from 'react-client/src/ReactFlightClientHostConfigBrowser';
1111
export * from 'react-client/src/ReactFlightClientHostConfigStream';
1212
export * from 'react-server-dom-webpack/src/ReactFlightClientWebpackBundlerConfig';
13+
export * from 'react-dom-bindings/src/shared/ReactDOMFlightClientHostConfig';

packages/react-client/src/forks/ReactFlightClientHostConfig.dom-bun.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
export * from 'react-client/src/ReactFlightClientHostConfigBrowser';
1111
export * from 'react-client/src/ReactFlightClientHostConfigStream';
12+
export * from 'react-dom-bindings/src/shared/ReactDOMFlightClientHostConfig';
1213

1314
export type Response = any;
1415
export opaque type SSRManifest = mixed;

packages/react-client/src/forks/ReactFlightClientHostConfig.dom-edge-webpack.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
export * from 'react-client/src/ReactFlightClientHostConfigBrowser';
1111
export * from 'react-client/src/ReactFlightClientHostConfigStream';
1212
export * from 'react-server-dom-webpack/src/ReactFlightClientWebpackBundlerConfig';
13+
export * from 'react-dom-bindings/src/shared/ReactDOMFlightClientHostConfig';

packages/react-client/src/forks/ReactFlightClientHostConfig.dom-legacy.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
export * from 'react-client/src/ReactFlightClientHostConfigBrowser';
1111
export * from 'react-client/src/ReactFlightClientHostConfigStream';
1212
export * from 'react-server-dom-webpack/src/ReactFlightClientWebpackBundlerConfig';
13+
export * from 'react-dom-bindings/src/shared/ReactDOMFlightClientHostConfig';

packages/react-client/src/forks/ReactFlightClientHostConfig.dom-node-webpack.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
export * from 'react-client/src/ReactFlightClientHostConfigNode';
1111
export * from 'react-client/src/ReactFlightClientHostConfigStream';
1212
export * from 'react-server-dom-webpack/src/ReactFlightClientWebpackBundlerConfig';
13+
export * from 'react-dom-bindings/src/shared/ReactDOMFlightClientHostConfig';

packages/react-client/src/forks/ReactFlightClientHostConfig.dom-node.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
export * from 'react-client/src/ReactFlightClientHostConfigNode';
1111
export * from 'react-client/src/ReactFlightClientHostConfigStream';
1212
export * from 'react-server-dom-webpack/src/ReactFlightClientNodeBundlerConfig';
13+
export * from 'react-dom-bindings/src/shared/ReactDOMFlightClientHostConfig';

packages/react-client/src/forks/ReactFlightClientHostConfig.dom-relay.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99

1010
export * from 'react-server-dom-relay/src/ReactFlightDOMRelayClientHostConfig';
1111
export * from '../ReactFlightClientHostConfigNoStream';
12+
export * from 'react-dom-bindings/src/shared/ReactDOMFlightClientHostConfig';

0 commit comments

Comments
 (0)