Skip to content

Commit

Permalink
Add wrapper around the ServerFormatConfig for legacy mode
Browse files Browse the repository at this point in the history
This ensures that we can inject custom overrides without negatively
affecting the new implementation.

This adds another field for static mark up for example.
  • Loading branch information
sebmarkbage committed Jun 14, 2021
1 parent 3a6ec70 commit 14a6de4
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 21 deletions.
4 changes: 2 additions & 2 deletions packages/react-dom/src/server/ReactDOMLegacyServerBrowser.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
import {
createResponseState,
createRootFormatContext,
} from './ReactDOMServerFormatConfig';
} from './ReactDOMServerLegacyFormatConfig';

type ServerOptions = {
identifierPrefix?: string,
Expand Down Expand Up @@ -59,7 +59,7 @@ function renderToString(
const request = createRequest(
children,
destination,
createResponseState(options ? options.identifierPrefix : undefined),
createResponseState(false, options ? options.identifierPrefix : undefined),
createRootFormatContext(undefined),
Infinity,
onError,
Expand Down
4 changes: 2 additions & 2 deletions packages/react-dom/src/server/ReactDOMLegacyServerNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
import {
createResponseState,
createRootFormatContext,
} from './ReactDOMServerFormatConfig';
} from './ReactDOMServerLegacyFormatConfig';

import {
version,
Expand Down Expand Up @@ -77,7 +77,7 @@ function renderToNodeStream(
const request = createRequest(
children,
destination,
createResponseState(options ? options.identifierPrefix : undefined),
createResponseState(false, options ? options.identifierPrefix : undefined),
createRootFormatContext(undefined),
Infinity,
onError,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ export type Destination = {
export type PrecomputedChunk = string;
export type Chunk = string;

export const isPrimaryStreamConfig = false;

export function scheduleWork(callback: () => void) {
callback();
}
Expand Down
17 changes: 9 additions & 8 deletions packages/react-dom/src/server/ReactDOMServerFormatConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
writeChunk,
stringToChunk,
stringToPrecomputedChunk,
isPrimaryStreamConfig,
} from 'react-server/src/ReactServerStreamConfig';

import {
Expand Down Expand Up @@ -51,7 +50,7 @@ import isArray from 'shared/isArray';

// Used to distinguish these contexts from ones used in other renderers.
// E.g. this can be used to distinguish legacy renderers from this modern one.
export const isPrimaryRenderer = isPrimaryStreamConfig;
export const isPrimaryRenderer = true;

// Per response, global state that is not contextual to the rendering subtree.
export type ResponseState = {
Expand All @@ -63,18 +62,20 @@ export type ResponseState = {
nextOpaqueID: number,
sentCompleteSegmentFunction: boolean,
sentCompleteBoundaryFunction: boolean,
sentClientRenderFunction: boolean,
sentClientRenderFunction: boolean, // We allow the legacy renderer to extend this object.
...
};

// Allows us to keep track of what we've already written so we can refer back to it.
export function createResponseState(
identifierPrefix: string = '',
identifierPrefix: string | void,
): ResponseState {
const idPrefix = identifierPrefix === undefined ? '' : identifierPrefix;
return {
placeholderPrefix: stringToPrecomputedChunk(identifierPrefix + 'P:'),
segmentPrefix: stringToPrecomputedChunk(identifierPrefix + 'S:'),
boundaryPrefix: identifierPrefix + 'B:',
opaqueIdentifierPrefix: identifierPrefix + 'R:',
placeholderPrefix: stringToPrecomputedChunk(idPrefix + 'P:'),
segmentPrefix: stringToPrecomputedChunk(idPrefix + 'S:'),
boundaryPrefix: idPrefix + 'B:',
opaqueIdentifierPrefix: idPrefix + 'R:',
nextSuspenseID: 0,
nextOpaqueID: 0,
sentCompleteSegmentFunction: false,
Expand Down
77 changes: 77 additions & 0 deletions packages/react-dom/src/server/ReactDOMServerLegacyFormatConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* Copyright (c) Facebook, Inc. and its 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 {createResponseState as createResponseStateImpl} from './ReactDOMServerFormatConfig';

import type {PrecomputedChunk} from 'react-server/src/ReactServerStreamConfig';

export const isPrimaryRenderer = false;

export type ResponseState = {
// Keep this in sync with ReactDOMServerFormatConfig
placeholderPrefix: PrecomputedChunk,
segmentPrefix: PrecomputedChunk,
boundaryPrefix: string,
opaqueIdentifierPrefix: string,
nextSuspenseID: number,
nextOpaqueID: number,
sentCompleteSegmentFunction: boolean,
sentCompleteBoundaryFunction: boolean,
sentClientRenderFunction: boolean,
// This is an extra field for the legacy renderer
generateStaticMarkup: boolean,
};

export function createResponseState(
generateStaticMarkup: boolean,
identifierPrefix: string | void,
): ResponseState {
const responseState = createResponseStateImpl(identifierPrefix);
return {
// Keep this in sync with ReactDOMServerFormatConfig
placeholderPrefix: responseState.placeholderPrefix,
segmentPrefix: responseState.segmentPrefix,
boundaryPrefix: responseState.boundaryPrefix,
opaqueIdentifierPrefix: responseState.opaqueIdentifierPrefix,
nextSuspenseID: responseState.nextSuspenseID,
nextOpaqueID: responseState.nextOpaqueID,
sentCompleteSegmentFunction: responseState.sentCompleteSegmentFunction,
sentCompleteBoundaryFunction: responseState.sentCompleteBoundaryFunction,
sentClientRenderFunction: responseState.sentClientRenderFunction,
// This is an extra field for the legacy renderer
generateStaticMarkup,
};
}

export type {
FormatContext,
SuspenseBoundaryID,
OpaqueIDType,
} from './ReactDOMServerFormatConfig';

export {
createRootFormatContext,
getChildFormatContext,
createSuspenseBoundaryID,
makeServerID,
pushEmpty,
pushTextInstance,
pushStartInstance,
pushEndInstance,
writePlaceholder,
writeStartCompletedSuspenseBoundary,
writeStartPendingSuspenseBoundary,
writeStartClientRenderedSuspenseBoundary,
writeEndSuspenseBoundary,
writeStartSegment,
writeEndSegment,
writeCompletedSegmentInstruction,
writeCompletedBoundaryInstruction,
writeClientRenderBoundaryInstruction,
} from './ReactDOMServerFormatConfig';
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ export type Destination = {
export type PrecomputedChunk = string;
export type Chunk = string;

export const isPrimaryStreamConfig = true;

export function scheduleWork(callback: () => void) {
// We don't schedule work in this model, and instead expect performWork to always be called repeatedly.
}
Expand Down
2 changes: 0 additions & 2 deletions packages/react-server/src/ReactServerStreamConfigBrowser.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ export type Destination = ReadableStreamController;
export type PrecomputedChunk = Uint8Array;
export type Chunk = Uint8Array;

export const isPrimaryStreamConfig = true;

export function scheduleWork(callback: () => void) {
callback();
}
Expand Down
2 changes: 0 additions & 2 deletions packages/react-server/src/ReactServerStreamConfigNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ export type Destination = Writable & MightBeFlushable;
export type PrecomputedChunk = Uint8Array;
export type Chunk = string;

export const isPrimaryStreamConfig = true;

export function scheduleWork(callback: () => void) {
setImmediate(callback);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
* @flow
*/

export * from 'react-dom/src/server/ReactDOMServerFormatConfig';
export * from 'react-dom/src/server/ReactDOMServerLegacyFormatConfig';

0 comments on commit 14a6de4

Please sign in to comment.