Skip to content

Commit faa9d19

Browse files
committed
provide impl for byteLengthOfChunk via config
1 parent 0ebf40c commit faa9d19

File tree

3 files changed

+39
-35
lines changed

3 files changed

+39
-35
lines changed

packages/react-server-dom-fb/src/ReactFlightDOMServerFB.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
*/
99

1010
import type {ReactClientValue} from 'react-server/src/ReactFlightServer';
11-
import type {Destination} from 'react-server/src/ReactServerStreamConfig';
11+
import type {
12+
Destination,
13+
Chunk,
14+
PrecomputedChunk,
15+
} from 'react-server/src/ReactServerStreamConfig';
1216
import type {ClientManifest} from './ReactFlightReferencesFB';
1317

1418
import {
@@ -17,6 +21,8 @@ import {
1721
startFlowing,
1822
} from 'react-server/src/ReactFlightServer';
1923

24+
import {setByteLengthOfChunkImplementation} from 'react-server/src/ReactServerStreamConfig';
25+
2026
export {
2127
registerClientReference,
2228
registerServerReference,
@@ -34,6 +40,11 @@ function renderToDestination(
3440
bundlerConfig: ClientManifest,
3541
options?: Options,
3642
): void {
43+
if (!configured) {
44+
throw new Error(
45+
'Please make sure to call `setConfig(...)` before calling `renderToDestination`.',
46+
);
47+
}
3748
const request = createRequest(
3849
model,
3950
bundlerConfig,
@@ -43,4 +54,15 @@ function renderToDestination(
4354
startFlowing(request, destination);
4455
}
4556

46-
export {renderToDestination};
57+
type Config = {
58+
byteLength: (chunk: Chunk | PrecomputedChunk) => number,
59+
};
60+
61+
let configured = false;
62+
63+
function setConfig(config: Config): void {
64+
setByteLengthOfChunkImplementation(config.byteLength);
65+
configured = true;
66+
}
67+
68+
export {renderToDestination, setConfig};

packages/react-server-dom-fb/src/__tests__/ReactFlightDOMServerFB-test.internal.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ describe('ReactFlightDOM for FB', () => {
8989
};
9090

9191
ReactServerDOMServer = require('../ReactFlightDOMServerFB');
92+
ReactServerDOMServer.setConfig({
93+
byteLength: str => Buffer.byteLength(str),
94+
});
9295

9396
// This reset is to load modules for the SSR/Browser scope.
9497
jest.resetModules();

packages/react-server/src/forks/ReactServerStreamConfig.dom-fb-experimental.js

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,45 +15,24 @@ import type {
1515
BinaryChunk,
1616
} from '../ReactServerStreamConfigFB';
1717

18+
let byteLengthImpl: null | ((chunk: Chunk | PrecomputedChunk) => number) = null;
19+
20+
export function setByteLengthOfChunkImplementation(
21+
impl: (chunk: Chunk | PrecomputedChunk) => number,
22+
): void {
23+
byteLengthImpl = impl;
24+
}
25+
1826
export function byteLengthOfChunk(chunk: Chunk | PrecomputedChunk): number {
19-
if (typeof chunk !== 'string') {
27+
if (byteLengthImpl == null) {
2028
// eslint-disable-next-line react-internal/prod-error-codes
21-
throw new Error('byteLengthOfChunk: binary chunks are not supported.');
29+
throw new Error(
30+
'byteLengthOfChunk implementation is not configured. Please, provide the implementation via ReactFlightDOMServer.setConfig(...);',
31+
);
2232
}
2333
return byteLengthImpl(chunk);
2434
}
2535

26-
// TODO: We need to replace this with native implementation, once its available on Hermes
27-
function byteLengthImpl(chunk: string) {
28-
/**
29-
From: https://datatracker.ietf.org/doc/html/rfc3629
30-
Char. number range | UTF-8 octet sequence
31-
(hexadecimal) | (binary)
32-
--------------------+---------------------------------------------
33-
0000 0000-0000 007F | 0xxxxxxx
34-
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
35-
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
36-
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
37-
*/
38-
let byteLength = chunk.length;
39-
for (let i = chunk.length - 1; i >= 0; i--) {
40-
const code = chunk.charCodeAt(i);
41-
if (code > 0x7f && code <= 0x7ff) {
42-
byteLength++;
43-
} else if (code > 0x7ff && code <= 0xffff) {
44-
byteLength += 2;
45-
}
46-
if (code >= 0xdc00 && code <= 0xdfff) {
47-
// It is a trail surrogate character.
48-
// In this case, the code decrements the loop counter i so
49-
// that the previous character (which should be a lead surrogate character)
50-
// is also included in the calculation.
51-
i--;
52-
}
53-
}
54-
return byteLength;
55-
}
56-
5736
export interface Destination {
5837
beginWriting(): void;
5938
write(chunk: Chunk | PrecomputedChunk | BinaryChunk): void;

0 commit comments

Comments
 (0)