Skip to content

[Float][Flight] Flight support for Float #26502

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions packages/react-client/src/ReactFlightClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ import type {
SSRManifest,
} from './ReactFlightClientConfig';

import type {HintModel} from 'react-server/src/ReactFlightServerConfig';

import {
resolveClientReference,
preloadModule,
requireModule,
parseModel,
dispatchHint,
} from './ReactFlightClientConfig';

import {knownServerReferences} from './ReactFlightServerReferenceRegistry';
Expand Down Expand Up @@ -778,6 +781,15 @@ export function resolveErrorDev(
}
}

export function resolveHint(
response: Response,
code: string,
model: UninitializedModel,
): void {
const hintModel = parseModel<HintModel>(response, model);
dispatchHint(code, hintModel);
}

export function close(response: Response): void {
// In case there are any remaining unresolved chunks, they won't
// be resolved now. So we need to issue an error to those.
Expand Down
6 changes: 6 additions & 0 deletions packages/react-client/src/ReactFlightClientStream.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
resolveModel,
resolveErrorProd,
resolveErrorDev,
resolveHint,
createResponse as createResponseBase,
parseModelString,
parseModelTuple,
Expand Down Expand Up @@ -46,6 +47,11 @@ function processFullRow(response: Response, row: string): void {
resolveModule(response, id, row.slice(colon + 2));
return;
}
case 'H': {
const code = row[colon + 2];
resolveHint(response, code, row.slice(colon + 3));
return;
}
case 'E': {
const errorInfo = JSON.parse(row.slice(colon + 2));
if (__DEV__) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const resolveClientReference = $$$config.resolveClientReference;
export const resolveServerReference = $$$config.resolveServerReference;
export const preloadModule = $$$config.preloadModule;
export const requireModule = $$$config.requireModule;
export const dispatchHint = $$$config.dispatchHint;

export opaque type Source = mixed;

Expand Down
20 changes: 9 additions & 11 deletions packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* @flow
*/

import type {HostDispatcher} from 'react-dom/src/ReactDOMDispatcher';
import type {EventPriority} from 'react-reconciler/src/ReactEventPriorities';
import type {DOMEventName} from '../events/DOMEventNames';
import type {Fiber, FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
Expand Down Expand Up @@ -1868,10 +1869,6 @@ export function clearSingleton(instance: Instance): void {

export const supportsResources = true;

// The resource types we support. currently they match the form for the as argument.
// In the future this may need to change, especially when modules / scripts are supported
type ResourceType = 'style' | 'font' | 'script';

type HoistableTagType = 'link' | 'meta' | 'title';
type TResource<
T: 'stylesheet' | 'style' | 'script' | 'void',
Expand Down Expand Up @@ -1962,7 +1959,7 @@ function getDocumentFromRoot(root: HoistableRoot): Document {
// We want this to be the default dispatcher on ReactDOMSharedInternals but we don't want to mutate
// internals in Module scope. Instead we export it and Internals will import it. There is already a cycle
// from Internals -> ReactDOM -> HostConfig -> Internals so this doesn't introduce a new one.
export const ReactDOMClientDispatcher = {
export const ReactDOMClientDispatcher: HostDispatcher = {
prefetchDNS,
preconnect,
preload,
Expand Down Expand Up @@ -2036,7 +2033,10 @@ function prefetchDNS(href: string, options?: mixed) {
preconnectAs('dns-prefetch', null, href);
}

function preconnect(href: string, options?: {crossOrigin?: string}) {
function preconnect(href: string, options: ?{crossOrigin?: string}) {
if (!enableFloat) {
return;
}
if (__DEV__) {
if (typeof href !== 'string' || !href) {
console.error(
Expand Down Expand Up @@ -2064,9 +2064,8 @@ function preconnect(href: string, options?: {crossOrigin?: string}) {
preconnectAs('preconnect', crossOrigin, href);
}

type PreloadAs = ResourceType;
type PreloadOptions = {
as: PreloadAs,
as: string,
crossOrigin?: string,
integrity?: string,
type?: string,
Expand Down Expand Up @@ -2115,7 +2114,7 @@ function preload(href: string, options: PreloadOptions) {

function preloadPropsFromPreloadOptions(
href: string,
as: ResourceType,
as: string,
options: PreloadOptions,
): PreloadProps {
return {
Expand All @@ -2128,9 +2127,8 @@ function preloadPropsFromPreloadOptions(
};
}

type PreinitAs = 'style' | 'script';
type PreinitOptions = {
as: PreinitAs,
as: string,
precedence?: string,
crossOrigin?: string,
integrity?: string,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import type {
HostDispatcher,
PrefetchDNSOptions,
PreconnectOptions,
PreloadOptions,
PreinitOptions,
} from 'react-dom/src/ReactDOMDispatcher';

import {enableFloat} from 'shared/ReactFeatureFlags';

import {
emitHint,
getHints,
resolveRequest,
} from 'react-server/src/ReactFlightServer';

export const ReactDOMFlightServerDispatcher: HostDispatcher = {
prefetchDNS,
preconnect,
preload,
preinit,
};

function prefetchDNS(href: string, options?: ?PrefetchDNSOptions) {
if (enableFloat) {
if (typeof href === 'string') {
const request = resolveRequest();
if (request) {
const hints = getHints(request);
const key = 'D' + href;
if (hints.has(key)) {
// duplicate hint
return;
}
hints.add(key);
if (options) {
emitHint(request, 'D', [href, options]);
} else {
emitHint(request, 'D', href);
}
}
}
}
}

function preconnect(href: string, options: ?PreconnectOptions) {
if (enableFloat) {
if (typeof href === 'string') {
const request = resolveRequest();
if (request) {
const hints = getHints(request);
const crossOrigin =
options == null || typeof options.crossOrigin !== 'string'
? null
: options.crossOrigin === 'use-credentials'
? 'use-credentials'
: '';

const key = `C${crossOrigin === null ? 'null' : crossOrigin}|${href}`;
if (hints.has(key)) {
// duplicate hint
return;
}
hints.add(key);
if (options) {
emitHint(request, 'C', [href, options]);
} else {
emitHint(request, 'C', href);
}
}
}
}
}

function preload(href: string, options: PreloadOptions) {
if (enableFloat) {
if (typeof href === 'string') {
const request = resolveRequest();
if (request) {
const hints = getHints(request);
const key = 'L' + href;
if (hints.has(key)) {
// duplicate hint
return;
}
hints.add(key);
emitHint(request, 'L', [href, options]);
}
}
}
}

function preinit(href: string, options: PreinitOptions) {
if (enableFloat) {
if (typeof href === 'string') {
const request = resolveRequest();
if (request) {
const hints = getHints(request);
const key = 'I' + href;
if (hints.has(key)) {
// duplicate hint
return;
}
hints.add(key);
emitHint(request, 'I', [href, options]);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ export function scheduleWork(callback: () => void) {

export function flushBuffered(destination: Destination) {}

export const supportsRequestStorage = false;
export const requestStorage: AsyncLocalStorage<any> = (null: any);

export function beginWriting(destination: Destination) {}

export function writeChunk(
Expand Down
Loading