@@ -245,10 +245,8 @@ module Model = struct
245245 context.push (to_chunk (Debug_ref (`String debug_info_ref)) current_index) |> ignore
246246 else ()
247247
248- let rec element_to_payload ~context ?(debug = false ) ~to_chunk ~env element =
249- let is_root = ref true in
250-
251- let rec turn_element_into_payload ~context element =
248+ let rec element_to_payload ?(debug = false ) ~context ~is_root ~to_chunk ~env element =
249+ let rec turn_element_into_payload ~context ~is_root element =
252250 match (element : React.element ) with
253251 | Empty -> `Null
254252 | DangerouslyInnerHtml _ ->
@@ -272,35 +270,28 @@ module Model = struct
272270 attributes
273271 in
274272 let props = props_to_json attributes in
275- node ~key ~tag ~props (List. map (turn_element_into_payload ~context ) children)
276- | Fragment children ->
277- if is_root.contents then is_root := false ;
278- turn_element_into_payload ~context children
279- | List children ->
280- if is_root.contents then is_root := false ;
281- `List (List. map (turn_element_into_payload ~context ) children)
282- | Array children ->
283- if is_root.contents then is_root := false ;
284- `List (Array. map (turn_element_into_payload ~context ) children |> Array. to_list)
273+ node ~key ~tag ~props (List. map (turn_element_into_payload ~context ~is_root ) children)
274+ | Fragment children -> turn_element_into_payload ~context ~is_root: false children
275+ | List children -> `List (List. map (turn_element_into_payload ~context ~is_root: false ) children)
276+ | Array children -> `List (Array. map (turn_element_into_payload ~context ~is_root: false ) children |> Array. to_list)
285277 | Upper_case_component (name , component ) -> (
286278 (* TODO: Get the stack info from component *)
287279 match component () with
288280 | element ->
289281 (* TODO: Can we remove the is_root difference. It currently align with react.js behavior, but it's not clear what is the purpose of it *)
290- if is_root.contents then (
291- is_root := false ;
282+ if is_root then (
292283 (*
293284 If it's the root element, React returns the element payload instead of a reference value.
294285 Root is a special case: https://github.com/facebook/react/blob/f3a803617ec4ba9d14bf5205ffece28ed1496a1d/packages/react-server/src/ReactFlightServer.js#L756-L766
295286 *)
296287 if debug then push_debug_info ~context ~to_chunk ~env ~index: 0 ~owner Name:name else () ;
297- turn_element_into_payload ~context element)
288+ turn_element_into_payload ~context ~is_root: false element)
298289 else
299290 (* If it's not the root React push the element to the stream and return the reference value *)
300291 let element_index =
301292 Stream. push ~context (fun index ->
302293 if debug then push_debug_info ~context ~to_chunk ~env ~index ~owner Name:name else () ;
303- let payload = turn_element_into_payload ~context element in
294+ let payload = turn_element_into_payload ~context ~is_root element in
304295 to_chunk (Value payload) index)
305296 in
306297 `String (ref_value element_index)
@@ -318,12 +309,12 @@ module Model = struct
318309 let error = make_error ~message ~stack ~digest: " " in
319310 let index = Stream. push ~context (to_chunk (Error (env, error))) in
320311 `String (lazy_value index)
321- | Return element -> turn_element_into_payload ~context element
312+ | Return element -> turn_element_into_payload ~context ~is_root: false element
322313 | Sleep ->
323314 let promise =
324315 try % lwt
325316 let % lwt element = promise in
326- Lwt. return (to_chunk (Value (turn_element_into_payload ~context element)))
317+ Lwt. return (to_chunk (Value (turn_element_into_payload ~context ~is_root element)))
327318 with exn ->
328319 let message = Printexc. to_string exn in
329320 let stack = create_stack_trace () in
@@ -335,29 +326,26 @@ module Model = struct
335326 | Suspense { key; children; fallback } ->
336327 (* TODO: Need to check is_root? *)
337328 (* TODO: Maybe we need to push suspense index and suspense node separately *)
338- let fallback = turn_element_into_payload ~context fallback in
339- suspense_node ~key ~fallback [ turn_element_into_payload ~context children ]
329+ let fallback = turn_element_into_payload ~context ~is_root fallback in
330+ suspense_node ~key ~fallback [ turn_element_into_payload ~context ~is_root children ]
340331 | Client_component { import_module; import_name; props; client = _ } ->
341332 let ref = component_ref ~module_: import_module ~name: import_name in
342333 let index = Stream. push ~context (to_chunk (Component_ref ref )) in
343- let client_props = client_values_to_json ~context ~to_chunk ~env props in
334+ let client_props = models_to_payload ~context ~to_chunk ~env props in
344335 node ~tag: (ref_value index) ~props: client_props []
345336 (* TODO: Do we need to do anything with Provider and Consumer? *)
346- | Provider children -> turn_element_into_payload ~context children
347- | Consumer children -> turn_element_into_payload ~context children
337+ | Provider children -> turn_element_into_payload ~context ~is_root children
338+ | Consumer children -> turn_element_into_payload ~context ~is_root children
348339 in
349- turn_element_into_payload ~context element
340+ turn_element_into_payload ~context ~is_root element
350341
351- and client_value_to_json ~context ?debug ~to_chunk ~env value =
352- match (value : React.client_value ) with
342+ and model_to_payload ~context ?debug ~ is_root ~to_chunk ~env value =
343+ match (value : React.model_value ) with
353344 | Json json -> json
354345 | Error error ->
355346 let index = Stream. push ~context (to_chunk (Error (env, error))) in
356347 `String (error_value index)
357- | Element element ->
358- let payload = element_to_payload ~context ?debug ~to_chunk ~env element in
359- let index = Stream. push ~context (to_chunk (Value payload)) in
360- `String (ref_value index)
348+ | Element element -> element_to_payload ~context ?debug ~is_root ~to_chunk ~env element
361349 | Promise (promise , value_to_json ) -> (
362350 match Lwt. state promise with
363351 | Return value ->
@@ -380,20 +368,28 @@ module Model = struct
380368 | Fail exn ->
381369 (* TODO: https://github.com/ml-in-barcelona/server-reason-react/issues/251 *)
382370 raise exn )
371+ | List list ->
372+ let list = List. map (fun element -> model_to_payload ~context ~is_root ~to_chunk ~env element) list in
373+ `List list
374+ | Assoc assoc ->
375+ let assoc =
376+ List. map (fun (name , value ) -> (name, model_to_payload ~context ~is_root ~to_chunk ~env value)) assoc
377+ in
378+ `Assoc assoc
383379 | Function action ->
384380 let index = Stream. push ~context (to_chunk (Value (`Assoc [ (" id" , `String action.id); (" bound" , `Null ) ]))) in
385381 `String (action_value index)
386382
387- and client_values_to_json ~context ~to_chunk ~env props =
388- List. map (fun (name , value ) -> (name, client_value_to_json ~context ~to_chunk ~env value)) props
383+ and models_to_payload ~context ~to_chunk ~env props =
384+ List. map (fun (name , value ) -> (name, model_to_payload ~context ~is_root: false ~to_chunk ~env value)) props
389385
390- let render ?(env = `Dev ) ?(debug = false ) ?subscribe element =
386+ let render ?(env = `Dev ) ?(debug = false ) ?subscribe model =
391387 let stream, context = Stream. make () in
392- let to_root_chunk element id =
393- let payload = element_to_payload ~debug ~context ~to_chunk ~env element in
388+ let to_root_chunk model id =
389+ let payload = model_to_payload ~debug ~is_root: true ~ context ~to_chunk ~env model in
394390 to_chunk (Value payload) id
395391 in
396- Stream. push ~context (to_root_chunk element ) |> ignore;
392+ Stream. push ~context (to_root_chunk model ) |> ignore;
397393 if context.pending = 0 then context.close () ;
398394 match subscribe with None -> Lwt. return () | Some subscribe -> Lwt_stream. iter_s subscribe stream
399395
@@ -405,11 +401,11 @@ module Model = struct
405401 let stack = create_stack_trace () in
406402 (* TODO: Improve it to be an UUID *)
407403 let digest = stack |> Hashtbl. hash |> Int. to_string in
408- Lwt. return (React. Error { message; stack; env = " Server" ; digest })
404+ Lwt. return (React.Model. Error { message; stack; env = " Server" ; digest })
409405 in
410406 let stream, context = Stream. make () in
411407 let to_root_chunk value id =
412- let payload = client_value_to_json ~debug ~context ~to_chunk ~env value in
408+ let payload = model_to_payload ~debug ~is_root: true ~context ~to_chunk ~env value in
413409 to_chunk (Value payload) id
414410 in
415411 Stream. push ~context (to_root_chunk response) |> ignore;
@@ -563,7 +559,7 @@ let rec render_element_to_html ~(fiber : Fiber.t) (element : React.element) : (H
563559 | Client_component { import_module; import_name; props; client } ->
564560 let context = fiber.context in
565561 let env = fiber.env in
566- let props = Model. client_values_to_json ~context ~to_chunk: model_to_chunk ~env props in
562+ let props = Model. models_to_payload ~context ~to_chunk: model_to_chunk ~env props in
567563 let % lwt html = client_to_html ~fiber client in
568564 let ref : json = Model. component_ref ~module_: import_module ~name: import_name in
569565 let index = Stream. push ~context (model_to_chunk (Component_ref ref )) in
@@ -929,8 +925,8 @@ let decodeFormDataReply formData =
929925 (args, aux (Js.FormData. make () ) formDataEntries)
930926
931927type server_function =
932- | FormData of (Yojson.Basic .t array -> Js.FormData .t -> React .client_value Lwt .t )
933- | Body of (Yojson.Basic .t array -> React .client_value Lwt .t )
928+ | FormData of (Yojson.Basic .t array -> Js.FormData .t -> React .model_value Lwt .t )
929+ | Body of (Yojson.Basic .t array -> React .model_value Lwt .t )
934930
935931module type FunctionReferences = sig
936932 type t
0 commit comments