[Flight] Expose `encodeReply` from ReactFlightDOMClientEdge (#27551)
Adds encodeReply to ReactFlightDOMClientEdge in webpack and turbopack bindings
Josh Story committed
Oct 19, 2023 at 17:24 UTC
3a1967b7d514b69c3fcb2ee53966fc035691bcd3
4 files changed
+130
-4
packages/react-server-dom-turbopack/src/ReactFlightDOMClientEdge.js
+17
-2
@@ -11,6 +11,8 @@ import type {Thenable} from 'shared/ReactTypes.js';
11
12
import type {Response as FlightResponse} from 'react-client/src/ReactFlightClient';
13
14
+import type {ReactServerValue} from 'react-client/src/ReactFlightReplyClient';
15
+
16
import type {
17
SSRModuleMap,
18
ModuleLoading,
@@ -29,7 +31,10 @@ import {
31
close,
32
} from 'react-client/src/ReactFlightClient';
33
32
-import {createServerReference as createServerReferenceImpl} from 'react-client/src/ReactFlightReplyClient';
34
+import {
35
+ processReply,
36
+ createServerReference as createServerReferenceImpl,
37
+} from 'react-client/src/ReactFlightReplyClient';
38
39
function noServerCall() {
40
throw new Error(
@@ -112,4 +117,14 @@ function createFromFetch<T>(
117
return getRoot(response);
118
}
119
115
-export {createFromFetch, createFromReadableStream};
120
+function encodeReply(
121
+ value: ReactServerValue,
122
+): Promise<
123
+ string | URLSearchParams | FormData,
124
+> /* We don't use URLSearchParams yet but maybe */ {
125
+ return new Promise((resolve, reject) => {
126
+ processReply(value, '', resolve, reject);
127
+ });
128
+}
129
+
130
+export {createFromFetch, createFromReadableStream, encodeReply};
packages/react-server-dom-turbopack/src/__tests__/ReactFlightDOMReplyEdge-test.js
new
+48
@@ -0,0 +1,48 @@
1
+/**
2
+ * Copyright (c) Meta Platforms, Inc. and 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
+ * @emails react-core
8
+ */
9
+
10
+'use strict';
11
+
12
+// Polyfills for test environment
13
+global.ReadableStream =
14
+ require('web-streams-polyfill/ponyfill/es6').ReadableStream;
15
+global.TextEncoder = require('util').TextEncoder;
16
+global.TextDecoder = require('util').TextDecoder;
17
+
18
+// let serverExports;
19
+let turbopackServerMap;
20
+let ReactServerDOMServer;
21
+let ReactServerDOMClient;
22
+
23
+describe('ReactFlightDOMReply', () => {
24
+ beforeEach(() => {
25
+ jest.resetModules();
26
+ // Simulate the condition resolution
27
+ jest.mock('react', () => require('react/react.shared-subset'));
28
+ jest.mock('react-server-dom-turbopack/server', () =>
29
+ require('react-server-dom-turbopack/server.edge'),
30
+ );
31
+ const TurbopackMock = require('./utils/TurbopackMock');
32
+ // serverExports = TurbopackMock.serverExports;
33
+ turbopackServerMap = TurbopackMock.turbopackServerMap;
34
+ ReactServerDOMServer = require('react-server-dom-turbopack/server.edge');
35
+ jest.resetModules();
36
+ ReactServerDOMClient = require('react-server-dom-turbopack/client.edge');
37
+ });
38
+
39
+ it('can encode a reply', async () => {
40
+ const body = await ReactServerDOMClient.encodeReply({some: 'object'});
41
+ const decoded = await ReactServerDOMServer.decodeReply(
42
+ body,
43
+ turbopackServerMap,
44
+ );
45
+
46
+ expect(decoded).toEqual({some: 'object'});
47
+ });
48
+});
packages/react-server-dom-webpack/src/ReactFlightDOMClientEdge.js
+17
-2
@@ -11,6 +11,8 @@ import type {Thenable} from 'shared/ReactTypes.js';
11
12
import type {Response as FlightResponse} from 'react-client/src/ReactFlightClient';
13
14
+import type {ReactServerValue} from 'react-client/src/ReactFlightReplyClient';
15
+
16
import type {
17
SSRModuleMap,
18
ModuleLoading,
@@ -29,7 +31,10 @@ import {
31
close,
32
} from 'react-client/src/ReactFlightClient';
33
32
-import {createServerReference as createServerReferenceImpl} from 'react-client/src/ReactFlightReplyClient';
34
+import {
35
+ processReply,
36
+ createServerReference as createServerReferenceImpl,
37
+} from 'react-client/src/ReactFlightReplyClient';
38
39
function noServerCall() {
40
throw new Error(
@@ -112,4 +117,14 @@ function createFromFetch<T>(
117
return getRoot(response);
118
}
119
115
-export {createFromFetch, createFromReadableStream};
120
+function encodeReply(
121
+ value: ReactServerValue,
122
+): Promise<
123
+ string | URLSearchParams | FormData,
124
+> /* We don't use URLSearchParams yet but maybe */ {
125
+ return new Promise((resolve, reject) => {
126
+ processReply(value, '', resolve, reject);
127
+ });
128
+}
129
+
130
+export {createFromFetch, createFromReadableStream, encodeReply};
packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMReplyEdge-test.js
new
+48
@@ -0,0 +1,48 @@
1
+/**
2
+ * Copyright (c) Meta Platforms, Inc. and 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
+ * @emails react-core
8
+ */
9
+
10
+'use strict';
11
+
12
+// Polyfills for test environment
13
+global.ReadableStream =
14
+ require('web-streams-polyfill/ponyfill/es6').ReadableStream;
15
+global.TextEncoder = require('util').TextEncoder;
16
+global.TextDecoder = require('util').TextDecoder;
17
+
18
+// let serverExports;
19
+let webpackServerMap;
20
+let ReactServerDOMServer;
21
+let ReactServerDOMClient;
22
+
23
+describe('ReactFlightDOMReplyEdge', () => {
24
+ beforeEach(() => {
25
+ jest.resetModules();
26
+ // Simulate the condition resolution
27
+ jest.mock('react', () => require('react/react.shared-subset'));
28
+ jest.mock('react-server-dom-webpack/server', () =>
29
+ require('react-server-dom-webpack/server.edge'),
30
+ );
31
+ const WebpackMock = require('./utils/WebpackMock');
32
+ // serverExports = WebpackMock.serverExports;
33
+ webpackServerMap = WebpackMock.webpackServerMap;
34
+ ReactServerDOMServer = require('react-server-dom-webpack/server.edge');
35
+ jest.resetModules();
36
+ ReactServerDOMClient = require('react-server-dom-webpack/client.edge');
37
+ });
38
+
39
+ it('can encode a reply', async () => {
40
+ const body = await ReactServerDOMClient.encodeReply({some: 'object'});
41
+ const decoded = await ReactServerDOMServer.decodeReply(
42
+ body,
43
+ webpackServerMap,
44
+ );
45
+
46
+ expect(decoded).toEqual({some: 'object'});
47
+ });
48
+});