Skip to content

Commit

Permalink
Support native ReadableStream as BodyInit & tests for React strea…
Browse files Browse the repository at this point in the history
…ming response w/ Fastify (#1111)

Co-authored-by: Arda TANRIKULU <[email protected]>
  • Loading branch information
dac09 and ardatan authored Jan 25, 2024
1 parent 8cf4d96 commit a129376
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/long-suits-train.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@whatwg-node/node-fetch": patch
---

Support native `ReadableStream` as `BodyInit`
2 changes: 1 addition & 1 deletion packages/node-fetch/src/Body.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ function processBodyInit(bodyInit: BodyPonyfillInit | null): {
},
};
}
if (bodyInit instanceof PonyfillReadableStream) {
if (bodyInit instanceof PonyfillReadableStream && bodyInit.readable != null) {
return {
bodyType: BodyInitType.ReadableStream,
bodyFactory: () => bodyInit,
Expand Down
2 changes: 1 addition & 1 deletion packages/node-fetch/src/ReadableStream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class PonyfillReadableStream<T> implements ReadableStream<T> {
| ReadableStream<T>
| PonyfillReadableStream<T>,
) {
if (underlyingSource instanceof PonyfillReadableStream) {
if (underlyingSource instanceof PonyfillReadableStream && underlyingSource.readable != null) {
this.readable = underlyingSource.readable;
} else if (isNodeReadable(underlyingSource)) {
this.readable = underlyingSource as Readable;
Expand Down
2 changes: 2 additions & 0 deletions packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
"@types/node": "20.11.6",
"express": "4.18.2",
"fastify": "4.25.2",
"react": "0.0.0-experimental-e5205658f-20230913",
"react-dom": "0.0.0-experimental-e5205658f-20230913",
"uWebSockets.js": "uNetworking/uWebSockets.js#v20.34.0"
},
"publishConfig": {
Expand Down
42 changes: 42 additions & 0 deletions packages/server/test/fastify.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import React from 'react';
import fastify, { FastifyReply, FastifyRequest } from 'fastify';
import { ReadableStream, Response, TextEncoder, URL } from '@whatwg-node/fetch';
import { createServerAdapter } from '../src/createServerAdapter.js';
Expand Down Expand Up @@ -145,4 +146,45 @@ describe('Fastify', () => {
expect(res.headers).toMatchObject(headers);
expect(res.statusCode).toBe(status);
});

it('Should handle react streaming response', async () => {
const serverAdapter = createServerAdapter(async () => {
const MyComponent = () => {
return React.createElement('h1', null, 'Rendered in React');
};

// @ts-expect-error React types not available yet
const { renderToReadableStream } = await import('react-dom/server.edge');

const stream = await renderToReadableStream(React.createElement(MyComponent));

return new Response(stream);
});

const fastifyServer = fastify();
fastifyServer.route({
url: '/renderReact',
method: ['GET'],
handler: async (req, reply) => {
const response = await serverAdapter.handleNodeRequest(req, {
req,
reply,
});
response.headers.forEach((value, key) => {
reply.header(key, value);
});

reply.status(response.status);

reply.send(response.body);

return reply;
},
});
const res = await fastifyServer.inject({
url: '/renderReact',
});
const body = res.body;
expect(body).toEqual('<h1>Rendered in React</h1>');
});
});
22 changes: 22 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7736,6 +7736,14 @@ [email protected]:
iconv-lite "0.4.24"
unpipe "1.0.0"

[email protected]:
version "0.0.0-experimental-e5205658f-20230913"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-0.0.0-experimental-e5205658f-20230913.tgz#5eb3f8f6e660f3498fcf81fdefd15f3f1d7130dc"
integrity sha512-Lnv7ObEPUBh/G2NoF2/1nmueYY5vmKsfgEBlG5gjMXeDgbKAf7yYI+wK49URKP9RyJRMjTOUcBghtM+nUwPWdg==
dependencies:
loose-envify "^1.1.0"
scheduler "0.0.0-experimental-e5205658f-20230913"

[email protected]:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
Expand All @@ -7754,6 +7762,13 @@ react-is@^18.0.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==

[email protected]:
version "0.0.0-experimental-e5205658f-20230913"
resolved "https://registry.yarnpkg.com/react/-/react-0.0.0-experimental-e5205658f-20230913.tgz#b14fd35fea76cb1e86c84982c304a4ddea752455"
integrity sha512-Vbc4OkA2YHmlUUr4bvzkaxnpTpJO/N7AMIRrlUFzU6rhbaQWp0+GisxQrsEJd1oLd8kpnXbf6LUiBRfhT/JZ3g==
dependencies:
loose-envify "^1.1.0"

[email protected]:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
Expand Down Expand Up @@ -8141,6 +8156,13 @@ [email protected], sax@>=0.6.0:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a"
integrity sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==

[email protected]:
version "0.0.0-experimental-e5205658f-20230913"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.0.0-experimental-e5205658f-20230913.tgz#ac5599f9923a751365cbf834cdf333542dd3f6fb"
integrity sha512-EGj1PauhuhJnJz0vr341m1MAUeX+hrsLVWwl0Uh/TKOVXWNSRn8BngAivX81HwgUTab9RETU81o1L2jmIo1CeA==
dependencies:
loose-envify "^1.1.0"

scheduler@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
Expand Down

0 comments on commit a129376

Please sign in to comment.