From 71c20233ff79e696d0eeca2ce1462d3083fbcfed Mon Sep 17 00:00:00 2001 From: polwex Date: Sun, 15 Jun 2025 04:59:49 +0700 Subject: and were done, just like that --- bs5/server/pages/Comments.re | 118 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 bs5/server/pages/Comments.re (limited to 'bs5/server/pages/Comments.re') diff --git a/bs5/server/pages/Comments.re b/bs5/server/pages/Comments.re new file mode 100644 index 0000000..6af39ff --- /dev/null +++ b/bs5/server/pages/Comments.re @@ -0,0 +1,118 @@ +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); + }, + ); +}; -- cgit v1.2.3