-
Notifications
You must be signed in to change notification settings - Fork 47.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Experimental Flight Infrastructure (#16398)
* Add Flight Build and Unify HostFormat Config between Flight and Fizz * Add basic resolution of models * Add basic Flight fixture Demonstrates the streaming protocol. * Rename to flight-server to distinguish from the client parts * Add Flight Client package and entry point * Fix fixture
- Loading branch information
1 parent
6cd365c
commit f4e974d
Showing
75 changed files
with
1,651 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
<!DOCTYPE html> | ||
<html style="width: 100%; height: 100%; overflow: hidden"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>Flight Example</title> | ||
</head> | ||
<body> | ||
<h1>Flight Example</h1> | ||
<div id="container"> | ||
<p> | ||
To install React, follow the instructions on | ||
<a href="https://github.com/facebook/react/">GitHub</a>. | ||
</p> | ||
<p> | ||
If you can see this, React is <strong>not</strong> working right. | ||
If you checked out the source from GitHub make sure to run <code>npm run build</code>. | ||
</p> | ||
</div> | ||
<script src="../../build/dist/react.development.js"></script> | ||
<script src="../../build/dist/react-dom.development.js"></script> | ||
<script src="../../build/dist/react-dom-unstable-flight-client.development.js"></script> | ||
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script> | ||
<script type="text/babel"> | ||
function Text({children}) { | ||
return <span>{children}</span>; | ||
} | ||
function HTML() { | ||
return ( | ||
<div> | ||
<Text>hello</Text> | ||
<Text>world</Text> | ||
</div> | ||
); | ||
} | ||
|
||
let model = { | ||
title: 'Title', | ||
content: { | ||
__html: <HTML />, | ||
} | ||
}; | ||
|
||
let stream = ReactFlightDOMClient.renderToReadableStream(model); | ||
let response = new Response(stream, { | ||
headers: {'Content-Type': 'text/html'}, | ||
}); | ||
display(response); | ||
|
||
async function display(responseToDisplay) { | ||
let blob = await responseToDisplay.blob(); | ||
let url = URL.createObjectURL(blob); | ||
let response = await fetch(url); | ||
let body = await response.body; | ||
|
||
let reader = body.getReader(); | ||
let charsReceived = 0; | ||
let decoder = new TextDecoder(); | ||
|
||
let json = ''; | ||
reader.read().then(function processChunk({ done, value }) { | ||
if (done) { | ||
renderResult(json); | ||
return; | ||
} | ||
json += decoder.decode(value); | ||
return reader.read().then(processChunk); | ||
}); | ||
} | ||
|
||
function Shell({ model }) { | ||
return <div> | ||
<h1>{model.title}</h1> | ||
<div dangerouslySetInnerHTML={model.content} /> | ||
</div>; | ||
} | ||
|
||
function renderResult(json) { | ||
let model = JSON.parse(json); | ||
let container = document.getElementById('container'); | ||
ReactDOM.render(<Shell model={model} />, container); | ||
} | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
'use strict'; | ||
|
||
if (process.env.NODE_ENV === 'production') { | ||
module.exports = require('./cjs/react-dom-unstable-flight-client.production.min.js'); | ||
} else { | ||
module.exports = require('./cjs/react-dom-unstable-flight-client.development.js'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
'use strict'; | ||
|
||
if (process.env.NODE_ENV === 'production') { | ||
module.exports = require('./cjs/react-dom-unstable-flight-server.browser.production.min.js'); | ||
} else { | ||
module.exports = require('./cjs/react-dom-unstable-flight-server.browser.development.js'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
'use strict'; | ||
|
||
module.exports = require('./unstable-flight-server.node'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
'use strict'; | ||
|
||
if (process.env.NODE_ENV === 'production') { | ||
module.exports = require('./cjs/react-dom-unstable-flight-server.node.production.min.js'); | ||
} else { | ||
module.exports = require('./cjs/react-dom-unstable-flight-server.node.development.js'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
packages/react-dom/src/client/flight/ReactFlightDOMClient.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* @flow | ||
*/ | ||
|
||
import type {ReactModel} from 'react-flight/src/ReactFlightClient'; | ||
|
||
import { | ||
createRequest, | ||
startWork, | ||
startFlowing, | ||
} from 'react-flight/inline.dom-browser'; | ||
|
||
function renderToReadableStream(model: ReactModel): ReadableStream { | ||
let request; | ||
return new ReadableStream({ | ||
start(controller) { | ||
request = createRequest(model, controller); | ||
startWork(request); | ||
}, | ||
pull(controller) { | ||
startFlowing(request, controller.desiredSize); | ||
}, | ||
cancel(reason) {}, | ||
}); | ||
} | ||
|
||
export default { | ||
renderToReadableStream, | ||
}; |
50 changes: 50 additions & 0 deletions
50
packages/react-dom/src/client/flight/ReactFlightDOMHostConfig.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* @flow | ||
*/ | ||
|
||
export type Destination = ReadableStreamController; | ||
|
||
export function scheduleWork(callback: () => void) { | ||
callback(); | ||
} | ||
|
||
export function flushBuffered(destination: Destination) { | ||
// WHATWG Streams do not yet have a way to flush the underlying | ||
// transform streams. https://github.com/whatwg/streams/issues/960 | ||
} | ||
|
||
export function beginWriting(destination: Destination) {} | ||
|
||
export function writeChunk(destination: Destination, buffer: Uint8Array) { | ||
destination.enqueue(buffer); | ||
} | ||
|
||
export function completeWriting(destination: Destination) {} | ||
|
||
export function close(destination: Destination) { | ||
destination.close(); | ||
} | ||
|
||
const textEncoder = new TextEncoder(); | ||
|
||
export function convertStringToBuffer(content: string): Uint8Array { | ||
return textEncoder.encode(content); | ||
} | ||
|
||
export function formatChunkAsString(type: string, props: Object): string { | ||
let str = '<' + type + '>'; | ||
if (typeof props.children === 'string') { | ||
str += props.children; | ||
} | ||
str += '</' + type + '>'; | ||
return str; | ||
} | ||
|
||
export function formatChunk(type: string, props: Object): Uint8Array { | ||
return convertStringToBuffer(formatChunkAsString(type, props)); | ||
} |
61 changes: 61 additions & 0 deletions
61
packages/react-dom/src/client/flight/__tests__/ReactFlightDOMBrowser-test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* @emails react-core | ||
*/ | ||
|
||
'use strict'; | ||
|
||
// Polyfills for test environment | ||
global.ReadableStream = require('@mattiasbuelens/web-streams-polyfill/ponyfill/es6').ReadableStream; | ||
global.TextEncoder = require('util').TextEncoder; | ||
|
||
let React; | ||
let ReactFlightDOMServer; | ||
|
||
describe('ReactFlightDOM', () => { | ||
beforeEach(() => { | ||
jest.resetModules(); | ||
React = require('react'); | ||
ReactFlightDOMServer = require('react-dom/unstable-flight-server.browser'); | ||
}); | ||
|
||
async function readResult(stream) { | ||
let reader = stream.getReader(); | ||
let result = ''; | ||
while (true) { | ||
let {done, value} = await reader.read(); | ||
if (done) { | ||
return result; | ||
} | ||
result += Buffer.from(value).toString('utf8'); | ||
} | ||
} | ||
|
||
it('should resolve HTML', async () => { | ||
function Text({children}) { | ||
return <span>{children}</span>; | ||
} | ||
function HTML() { | ||
return ( | ||
<div> | ||
<Text>hello</Text> | ||
<Text>world</Text> | ||
</div> | ||
); | ||
} | ||
|
||
let model = { | ||
html: <HTML />, | ||
}; | ||
let stream = ReactFlightDOMServer.renderToReadableStream(model); | ||
jest.runAllTimers(); | ||
let result = JSON.parse(await readResult(stream)); | ||
expect(result).toEqual({ | ||
html: '<div><span>hello</span><span>world</span></div>', | ||
}); | ||
}); | ||
}); |
57 changes: 57 additions & 0 deletions
57
packages/react-dom/src/client/flight/__tests__/ReactFlightDOMNode-test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* @emails react-core | ||
* @jest-environment node | ||
*/ | ||
|
||
'use strict'; | ||
|
||
let Stream; | ||
let React; | ||
let ReactFlightDOMServer; | ||
|
||
describe('ReactFlightDOM', () => { | ||
beforeEach(() => { | ||
jest.resetModules(); | ||
React = require('react'); | ||
ReactFlightDOMServer = require('react-dom/unstable-flight-server'); | ||
Stream = require('stream'); | ||
}); | ||
|
||
function getTestWritable() { | ||
let writable = new Stream.PassThrough(); | ||
writable.setEncoding('utf8'); | ||
writable.result = ''; | ||
writable.on('data', chunk => (writable.result += chunk)); | ||
return writable; | ||
} | ||
|
||
it('should resolve HTML', () => { | ||
function Text({children}) { | ||
return <span>{children}</span>; | ||
} | ||
function HTML() { | ||
return ( | ||
<div> | ||
<Text>hello</Text> | ||
<Text>world</Text> | ||
</div> | ||
); | ||
} | ||
|
||
let writable = getTestWritable(); | ||
let model = { | ||
html: <HTML />, | ||
}; | ||
ReactFlightDOMServer.pipeToNodeWritable(model, writable); | ||
jest.runAllTimers(); | ||
let result = JSON.parse(writable.result); | ||
expect(result).toEqual({ | ||
html: '<div><span>hello</span><span>world</span></div>', | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.