blob: cbf70d7c7b9bbf81f340d3de5cc714d38a957a5a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
Core Architecture
server.re - Main entry point:
- Uses Dream web framework (OCaml's web server)
- Sets up routing with getAndPost helper for progressive enhancement
- Serves static assets (CSS, JS) and handles React rendering
Key Libraries (from dune file):
- dream - Web framework
- react/reactDOM - Native React implementation
- demo_shared_native - Shared components
- lwt.unix - Async I/O
- yojson - JSON handling
Rendering Pipeline
Three rendering modes:
1. renderToString - Basic SSR (line 28-31)
2. renderToStaticMarkup - No hydration attributes (line 34-38)
3. renderToStream - Streaming SSR with React Server Components
React Server Components (RSC)
DreamRSC.re handles the magic:
Content negotiation:
switch (Dream.header(request, "Accept")) {
| Some(accept) when is_react_component_header(accept) =>
stream_model(~location=Dream.target(request), app) (* RSC payload *)
| _ =>
stream_html(~bootstrapScripts, app) (* Full HTML *)
Server Actions (lines 50-87):
- Reads ACTION_ID header
- Decodes form data or request body
- Calls registered server function via FunctionReferences.get
- Streams response back as application/react.action
Request Flow
1. Client request → Dream router
2. Accept header check → RSC payload vs HTML
3. Server function lookup → FunctionReferences registry
4. Component rendering → ReactServerDOM.render_model/render_html
5. Streaming response → Chunks sent via Dream.write
File Structure in OCaml syntax:
(* Main server setup *)
let server =
Dream.logger (
Dream.router [
get_and_post "/" Pages.Home.handler;
Dream.get "/static/**" (Dream.static "./build/client");
(* ... more routes *)
]
)
(* Page handler example *)
let handler _request =
let app = Document.make [
Html.h1 [React.string "Hello"]
] in
Dream.html (ReactDOM.renderToStaticMarkup app)
The beauty is it's a standard Dream web server that happens to render React components natively, with RSC streaming as an enhancement
layer on top!
|