Add Relay Flight Build (#18242)
* Rename to clarify that it's client-only * Rename FizzStreamer to FizzServer for consistency * Rename react-flight to react-client/flight For consistency with react-server. Currently this just includes flight but it could be expanded to include the whole reconciler. * Add Relay Flight Build * Rename ReactServerHostConfig to ReactServerStreamConfig This will be the config specifically for streaming purposes. There will be other configs for other purposes.
Sebastian Markbåge committed
Mar 7, 2020 at 11:23 UTC
bdc5cc4635f13e5ca43883a9f9587fc9a868c528
45 files changed
+311
-48
packages/react-client/README.md
renamed
+1
-1
@@ -1,4 +1,4 @@
1
-# react-flight
1
+# react-client
2
3
This is an experimental package for consuming custom React streaming models.
4
packages/react-client/flight.js
renamed
packages/react-client/npm/flight.js
new
+7
@@ -0,0 +1,7 @@
1
+'use strict';
2
+
3
+if (process.env.NODE_ENV === 'production') {
4
+ module.exports = require('./cjs/react-client-flight.production.min.js');
5
+} else {
6
+ module.exports = require('./cjs/react-client-flight.development.js');
7
+}
packages/react-client/package.json
renamed
+3
-4
@@ -1,5 +1,5 @@
1
{
2
- "name": "react-flight",
2
+ "name": "react-client",
3
"description": "React package for consuming streaming models.",
4
"version": "0.1.0",
5
"private": true,
@@ -12,14 +12,13 @@
12
"files": [
13
"LICENSE",
14
"README.md",
15
- "index.js",
15
+ "flight.js",
16
"cjs/"
17
],
18
- "main": "index.js",
18
"repository": {
19
"type" : "git",
20
"url" : "https://github.com/facebook/react.git",
22
- "directory": "packages/react-flight"
21
+ "directory": "packages/react-client"
22
},
23
"engines": {
24
"node": ">=0.10.0"
packages/react-client/src/ReactFlightClient.js
renamed
packages/react-client/src/ReactFlightClientHostConfig.js
renamed
packages/react-client/src/ReactFlightClientHostConfigBrowser.js
renamed
packages/react-client/src/__tests__/ReactFlight-test.js
renamed
packages/react-client/src/forks/ReactFlightClientHostConfig.custom.js
renamed
packages/react-client/src/forks/ReactFlightClientHostConfig.dom-browser.js
new
+10
@@ -0,0 +1,10 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ */
9
+
10
+export * from 'react-client/src/ReactFlightClientHostConfigBrowser';
packages/react-client/src/forks/ReactFlightClientHostConfig.dom-relay.js
new
+10
@@ -0,0 +1,10 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ */
9
+
10
+export * from 'react-flight-dom-relay/src/ReactFlightDOMRelayClientHostConfig';
packages/react-client/src/forks/ReactFlightClientHostConfig.dom.js
new
+10
@@ -0,0 +1,10 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ */
9
+
10
+export * from 'react-client/src/ReactFlightClientHostConfigBrowser';
packages/react-dom/src/server/ReactDOMFizzServerBrowser.js
+1
-1
@@ -13,7 +13,7 @@ import {
13
createRequest,
14
startWork,
15
startFlowing,
16
-} from 'react-server/src/ReactFizzStreamer';
16
+} from 'react-server/src/ReactFizzServer';
17
18
function renderToReadableStream(children: ReactNodeList): ReadableStream {
19
let request;
packages/react-dom/src/server/ReactDOMFizzServerNode.js
+1
-1
@@ -14,7 +14,7 @@ import {
14
createRequest,
15
startWork,
16
startFlowing,
17
-} from 'react-server/src/ReactFizzStreamer';
17
+} from 'react-server/src/ReactFizzServer';
18
19
function createDrainHandler(destination, request) {
20
return () => startFlowing(request);
packages/react-flight-dom-relay/index.js
renamed
+1
-1
@@ -7,4 +7,4 @@
7
* @flow
8
*/
9
10
-export * from '../ReactServerHostConfigBrowser';
10
+export * from './src/ReactFlightDOMRelayClient';
packages/react-flight-dom-relay/package.json
new
+18
@@ -0,0 +1,18 @@
1
+{
2
+ "name": "react-flight-dom-relay",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "repository": {
6
+ "type" : "git",
7
+ "url" : "https://github.com/facebook/react.git",
8
+ "directory": "packages/react-flight-dom-relay"
9
+ },
10
+ "dependencies": {
11
+ "object-assign": "^4.1.1",
12
+ "scheduler": "^0.11.0"
13
+ },
14
+ "peerDependencies": {
15
+ "react": "^16.0.0",
16
+ "react-dom": "^16.0.0"
17
+ }
18
+}
packages/react-flight-dom-relay/server.js
renamed
+1
-1
@@ -7,4 +7,4 @@
7
* @flow
8
*/
9
10
-export * from 'react-flight/src/ReactFlightHostConfigBrowser';
10
+export * from './src/ReactFlightDOMRelayServer';
packages/react-flight-dom-relay/src/ReactFlightDOMRelayClient.js
new
+30
@@ -0,0 +1,30 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ */
9
+
10
+import type {ReactModelRoot} from 'react-client/src/ReactFlightClient';
11
+
12
+import {
13
+ createResponse,
14
+ getModelRoot,
15
+ processStringChunk,
16
+ complete,
17
+} from 'react-client/src/ReactFlightClient';
18
+
19
+type EncodedData = Array<string>;
20
+
21
+function read<T>(data: EncodedData): ReactModelRoot<T> {
22
+ let response = createResponse(data);
23
+ for (let i = 0; i < data.length; i++) {
24
+ processStringChunk(response, data[i], 0);
25
+ }
26
+ complete(response);
27
+ return getModelRoot(response);
28
+}
29
+
30
+export {read};
packages/react-flight-dom-relay/src/ReactFlightDOMRelayClientHostConfig.js
new
+32
@@ -0,0 +1,32 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ */
9
+
10
+export type Source = Array<string>;
11
+
12
+export type StringDecoder = void;
13
+
14
+export const supportsBinaryStreams = false;
15
+
16
+export function createStringDecoder(): void {
17
+ throw new Error('Should never be called');
18
+}
19
+
20
+export function readPartialStringChunk(
21
+ decoder: StringDecoder,
22
+ buffer: Uint8Array,
23
+): string {
24
+ throw new Error('Should never be called');
25
+}
26
+
27
+export function readFinalStringChunk(
28
+ decoder: StringDecoder,
29
+ buffer: Uint8Array,
30
+): string {
31
+ throw new Error('Should never be called');
32
+}
packages/react-flight-dom-relay/src/ReactFlightDOMRelayServer.js
new
+23
@@ -0,0 +1,23 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ */
9
+
10
+import type {ReactModel} from 'react-server/src/ReactFlightServer';
11
+
12
+import {createRequest, startWork} from 'react-server/src/ReactFlightServer';
13
+
14
+type EncodedData = Array<string>;
15
+
16
+function render(model: ReactModel): EncodedData {
17
+ let data: EncodedData = [];
18
+ let request = createRequest(model, data);
19
+ startWork(request);
20
+ return data;
21
+}
22
+
23
+export {render};
packages/react-flight-dom-relay/src/ReactFlightDOMRelayServerHostConfig.js
new
+34
@@ -0,0 +1,34 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ */
9
+
10
+export type Destination = Array<string>;
11
+
12
+export function scheduleWork(callback: () => void) {
13
+ callback();
14
+}
15
+
16
+export function flushBuffered(destination: Destination) {}
17
+
18
+export function beginWriting(destination: Destination) {}
19
+
20
+export function writeChunk(
21
+ destination: Destination,
22
+ buffer: Uint8Array,
23
+): boolean {
24
+ destination.push(Buffer.from((buffer: any)).toString('utf8'));
25
+ return true;
26
+}
27
+
28
+export function completeWriting(destination: Destination) {}
29
+
30
+export function close(destination: Destination) {}
31
+
32
+export function convertStringToBuffer(content: string): Uint8Array {
33
+ return Buffer.from(content, 'utf8');
34
+}
packages/react-flight-dom-relay/src/__tests__/ReactFlightDOMRelay-test.internal.js
new
+42
@@ -0,0 +1,42 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+'use strict';
9
+
10
+// Polyfills for test environment
11
+global.TextDecoder = require('util').TextDecoder;
12
+
13
+let React;
14
+let ReactDOMFlightRelayServer;
15
+let ReactDOMFlightRelayClient;
16
+
17
+describe('ReactFlightDOMRelay', () => {
18
+ beforeEach(() => {
19
+ jest.resetModules();
20
+
21
+ React = require('react');
22
+ ReactDOMFlightRelayServer = require('react-flight-dom-relay/server');
23
+ ReactDOMFlightRelayClient = require('react-flight-dom-relay');
24
+ });
25
+
26
+ it('can resolve a model', () => {
27
+ function Bar({text}) {
28
+ return text.toUpperCase();
29
+ }
30
+ function Foo() {
31
+ return {
32
+ bar: [<Bar text="a" />, <Bar text="b" />],
33
+ };
34
+ }
35
+ let data = ReactDOMFlightRelayServer.render({
36
+ foo: <Foo />,
37
+ });
38
+ let root = ReactDOMFlightRelayClient.read(data);
39
+ let model = root.model;
40
+ expect(model).toEqual({foo: {bar: ['A', 'B']}});
41
+ });
42
+});
packages/react-flight-dom-webpack/src/ReactFlightDOMClient.js
+2
-2
@@ -7,7 +7,7 @@
7
* @flow
8
*/
9
10
-import type {ReactModelRoot} from 'react-flight/src/ReactFlightClient';
10
+import type {ReactModelRoot} from 'react-client/src/ReactFlightClient';
11
12
import {
13
createResponse,
@@ -16,7 +16,7 @@ import {
16
processStringChunk,
17
processBinaryChunk,
18
complete,
19
-} from 'react-flight/src/ReactFlightClient';
19
+} from 'react-client/src/ReactFlightClient';
20
21
function startReadingFromStream(response, stream: ReadableStream): void {
22
let reader = stream.getReader();
packages/react-flight/npm/index.js
deleted
-7
@@ -1,7 +0,0 @@
1
-'use strict';
2
-
3
-if (process.env.NODE_ENV === 'production') {
4
- module.exports = require('./cjs/react-flight.production.min.js');
5
-} else {
6
- module.exports = require('./cjs/react-flight.development.js');
7
-}
packages/react-noop-renderer/package.json
+1
-1
@@ -14,7 +14,7 @@
14
"object-assign": "^4.1.1",
15
"regenerator-runtime": "^0.11.0",
16
"react-reconciler": "*",
17
- "react-flight": "*",
17
+ "react-client": "*",
18
"react-server": "*"
19
},
20
"peerDependencies": {
packages/react-noop-renderer/src/ReactNoopFlightClient.js
+2
-2
@@ -14,9 +14,9 @@
14
* environment.
15
*/
16
17
-import type {ReactModelRoot} from 'react-flight';
17
+import type {ReactModelRoot} from 'react-client/flight';
18
19
-import ReactFlightClient from 'react-flight';
19
+import ReactFlightClient from 'react-client/flight';
20
21
type Source = Array<string>;
22
packages/react-noop-renderer/src/ReactNoopServer.js
+2
-2
@@ -14,11 +14,11 @@
14
* environment.
15
*/
16
17
-import ReactFizzStreamer from 'react-server';
17
+import ReactFizzServer from 'react-server';
18
19
type Destination = Array<string>;
20
21
-const ReactNoopServer = ReactFizzStreamer({
21
+const ReactNoopServer = ReactFizzServer({
22
scheduleWork(callback: () => void) {
23
callback();
24
},
packages/react-reconciler/src/forks/ReactFiberHostConfig.dom-relay.js
renamed
+1
-1
@@ -7,4 +7,4 @@
7
* @flow
8
*/
9
10
-export * from 'react-flight/src/ReactFlightHostConfigBrowser';
10
+export * from 'react-dom/src/client/ReactDOMHostConfig';
packages/react-server/index.js
+1
-1
@@ -7,4 +7,4 @@
7
* @flow
8
*/
9
10
-export * from './src/ReactFizzStreamer';
10
+export * from './src/ReactFizzServer';
packages/react-server/src/ReactDOMServerFormatConfig.js
+1
-1
@@ -7,7 +7,7 @@
7
* @flow
8
*/
9
10
-import {convertStringToBuffer} from 'react-server/src/ReactServerHostConfig';
10
+import {convertStringToBuffer} from 'react-server/src/ReactServerStreamConfig';
11
12
import {renderToStaticMarkup} from 'react-dom/server';
13
packages/react-server/src/ReactFizzServer.js
renamed
+2
-2
@@ -7,7 +7,7 @@
7
* @flow
8
*/
9
10
-import type {Destination} from './ReactServerHostConfig';
10
+import type {Destination} from './ReactServerStreamConfig';
11
import type {ReactNodeList} from 'shared/ReactTypes';
12
13
import {
@@ -17,7 +17,7 @@ import {
17
completeWriting,
18
flushBuffered,
19
close,
20
-} from './ReactServerHostConfig';
20
+} from './ReactServerStreamConfig';
21
import {formatChunk} from './ReactServerFormatConfig';
22
import {REACT_ELEMENT_TYPE} from 'shared/ReactSymbols';
23
packages/react-server/src/ReactFlightServer.js
+2
-2
@@ -7,7 +7,7 @@
7
* @flow
8
*/
9
10
-import type {Destination} from './ReactServerHostConfig';
10
+import type {Destination} from './ReactServerStreamConfig';
11
12
import {
13
scheduleWork,
@@ -17,7 +17,7 @@ import {
17
flushBuffered,
18
close,
19
convertStringToBuffer,
20
-} from './ReactServerHostConfig';
20
+} from './ReactServerStreamConfig';
21
import {renderHostChildrenToString} from './ReactServerFormatConfig';
22
import {REACT_ELEMENT_TYPE} from 'shared/ReactSymbols';
23
packages/react-server/src/ReactServerStreamConfig.js
renamed
packages/react-server/src/ReactServerStreamConfigBrowser.js
renamed
packages/react-server/src/ReactServerStreamConfigNode.js
renamed
packages/react-server/src/forks/ReactServerFormatConfig.dom-relay.js
renamed
+1
-1
@@ -7,4 +7,4 @@
7
* @flow
8
*/
9
10
-export * from '../ReactServerHostConfigNode';
10
+export * from '../ReactDOMServerFormatConfig';
packages/react-server/src/forks/ReactServerStreamConfig.custom.js
renamed
packages/react-server/src/forks/ReactServerStreamConfig.dom-browser.js
new
+10
@@ -0,0 +1,10 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ */
9
+
10
+export * from '../ReactServerStreamConfigBrowser';
packages/react-server/src/forks/ReactServerStreamConfig.dom-relay.js
new
+10
@@ -0,0 +1,10 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ */
9
+
10
+export * from 'react-flight-dom-relay/src/ReactFlightDOMRelayServerHostConfig';
packages/react-server/src/forks/ReactServerStreamConfig.dom.js
new
+10
@@ -0,0 +1,10 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ */
9
+
10
+export * from '../ReactServerStreamConfigNode';
scripts/flow/createFlowConfigs.js
+1
-1
@@ -49,7 +49,7 @@ function writeConfig(renderer, rendererInfo, isServerSupported) {
49
'%REACT_RENDERER_FLOW_OPTIONS%',
50
`
51
module.name_mapper='ReactFiberHostConfig$$' -> 'forks/ReactFiberHostConfig.${renderer}'
52
-module.name_mapper='ReactServerHostConfig$$' -> 'forks/ReactServerHostConfig.${serverRenderer}'
52
+module.name_mapper='ReactServerStreamConfig$$' -> 'forks/ReactServerStreamConfig.${serverRenderer}'
53
module.name_mapper='ReactServerFormatConfig$$' -> 'forks/ReactServerFormatConfig.${serverRenderer}'
54
module.name_mapper='ReactFlightClientHostConfig$$' -> 'forks/ReactFlightClientHostConfig.${serverRenderer}'
55
`.trim(),
scripts/jest/setupHostConfigs.js
+8
-8
@@ -11,35 +11,35 @@ jest.mock('react-reconciler', () => {
11
return require.requireActual('react-reconciler');
12
};
13
});
14
-const shimServerHostConfigPath = 'react-server/src/ReactServerHostConfig';
14
+const shimServerStreamConfigPath = 'react-server/src/ReactServerStreamConfig';
15
const shimServerFormatConfigPath = 'react-server/src/ReactServerFormatConfig';
16
jest.mock('react-server', () => {
17
return config => {
18
- jest.mock(shimServerHostConfigPath, () => config);
18
+ jest.mock(shimServerStreamConfigPath, () => config);
19
jest.mock(shimServerFormatConfigPath, () => config);
20
return require.requireActual('react-server');
21
};
22
});
23
jest.mock('react-server/flight', () => {
24
return config => {
25
- jest.mock(shimServerHostConfigPath, () => config);
25
+ jest.mock(shimServerStreamConfigPath, () => config);
26
jest.mock(shimServerFormatConfigPath, () => config);
27
return require.requireActual('react-server/flight');
28
};
29
});
30
const shimFlightClientHostConfigPath =
31
- 'react-flight/src/ReactFlightClientHostConfig';
32
-jest.mock('react-flight', () => {
31
+ 'react-client/src/ReactFlightClientHostConfig';
32
+jest.mock('react-client/flight', () => {
33
return config => {
34
jest.mock(shimFlightClientHostConfigPath, () => config);
35
- return require.requireActual('react-flight');
35
+ return require.requireActual('react-client/flight');
36
};
37
});
38
39
const configPaths = [
40
'react-reconciler/src/ReactFiberHostConfig',
41
- 'react-flight/src/ReactFlightClientHostConfig',
42
- 'react-server/src/ReactServerHostConfig',
41
+ 'react-client/src/ReactFlightClientHostConfig',
42
+ 'react-server/src/ReactServerStreamConfig',
43
'react-server/src/ReactServerFormatConfig',
44
];
45
scripts/rollup/bundles.js
+19
-1
@@ -197,6 +197,24 @@ const bundles = [
197
externals: ['react'],
198
},
199
200
+ /******* React DOM Flight Server Relay *******/
201
+ {
202
+ bundleTypes: [FB_WWW_DEV, FB_WWW_PROD],
203
+ moduleType: RENDERER,
204
+ entry: 'react-flight-dom-relay/server',
205
+ global: 'ReactFlightDOMRelayServer',
206
+ externals: ['react', 'react-dom/server'],
207
+ },
208
+
209
+ /******* React DOM Flight Client Relay *******/
210
+ {
211
+ bundleTypes: [FB_WWW_DEV, FB_WWW_PROD],
212
+ moduleType: RENDERER,
213
+ entry: 'react-flight-dom-relay',
214
+ global: 'ReactFlightDOMRelayClient',
215
+ externals: ['react'],
216
+ },
217
+
218
/******* React ART *******/
219
{
220
bundleTypes: [
@@ -384,7 +402,7 @@ const bundles = [
402
{
403
bundleTypes: [NODE_DEV, NODE_PROD],
404
moduleType: RECONCILER,
387
- entry: 'react-flight',
405
+ entry: 'react-client/flight',
406
global: 'ReactFlightClient',
407
externals: ['react'],
408
},
scripts/rollup/forks.js
+6
-6
@@ -298,7 +298,7 @@ const forks = Object.freeze({
298
);
299
},
300
301
- 'react-server/src/ReactServerHostConfig': (
301
+ 'react-server/src/ReactServerStreamConfig': (
302
bundleType,
303
entry,
304
dependencies,
@@ -316,11 +316,11 @@ const forks = Object.freeze({
316
if (!rendererInfo.isServerSupported) {
317
return null;
318
}
319
- return `react-server/src/forks/ReactServerHostConfig.${rendererInfo.shortName}.js`;
319
+ return `react-server/src/forks/ReactServerStreamConfig.${rendererInfo.shortName}.js`;
320
}
321
}
322
throw new Error(
323
- 'Expected ReactServerHostConfig to always be replaced with a shim, but ' +
323
+ 'Expected ReactServerStreamConfig to always be replaced with a shim, but ' +
324
`found no mention of "${entry}" entry point in ./scripts/shared/inlinedHostConfigs.js. ` +
325
'Did you mean to add it there to associate it with a specific renderer?'
326
);
@@ -354,13 +354,13 @@ const forks = Object.freeze({
354
);
355
},
356
357
- 'react-flight/src/ReactFlightClientHostConfig': (
357
+ 'react-client/src/ReactFlightClientHostConfig': (
358
bundleType,
359
entry,
360
dependencies,
361
moduleType
362
) => {
363
- if (dependencies.indexOf('react-flight') !== -1) {
363
+ if (dependencies.indexOf('react-client') !== -1) {
364
return null;
365
}
366
if (moduleType !== RENDERER && moduleType !== RECONCILER) {
@@ -372,7 +372,7 @@ const forks = Object.freeze({
372
if (!rendererInfo.isServerSupported) {
373
return null;
374
}
375
- return `react-flight/src/forks/ReactFlightClientHostConfig.${rendererInfo.shortName}.js`;
375
+ return `react-client/src/forks/ReactFlightClientHostConfig.${rendererInfo.shortName}.js`;
376
}
377
}
378
throw new Error(
scripts/shared/inlinedHostConfigs.js
+8
-1
@@ -78,11 +78,18 @@ module.exports = [
78
isFlowTyped: true,
79
isServerSupported: false,
80
},
81
+ {
82
+ shortName: 'dom-relay',
83
+ entryPoints: ['react-flight-dom-relay', 'react-flight-dom-relay/server'],
84
+ paths: ['react-dom', 'react-flight-dom-relay'],
85
+ isFlowTyped: true,
86
+ isServerSupported: true,
87
+ },
88
{
89
shortName: 'custom',
90
entryPoints: [
91
'react-reconciler',
85
- 'react-flight',
92
+ 'react-client/flight',
93
'react-server',
94
'react-server/flight',
95
],