import express from 'express' ; import compress from 'compression' ; import { readFileSync } from 'fs' ; import { unlink , writeFile } from 'fs/promises' ; import { pipeToNodeWritable } from 'react-server-dom-webpack/writer' ; import path from 'path' ; import React from 'react' ; import ReactApp from './App.server' ; const PORT = 4000 ; const app = express ( ) ; app . use ( compress ( ) ) ; app . use ( express . json ( ) ) ; app . listen ( PORT , ( ) => { console . log ( 'React Notes listening at 4000...' ) ; } ) ; function handleErrors ( fn ) { return async function ( req , res , next ) { try { return await fn ( req , res ) ; } catch ( x ) { next ( x ) ; } } ; } app . get ( '/' , handleErrors ( async function ( _req , res ) { await waitForWebpack ( ) ; const html = readFileSync ( path . resolve ( __dirname , '../build/index.html' ) , 'utf8' ) ; res . send ( html ) ; } ) ) ; async function renderReactTree ( res , props ) { await waitForWebpack ( ) ; const manifest = readFileSync ( path . resolve ( __dirname , '../build/react-client-manifest.json' ) , 'utf8' ) ; const moduleMap = JSON . parse ( manifest ) ; pipeToNodeWritable ( React . createElement ( ReactApp , props ) , res , moduleMap ) ; } function sendResponse ( req , res , redirectToId ) { const location = JSON . parse ( req . query . location ) ; if ( redirectToId ) { location . selectedId = redirectToId ; } res . set ( 'X-Location' , JSON . stringify ( location ) ) ; renderReactTree ( res , { selectedId : location . selectedId , isEditing : location . isEditing , searchText : location . searchText , } ) ; } app . get ( '/react' , function ( req , res ) { sendResponse ( req , res , null ) ; } ) ; app . get ( '/sleep/:ms' , function ( req , res ) { setTimeout ( ( ) => { res . json ( { ok : true } ) ; } , req . params . ms ) ; } ) ; app . use ( express . static ( 'build' ) ) ; app . use ( express . static ( 'public' ) ) ; app . on ( 'error' , function ( error ) { if ( error . syscall !== 'listen' ) { throw error ; } var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port ; switch ( error . code ) { case 'EACCES' : console . error ( bind + ' requires elevated privileges' ) ; process . exit ( 1 ) ; break ; case 'EADDRINUSE' : console . error ( bind + ' is already in use' ) ; process . exit ( 1 ) ; break ; default : throw error ; } } ) ; async function waitForWebpack ( ) { while ( true ) { try { readFileSync ( path . resolve ( __dirname , '../build/index.html' ) ) ; return ; } catch ( err ) { console . log ( 'Could not find webpack build output. Will retry in a second...' ) ; await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) ) ; } } }