module Post = {
let make = () => {
{React.string(
"Notice how HTML for comments 'streams in' before the JavaScript (or React) has loaded on the page. In fact, the demo is entirely rendered in the server and doesn't use client-side JavaScript at all",
)}
{React.string("This demo is ")}
{React.string("artificially slowed down")}
{React.string(" while loading the comments data.")}
;
};
};
module Data = {
let delay = 4.0;
let fakeData = [
"Wait, it doesn't wait for React to load?",
"How does this even work?",
"I like marshmallows",
"!1!1!1! This is a comment",
"This is actually static from the server",
"But, imagine it's dynamic",
];
let get = () => fakeData;
let cached = ref(false);
let destroy = () => cached := false;
let promise = () => {
cached.contents
? Lwt.return(fakeData)
: {
let%lwt () = Lwt_unix.sleep(delay);
cached.contents = true;
Lwt.return(fakeData);
};
};
};
module Comments = {
[@react.async.component]
let make = () => {
let comments = React.Experimental.use(Data.promise());
Lwt.return(
{comments
|> List.mapi((i, comment) =>
{React.string(comment)}
)
|> React.list}
,
);
};
};
module Page = {
[@react.component]
let make = () => {
{React.string("Rendering React.Suspense on the server")}
{React.string("Comments")}
}>
{React.string("Thanks for reading!")}
;
};
};
let handler = _request => {
Dream.stream(
~headers=[("Content-Type", "text/html")],
response_stream => {
Data.destroy();
let pipe = data => {
let%lwt () = Dream.write(response_stream, data);
Dream.flush(response_stream);
};
let%lwt (stream, _abort) =
ReactDOM.renderToStream( );
Lwt_stream.iter_s(pipe, stream);
},
);
};