Skip to content

Commit

Permalink
Use AbortSignal option for W3C streams instead of external control
Browse files Browse the repository at this point in the history
  • Loading branch information
sebmarkbage committed Mar 18, 2021
1 parent 5d8cdc8 commit ab84723
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 18 deletions.
5 changes: 4 additions & 1 deletion fixtures/fizz-ssr-browser/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ <h1>Fizz Example</h1>
<script src="../../build/node_modules/react-dom/umd/react-dom-unstable-fizz.browser.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
<script type="text/babel">
let {stream} = ReactDOMFizzServer.renderToReadableStream(<body>Success</body>);
let controller = new AbortController();
let stream = ReactDOMFizzServer.renderToReadableStream(<body>Success</body>, {
signal: controller.signal,
});
let response = new Response(stream, {
headers: {'Content-Type': 'text/html'},
});
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@babel/preset-react": "^7.10.4",
"@babel/traverse": "^7.11.0",
"@mattiasbuelens/web-streams-polyfill": "^0.3.2",
"abort-controller": "^3.0.0",
"art": "0.10.1",
"babel-eslint": "^10.0.3",
"babel-plugin-syntax-trailing-function-commas": "^6.5.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// Polyfills for test environment
global.ReadableStream = require('@mattiasbuelens/web-streams-polyfill/ponyfill/es6').ReadableStream;
global.TextEncoder = require('util').TextEncoder;
global.AbortController = require('abort-controller');

let React;
let ReactDOMFizzServer;
Expand Down Expand Up @@ -50,7 +51,7 @@ describe('ReactDOMFizzServer', () => {

// @gate experimental
it('should call renderToReadableStream', async () => {
const {stream} = ReactDOMFizzServer.renderToReadableStream(
const stream = ReactDOMFizzServer.renderToReadableStream(
<div>hello world</div>,
);
const result = await readResult(stream);
Expand All @@ -59,7 +60,7 @@ describe('ReactDOMFizzServer', () => {

// @gate experimental
it('should error the stream when an error is thrown at the root', async () => {
const {stream} = ReactDOMFizzServer.renderToReadableStream(
const stream = ReactDOMFizzServer.renderToReadableStream(
<div>
<Throw />
</div>,
Expand All @@ -78,7 +79,7 @@ describe('ReactDOMFizzServer', () => {

// @gate experimental
it('should error the stream when an error is thrown inside a fallback', async () => {
const {stream} = ReactDOMFizzServer.renderToReadableStream(
const stream = ReactDOMFizzServer.renderToReadableStream(
<div>
<Suspense fallback={<Throw />}>
<InfiniteSuspend />
Expand All @@ -99,7 +100,7 @@ describe('ReactDOMFizzServer', () => {

// @gate experimental
it('should not error the stream when an error is thrown inside suspense boundary', async () => {
const {stream} = ReactDOMFizzServer.renderToReadableStream(
const stream = ReactDOMFizzServer.renderToReadableStream(
<div>
<Suspense fallback={<div>Loading</div>}>
<Throw />
Expand All @@ -113,15 +114,17 @@ describe('ReactDOMFizzServer', () => {

// @gate experimental
it('should be able to complete by aborting even if the promise never resolves', async () => {
const {abort, stream} = ReactDOMFizzServer.renderToReadableStream(
const controller = new AbortController();
const stream = ReactDOMFizzServer.renderToReadableStream(
<div>
<Suspense fallback={<div>Loading</div>}>
<InfiniteSuspend />
</Suspense>
</div>,
{signal: controller.signal},
);

abort();
controller.abort();

const result = await readResult(stream);
expect(result).toContain('Loading');
Expand Down
21 changes: 10 additions & 11 deletions packages/react-dom/src/server/ReactDOMFizzServerBrowser.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,19 @@ import {
abort,
} from 'react-server/src/ReactFizzServer';

type Controls = {
stream: ReadableStream,
abort(): void,
type Options = {
signal?: AbortSignal,
};

function renderToReadableStream(children: ReactNodeList): Controls {
function renderToReadableStream(
children: ReactNodeList,
options?: Options,
): ReadableStream {
let request;
const stream = new ReadableStream({
if (options && options.signal) {
options.signal.addEventListener('abort', () => abort(request));
}
return new ReadableStream({
start(controller) {
request = createRequest(children, controller);
startWork(request);
Expand All @@ -33,12 +38,6 @@ function renderToReadableStream(children: ReactNodeList): Controls {
},
cancel(reason) {},
});
return {
stream,
abort() {
abort(request);
},
};
}

export {renderToReadableStream};

0 comments on commit ab84723

Please sign in to comment.