farrow-js / farrow

A Type-Friendly Web Framework for Node.js
https://www.farrowjs.com
MIT License
768 stars 37 forks source link

Question(farrow-http): how to work with react 18 renderToPipeableStream #129

Closed tqma113 closed 2 years ago

tqma113 commented 2 years ago

https://codesandbox.io/s/kind-sammet-j56ro?file=/server/render.js:1217-1223 https://github.com/reactwg/react-18/discussions/22

const { pipe, abort } = renderToPipeableStream(
    <DataProvider data={data}>
      <App assets={assets} />
    </DataProvider>,
    {
      bootstrapScripts: [assets["main.js"]],
      onCompleteShell() {
        res.statusCode = didError ? 500 : 200;
        res.setHeader("Content-type", "text/html");
        pipe(res); // Here is the conflict point
      },
      onError(x) {
        didError = true;
        console.error(x);
      }
    }
  );

How to do pipe(res) with farrow-http?

Lucifier129 commented 2 years ago

Response.custom(handler) is for this use-case.

const renderReactStream = (elem, options) => {
  return Response.custom(( { res } ) => {
    const { pipe, abort } = renderToPipeableStream(elem,
    {
      ...options,
      onCompleteShell() {
        options?.onCompleteShell(res)
        pipe(res); // No problem!
      }
    }
  );
  })
}

http.use(request => {
  return renderReactStream( 
    <DataProvider data={data}>
      <App assets={assets} />
    </DataProvider>,
    {
      bootstrapScripts: [assets["main.js"]],
      onCompleteShell(res) {
        res.statusCode = didError ? 500 : 200;
        res.setHeader("Content-type", "text/html");
      },
      onError(x) {
        didError = true;
        console.error(x);
      }
    })
})