1/**2 * Copyright (c) Meta Platforms, Inc. and affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 */89import {Writable} from 'stream';10import * as React from 'react';11import {renderToPipeableStream} from 'react-dom/server';12import App from '../src/App';13import {ABORT_DELAY} from './delays';1415// In a real setup, you'd read it from webpack build stats.16let assets = {17 'main.js': '/main.js',18 'main.css': '/main.css',19};2021function HtmlWritable(options) {22 Writable.call(this, options);23 this.chunks = [];24 this.html = '';25}2627HtmlWritable.prototype = Object.create(Writable.prototype);28HtmlWritable.prototype.getHtml = function getHtml() {29 return this.html;30};31HtmlWritable.prototype._write = function _write(chunk, encoding, callback) {32 this.chunks.push(chunk);33 callback();34};35HtmlWritable.prototype._final = function _final(callback) {36 this.html = Buffer.concat(this.chunks).toString();37 callback();38};3940module.exports = function render(url, res) {41 let writable = new HtmlWritable();42 res.socket.on('error', error => {43 console.error('Fatal', error);44 });45 let didError = false;46 let didFinish = false;4748 writable.on('finish', () => {49 // If something errored before we started streaming, we set the error code appropriately.50 res.statusCode = didError ? 500 : 200;51 res.setHeader('Content-type', 'text/html');52 res.send(writable.getHtml());53 });5455 const {pipe, abort} = renderToPipeableStream(<App assets={assets} />, {56 bootstrapScripts: [assets['main.js']],57 onAllReady() {58 // Full completion.59 // You can use this for SSG or crawlers.60 didFinish = true;61 },62 onShellReady() {63 // If something errored before we started streaming, we set the error code appropriately.64 pipe(writable);65 },66 onShellError(x) {67 // Something errored before we could complete the shell so we emit an alternative shell.68 res.statusCode = 500;69 res.send('<!doctype><p>Error</p>');70 },71 onError(x) {72 didError = true;73 console.error(x);74 },75 });76 // Abandon and switch to client rendering if enough time passes.77 // Try lowering this to see the client recover.78 setTimeout(() => {79 if (!didFinish) {80 abort();81 }82 }, ABORT_DELAY);83};
Findings
✓ No findings reported for this file.