Skip to content

Commit

Permalink
provide impl for byteLengthOfChunk via config
Browse files Browse the repository at this point in the history
  • Loading branch information
alunyov committed Nov 18, 2023
1 parent 0ebf40c commit faa9d19
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 35 deletions.
26 changes: 24 additions & 2 deletions packages/react-server-dom-fb/src/ReactFlightDOMServerFB.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
*/

import type {ReactClientValue} from 'react-server/src/ReactFlightServer';
import type {Destination} from 'react-server/src/ReactServerStreamConfig';
import type {
Destination,
Chunk,
PrecomputedChunk,
} from 'react-server/src/ReactServerStreamConfig';
import type {ClientManifest} from './ReactFlightReferencesFB';

import {
Expand All @@ -17,6 +21,8 @@ import {
startFlowing,
} from 'react-server/src/ReactFlightServer';

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

export {
registerClientReference,
registerServerReference,
Expand All @@ -34,6 +40,11 @@ function renderToDestination(
bundlerConfig: ClientManifest,
options?: Options,
): void {
if (!configured) {
throw new Error(
'Please make sure to call `setConfig(...)` before calling `renderToDestination`.',
);
}
const request = createRequest(
model,
bundlerConfig,
Expand All @@ -43,4 +54,15 @@ function renderToDestination(
startFlowing(request, destination);
}

export {renderToDestination};
type Config = {
byteLength: (chunk: Chunk | PrecomputedChunk) => number,
};

let configured = false;

function setConfig(config: Config): void {
setByteLengthOfChunkImplementation(config.byteLength);
configured = true;
}

export {renderToDestination, setConfig};
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ describe('ReactFlightDOM for FB', () => {
};

ReactServerDOMServer = require('../ReactFlightDOMServerFB');
ReactServerDOMServer.setConfig({
byteLength: str => Buffer.byteLength(str),
});

// This reset is to load modules for the SSR/Browser scope.
jest.resetModules();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,24 @@ import type {
BinaryChunk,
} from '../ReactServerStreamConfigFB';

let byteLengthImpl: null | ((chunk: Chunk | PrecomputedChunk) => number) = null;

export function setByteLengthOfChunkImplementation(
impl: (chunk: Chunk | PrecomputedChunk) => number,
): void {
byteLengthImpl = impl;
}

export function byteLengthOfChunk(chunk: Chunk | PrecomputedChunk): number {
if (typeof chunk !== 'string') {
if (byteLengthImpl == null) {
// eslint-disable-next-line react-internal/prod-error-codes
throw new Error('byteLengthOfChunk: binary chunks are not supported.');
throw new Error(
'byteLengthOfChunk implementation is not configured. Please, provide the implementation via ReactFlightDOMServer.setConfig(...);',
);
}
return byteLengthImpl(chunk);
}

// TODO: We need to replace this with native implementation, once its available on Hermes
function byteLengthImpl(chunk: string) {
/**
From: https://datatracker.ietf.org/doc/html/rfc3629
Char. number range | UTF-8 octet sequence
(hexadecimal) | (binary)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
let byteLength = chunk.length;
for (let i = chunk.length - 1; i >= 0; i--) {
const code = chunk.charCodeAt(i);
if (code > 0x7f && code <= 0x7ff) {
byteLength++;
} else if (code > 0x7ff && code <= 0xffff) {
byteLength += 2;
}
if (code >= 0xdc00 && code <= 0xdfff) {
// It is a trail surrogate character.
// In this case, the code decrements the loop counter i so
// that the previous character (which should be a lead surrogate character)
// is also included in the calculation.
i--;
}
}
return byteLength;
}

export interface Destination {
beginWriting(): void;
write(chunk: Chunk | PrecomputedChunk | BinaryChunk): void;
Expand Down

0 comments on commit faa9d19

Please sign in to comment.