Skip to content

Commit

Permalink
Ported streaming React render to 0.14 branch. All tests pass, includi…
Browse files Browse the repository at this point in the history
…ng streaming render.
  • Loading branch information
aickin committed Oct 14, 2015
1 parent b020e69 commit d650a52
Show file tree
Hide file tree
Showing 14 changed files with 781 additions and 62 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"browserify": "^9.0.3",
"bundle-collapser": "^1.1.1",
"coffee-script": "^1.8.0",
"concat-stream": "^1.5.0",
"del": "^1.2.0",
"derequire": "^2.0.0",
"envify": "^3.0.0",
Expand Down
3 changes: 3 additions & 0 deletions src/renderers/dom/ReactDOMServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@
var ReactDefaultInjection = require('ReactDefaultInjection');
var ReactServerRendering = require('ReactServerRendering');
var ReactVersion = require('ReactVersion');
var ReactServerAsyncRendering = require('ReactServerAsyncRendering');

ReactDefaultInjection.inject();

var ReactDOMServer = {
renderToString: ReactServerRendering.renderToString,
renderToStaticMarkup: ReactServerRendering.renderToStaticMarkup,
version: ReactVersion,
asyncRenderToString: ReactServerAsyncRendering.renderToString,
asyncRenderToStaticMarkup: ReactServerAsyncRendering.renderToStaticMarkup,
};

module.exports = ReactDOMServer;
102 changes: 102 additions & 0 deletions src/renderers/dom/server/ReactServerAsyncRendering.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/**
* Copyright 2013-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @typechecks static-only
* @providesModule ReactServerAsyncRendering
*/
'use strict';

var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy');
var ReactElement = require('ReactElement');
var ReactInstanceHandles = require('ReactInstanceHandles');
var ReactMarkupChecksum = require('ReactMarkupChecksum');
var ReactServerBatchingStrategy = require('ReactServerBatchingStrategy');
var ReactServerRenderingTransaction =
require('ReactServerRenderingTransaction');
var ReactUpdates = require('ReactUpdates');

var emptyObject = require('emptyObject');
var instantiateReactComponent = require('instantiateReactComponent');
var invariant = require('invariant');
var rollingAdler32 = require('rollingAdler32');

/**
* @param {ReactElement} element
* @return {Number} the markup checksum
*/
function renderToString(element, stream) {
invariant(
ReactElement.isValidElement(element),
'renderToString(): You must pass a valid ReactElement.'
);

var transaction;
try {
ReactUpdates.injection.injectBatchingStrategy(ReactServerBatchingStrategy);

var id = ReactInstanceHandles.createReactRootID();
transaction = ReactServerRenderingTransaction.getPooled(false);

var rollingHash = rollingAdler32('');
// wrap the stream so that we can update the hash every time a string is written to the
// output.
var wrappedStream = {
write: function(text) {
// pass through to the underlying stream.
stream.write(text);
// also, add to the rolling hash.
rollingHash = rollingAdler32(text, rollingHash);
}
}
return transaction.perform(function() {
var componentInstance = instantiateReactComponent(element, null);
componentInstance.mountComponentAsync(id, transaction, emptyObject, wrappedStream);
return rollingHash.hash();
}, null);
} finally {
ReactServerRenderingTransaction.release(transaction);
// Revert to the DOM batching strategy since these two renderers
// currently share these stateful modules.
ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy);
}
}

/**
* @param {ReactElement} element
* @return {string} the HTML markup, without the extra React ID and checksum
* (for generating static pages)
*/
function renderToStaticMarkup(element, stream) {
invariant(
ReactElement.isValidElement(element),
'renderToStaticMarkup(): You must pass a valid ReactElement.'
);

var transaction;
try {
ReactUpdates.injection.injectBatchingStrategy(ReactServerBatchingStrategy);

var id = ReactInstanceHandles.createReactRootID();
transaction = ReactServerRenderingTransaction.getPooled(true);

return transaction.perform(function() {
var componentInstance = instantiateReactComponent(element, null);
componentInstance.mountComponentAsync(id, transaction, emptyObject, stream);
}, null);
} finally {
ReactServerRenderingTransaction.release(transaction);
// Revert to the DOM batching strategy since these two renderers
// currently share these stateful modules.
ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy);
}
}

module.exports = {
renderToString: renderToString,
renderToStaticMarkup: renderToStaticMarkup,
};
Loading

0 comments on commit d650a52

Please sign in to comment.