Skip to content
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

[Flight] Make byteLengthOfChunk Optional #30130

Merged
merged 2 commits into from
Jun 28, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ export function typedArrayToBinaryChunk(
throw new Error('Not implemented.');
}

export function byteLengthOfChunk(chunk: Chunk | PrecomputedChunk): number {
throw new Error('Not implemented.');
}
export const byteLengthOfChunk:
| null
| ((chunk: Chunk | PrecomputedChunk) => number) = null;

export function byteLengthOfBinaryChunk(chunk: BinaryChunk): number {
throw new Error('Not implemented.');
Expand Down
11 changes: 11 additions & 0 deletions packages/react-html/src/__tests__/ReactHTMLClient-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ if (!__EXPERIMENTAL__) {
expect(html).toBe('<div>hello world</div>');
});

it('should be able to render a large string', async () => {
function Component() {
return <div>{'hello '.repeat(200)}world</div>;
}

const html = await ReactHTML.renderToMarkup(
React.createElement(Component),
);
expect(html).toBe('<div>' + ('hello '.repeat(200) + 'world') + '</div>');
});

it('should prefix html tags with a doctype', async () => {
const html = await ReactHTML.renderToMarkup(
<html>
Expand Down
12 changes: 12 additions & 0 deletions packages/react-html/src/__tests__/ReactHTMLServer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ if (!__EXPERIMENTAL__) {
expect(html).toBe('<div>hello world</div>');
});

it('should be able to render a large string', async () => {
function Component() {
// We can't use JSX because that's client-JSX in our tests.
return React.createElement('div', null, 'hello '.repeat(200) + 'world');
}

const html = await ReactHTML.renderToMarkup(
React.createElement(Component),
);
expect(html).toBe('<div>' + ('hello '.repeat(200) + 'world') + '</div>');
});

it('should prefix html tags with a doctype', async () => {
const html = await ReactHTML.renderToMarkup(
// We can't use JSX because that's client-JSX in our tests.
Expand Down
10 changes: 8 additions & 2 deletions packages/react-server/src/ReactFlightServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2541,7 +2541,7 @@ function renderModelDestructive(
return serializeDateFromDateJSON(value);
}
}
if (value.length >= 1024) {
if (value.length >= 1024 && byteLengthOfChunk !== null) {
// For large strings, we encode them outside the JSON payload so that we
// don't have to double encode and double parse the strings. This can also
// be more compact in case the string has a lot of escaped characters.
Expand Down Expand Up @@ -2892,6 +2892,12 @@ function emitTypedArrayChunk(
}

function emitTextChunk(request: Request, id: number, text: string): void {
if (byteLengthOfChunk === null) {
// eslint-disable-next-line react-internal/prod-error-codes
throw new Error(
'Existence of byteLengthOfChunk should have already been checked. This is a bug in React.',
);
}
request.pendingChunks++; // Extra chunk for the header.
const textChunk = stringToChunk(text);
const binaryLength = byteLengthOfChunk(textChunk);
Expand Down Expand Up @@ -3289,7 +3295,7 @@ function emitChunk(
const id = task.id;
// For certain types we have special types, we typically outlined them but
// we can emit them directly for this row instead of through an indirection.
if (typeof value === 'string') {
if (typeof value === 'string' && byteLengthOfChunk !== null) {
if (enableTaint) {
const tainted = TaintRegistryValues.get(value);
if (tainted !== undefined) {
Expand Down