package server-reason-react
Rendering React components on the server natively
Install
Dune Dependency
Authors
Maintainers
Sources
server-reason-react-0.3.1.tbz
sha256=b97fbe6a7c3e5e1a7775e0f6498f257acaaa7e272177a9a3e0e50b7a49408d7c
sha512=b27a94618c367c80efef83a41c2a59c9cc7848fd753049ed40fa1f2cface1ef34cf3a995835bf08e2eb59c3186911f429b4706ed07dcb9724df6af5eb012a31d
doc/src/server-reason-react.react/React.ml.html
Source file React.ml
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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668
type domRef type 'value ref = { mutable current : 'value } module Ref = struct type t = domRef type currentDomRef = Dom.element Js.nullable ref type callbackDomRef = Dom.element Js.nullable -> unit external domRef : currentDomRef -> domRef = "%identity" external callbackDomRef : callbackDomRef -> domRef = "%identity" end let createRef () = { current = None } let useRef value = { current = value } let forwardRef f = f () module Event = struct type 'a synthetic module MakeEventWithType (Type : sig type t end) = struct let bubbles : Type.t -> bool = fun _ -> false let cancelable : Type.t -> bool = fun _ -> false let currentTarget : Type.t -> < .. > Js.t = fun _ -> object end let defaultPrevented : Type.t -> bool = fun _ -> false let eventPhase : Type.t -> int = fun _ -> 0 let isTrusted : Type.t -> bool = fun _ -> false let nativeEvent : Type.t -> < .. > Js.t = fun _ -> object end let preventDefault : Type.t -> unit = fun _ -> () let isDefaultPrevented : Type.t -> bool = fun _ -> false let stopPropagation : Type.t -> unit = fun _ -> () let isPropagationStopped : Type.t -> bool = fun _ -> false let target : Type.t -> < .. > Js.t = fun _ -> object end let timeStamp : Type.t -> float = fun _ -> 0. let type_ : Type.t -> string = fun _ -> "" let persist : Type.t -> unit = fun _ -> () end module Synthetic = struct type tag type t = tag synthetic let bubbles : 'a synthetic -> bool = fun _ -> false let cancelable : 'a synthetic -> bool = fun _ -> false let currentTarget : 'a synthetic -> < .. > Js.t = fun _ -> object end let defaultPrevented : 'a synthetic -> bool = fun _ -> false let eventPhase : 'a synthetic -> int = fun _ -> 0 let isTrusted : 'a synthetic -> bool = fun _ -> false let nativeEvent : 'a synthetic -> < .. > Js.t = fun _ -> object end let preventDefault : 'a synthetic -> unit = fun _ -> () let isDefaultPrevented : 'a synthetic -> bool = fun _ -> false let stopPropagation : 'a synthetic -> unit = fun _ -> () let isPropagationStopped : 'a synthetic -> bool = fun _ -> false let target : 'a synthetic -> < .. > Js.t = fun _ -> object end let timeStamp : 'a synthetic -> float = fun _ -> 0. let type_ : 'a synthetic -> string = fun _ -> "" let persist : 'a synthetic -> unit = fun _ -> () end (* let toSyntheticEvent : 'a synthetic -> Synthetic.t = i -> i *) module Clipboard = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) let clipboardData : t -> < .. > Js.t = fun _ -> object end end module Composition = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) let data : t -> string = fun _ -> "" end module Keyboard = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) let altKey : t -> bool = fun _ -> false let charCode : t -> int = fun _ -> 0 let ctrlKey : t -> bool = fun _ -> false let getModifierState : t -> string -> bool = fun _ _ -> false let key : t -> string = fun _ -> "" let keyCode : t -> int = fun _ -> 0 let locale : t -> string = fun _ -> "" let location : t -> int = fun _ -> 0 let metaKey : t -> bool = fun _ -> false let repeat : t -> bool = fun _ -> false let shiftKey : t -> bool = fun _ -> false let which : t -> int = fun _ -> 0 end module Focus = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) let : t -> < .. > Js.t option = fun _ -> None end module Form = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) end module Mouse = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) let altKey : t -> bool = fun _ -> false let : t -> int = fun _ -> 0 let : t -> int = fun _ -> 0 let clientX : t -> int = fun _ -> 0 let clientY : t -> int = fun _ -> 0 let ctrlKey : t -> bool = fun _ -> false let getModifierState : t -> string -> bool = fun _ _ -> false let metaKey : t -> bool = fun _ -> false let movementX : t -> int = fun _ -> 0 let movementY : t -> int = fun _ -> 0 let pageX : t -> int = fun _ -> 0 let pageY : t -> int = fun _ -> 0 let : t -> < .. > Js.t option = fun _ -> None let screenX : t -> int = fun _ -> 0 let screenY : t -> int = fun _ -> 0 let shiftKey : t -> bool = fun _ -> false end module Pointer = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) let detail : t -> int = fun _ -> 0 (* let view : t -> Dom.window = fun _ -> object end *) let screenX : t -> int = fun _ -> 0 let screenY : t -> int = fun _ -> 0 let clientX : t -> int = fun _ -> 0 let clientY : t -> int = fun _ -> 0 let pageX : t -> int = fun _ -> 0 let pageY : t -> int = fun _ -> 0 let movementX : t -> int = fun _ -> 0 let movementY : t -> int = fun _ -> 0 let ctrlKey : t -> bool = fun _ -> false let shiftKey : t -> bool = fun _ -> false let altKey : t -> bool = fun _ -> false let metaKey : t -> bool = fun _ -> false let getModifierState : t -> string -> bool = fun _ _ -> false let : t -> int = fun _ -> 0 let : t -> int = fun _ -> 0 let : t -> < .. > Js.t option = fun _ -> None (* let pointerId : t -> Dom.eventPointerId *) let width : t -> float = fun _ -> 0. let height : t -> float = fun _ -> 0. let pressure : t -> float = fun _ -> 0. let tangentialPressure : t -> float = fun _ -> 0. let tiltX : t -> int = fun _ -> 0 let tiltY : t -> int = fun _ -> 0 let twist : t -> int = fun _ -> 0 let pointerType : t -> string = fun _ -> "" let isPrimary : t -> bool = fun _ -> false end module Selection = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) end module Touch = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) let altKey : t -> bool = fun _ -> false let changedTouches : t -> < .. > Js.t = fun _ -> object end let ctrlKey : t -> bool = fun _ -> false let getModifierState : t -> string -> bool = fun _ _ -> false let metaKey : t -> bool = fun _ -> false let shiftKey : t -> bool = fun _ -> false let targetTouches : t -> < .. > Js.t = fun _ -> object end let touches : t -> < .. > Js.t = fun _ -> object end end module UI = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) let detail : t -> int = fun _ -> 0 (* let view : t -> Dom.window *) end module Wheel = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) let deltaMode : t -> int = fun _ -> 0 let deltaX : t -> float = fun _ -> 0. let deltaY : t -> float = fun _ -> 0. let deltaZ : t -> float = fun _ -> 0. end module Media = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) end module Image = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) end module Animation = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) let animationName : t -> string = fun _ -> "" let pseudoElement : t -> string = fun _ -> "" let elapsedTime : t -> float = fun _ -> 0. end module Transition = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) let propertyName : t -> string = fun _ -> "" let pseudoElement : t -> string = fun _ -> "" let elapsedTime : t -> float = fun _ -> 0. end module Drag = struct type tag type t = tag synthetic include MakeEventWithType (struct type nonrec t = t [@@nonrec] end) let altKey : t -> bool = fun _ -> false let : t -> int = fun _ -> 0 let : t -> int = fun _ -> 0 let clientX : t -> int = fun _ -> 0 let clientY : t -> int = fun _ -> 0 let ctrlKey : t -> bool = fun _ -> false let getModifierState : t -> string -> bool = fun _ _ -> false let metaKey : t -> bool = fun _ -> false let movementX : t -> int = fun _ -> 0 let movementY : t -> int = fun _ -> 0 let pageX : t -> int = fun _ -> 0 let pageY : t -> int = fun _ -> 0 let : t -> < .. > Js.t option = fun _ -> None let screenX : t -> int = fun _ -> 0 let screenY : t -> int = fun _ -> 0 let shiftKey : t -> bool = fun _ -> false let dataTransfer : t -> < .. > Js.t option = fun _ -> None end end module JSX = struct type event = | Drag of (Event.Drag.t -> unit) | Mouse of (Event.Mouse.t -> unit) | Selection of (Event.Selection.t -> unit) | Touch of (Event.Touch.t -> unit) | UI of (Event.UI.t -> unit) | Wheel of (Event.Wheel.t -> unit) | Clipboard of (Event.Clipboard.t -> unit) | Composition of (Event.Composition.t -> unit) | Transition of (Event.Transition.t -> unit) | Animation of (Event.Animation.t -> unit) | Pointer of (Event.Pointer.t -> unit) | Keyboard of (Event.Keyboard.t -> unit) | Focus of (Event.Focus.t -> unit) | Form of (Event.Form.t -> unit) | Media of (Event.Media.t -> unit) | Inline of string type prop = | Bool of (string * bool) | String of (string * string) | Style of string | DangerouslyInnerHtml of string | Ref of Ref.t | Event of string * event let bool key value = Bool (key, value) let string key value = String (key, value) let style value = Style value let int key value = String (key, string_of_int value) let float key value = String (key, string_of_float value) let dangerouslyInnerHtml value = DangerouslyInnerHtml value#__html let ref value = Ref value let event key value = Event (key, value) module Event = struct let drag key value = event key (Drag value) let mouse key value = event key (Mouse value) let selection key value = event key (Selection value) let touch key value = event key (Touch value) let ui key value = event key (UI value) let wheel key value = event key (Wheel value) let clipboard key value = event key (Clipboard value) let composition key value = event key (Composition value) let transition key value = event key (Transition value) let animation key value = event key (Animation value) let pointer key value = event key (Pointer value) let keyboard key value = event key (Keyboard value) let focus key value = event key (Focus value) let form key value = event key (Form value) let media key value = event key (Media value) end end type lower_case_element = { tag : string; attributes : JSX.prop list; children : element list; } and element = | Lower_case_element of lower_case_element | Upper_case_component of (unit -> element) | List of element array | Text of string | InnerHtml of string | Fragment of element | Empty | Provider of element | Consumer of element | Suspense of { children : element; fallback : element } exception Invalid_children of string let compare_attribute left right = match (left, right) with | JSX.Bool (left_key, _), JSX.Bool (right_key, _) -> String.compare left_key right_key | String (left_key, _), String (right_key, _) -> String.compare left_key right_key | Style left_styles, Style right_styles -> String.compare left_styles right_styles | _ -> 0 let clone_attribute acc attr new_attr = let open JSX in match (attr, new_attr) with | Bool (left, _), Bool (right, value) when left == right -> Bool (left, value) :: acc | String (left, _), String (right, value) when left == right -> String (left, value) :: acc | _ -> new_attr :: acc module StringMap = Map.Make (String) let attributes_to_map attributes = let open JSX in List.fold_left (fun acc attr -> match attr with | Bool (key, value) -> acc |> StringMap.add key (Bool (key, value)) | String (key, value) -> acc |> StringMap.add key (String (key, value)) (* The following constructors shoudn't be part of the Map: *) | DangerouslyInnerHtml _ -> acc | Ref _ -> acc | Event _ -> acc | Style _ -> acc) StringMap.empty attributes let clone_attributes attributes new_attributes = let attribute_map = attributes_to_map attributes in let new_attribute_map = attributes_to_map new_attributes in StringMap.merge (fun _key attr new_attr -> match (attr, new_attr) with | Some attr, Some new_attr -> Some (clone_attribute [] attr new_attr) | Some attr, None -> Some [ attr ] | None, Some new_attr -> Some [ new_attr ] | None, None -> None) attribute_map new_attribute_map |> StringMap.bindings |> List.map (fun (_, attrs) -> attrs) |> List.flatten |> List.rev |> List.sort compare_attribute let create_element_inner tag attributes children = let dangerouslySetInnerHTML = List.find_opt (function JSX.DangerouslyInnerHtml _ -> true | _ -> false) attributes in let children = match (dangerouslySetInnerHTML, children) with | None, children -> children | Some (JSX.DangerouslyInnerHtml innerHtml), [] -> (* This adds as children the innerHTML, and we treat it differently from Element.Text to avoid encoding to HTML their content *) [ InnerHtml innerHtml ] | Some _, _children -> raise (Invalid_children tag) in Lower_case_element { tag; attributes; children } let createElement tag attributes children = match Html.is_self_closing_tag tag with | true when List.length children > 0 -> (* TODO: Add test for this *) raise @@ Invalid_children "closing tag with children isn't valid" | true -> Lower_case_element { tag; attributes; children = [] } | false -> create_element_inner tag attributes children (* cloneElements overrides childrens but is not always obvious what to do with Provider, Consumer or Suspense. TODO: Check original (JS) implementation *) let cloneElement element new_attributes = match element with | Lower_case_element { tag; attributes; children } -> Lower_case_element { tag; attributes = clone_attributes attributes new_attributes; children; } | Fragment _childrens -> Fragment _childrens | Text t -> Text t | InnerHtml t -> InnerHtml t | Empty -> Empty | List l -> List l | Provider child -> Provider child | Consumer child -> Consumer child | Upper_case_component f -> Upper_case_component f | Suspense { fallback; children } -> Suspense { fallback; children } module Fragment = struct let make ~children ?key:_ () = Fragment children end let fragment children = Fragment.make ~children ?key:None () (* ReasonReact APIs *) let string txt = Text txt let null = Empty let int i = Text (string_of_int i) (* FIXME: float_of_string might be different from the browser *) let float f = Text (string_of_float f) let array arr = List arr let list_to_array list = let rec to_array i res = match i < 0 with | true -> res | false -> let item = List.nth list i in let rest = Array.append [| item |] res in to_array (i - 1) rest in to_array (List.length list - 1) [||] let list l = List (list_to_array l) type 'a provider = value:'a -> children:element -> unit -> element type 'a context = { current_value : 'a ref; provider : 'a provider; consumer : children:element -> element; } module Context = struct type 'a t = 'a context let provider ctx = ctx.provider end let createContext (initial_value : 'a) : 'a Context.t = let ref_value = { current = initial_value } in let provider ~value ~children () = ref_value.current <- value; Provider children in let consumer ~children = Consumer children in { current_value = ref_value; provider; consumer } module Suspense = struct let or_react_null = function None -> null | Some x -> x let make ?fallback ?children () = Suspense { fallback = or_react_null fallback; children = or_react_null children } end (* let memo f : 'props * 'props -> bool = f let memoCustomCompareProps f _compare : 'props * 'props -> bool = f *) let useContext context = context.current_value.current let useState (make_initial_value : unit -> 'state) = let initial_value : 'state = make_initial_value () in let setState (fn : 'state -> 'state) = let _ = fn initial_value in () in (initial_value, setState) let internal_id = ref 0 let useId () = internal_id := !internal_id + 1; Int.to_string !internal_id let useMemo fn = fn () let useMemo0 fn = fn () let useMemo1 fn _ = fn () let useMemo2 fn _ = fn () let useMemo3 fn _ = fn () let useMemo4 fn _ = fn () let useMemo5 fn _ = fn () let useMemo6 fn _ = fn () let useCallback fn = fn let useCallback0 fn = fn let useCallback1 fn _ = fn let useCallback2 fn _ = fn let useCallback3 fn _ = fn let useCallback4 fn _ = fn let useCallback5 fn _ = fn let useCallback6 fn _ = fn let useReducer _ s = (s, fun _ -> ()) let useReducerWithMapState _ s mapper = (mapper s, fun _ -> ()) let useEffect _ = () let useEffect0 _ = () let useEffect1 _ _ = () let useEffect2 _ _ = () let useEffect3 _ _ = () let useEffect4 _ _ = () let useEffect5 _ _ = () let useEffect6 _ _ = () let useLayoutEffect0 _ = () let useLayoutEffect1 _ _ = () let useLayoutEffect2 _ _ = () let useLayoutEffect3 _ _ = () let useLayoutEffect4 _ _ = () let useLayoutEffect5 _ _ = () let useLayoutEffect6 _ _ = () module Children = struct let map element fn = match element with | List children -> Array.map fn children |> Array.to_list |> list | _ -> fn element let mapWithIndex element fn = match element with | List children -> Array.mapi (fun index element -> fn element index) children |> Array.to_list |> list | _ -> fn element 0 let forEach element fn = match element with | List children -> Array.iter fn children | _ -> let _ = fn element in () let forEachWithIndex element fn = match element with | List children -> Array.iteri (fun index element -> fn element index) children | _ -> let _ = fn element 0 in () let count element = match element with | List children -> Array.length children | Empty -> 0 | _ -> 1 let only element = match element with | List children -> if Array.length children >= 1 then Array.get children 0 else raise (Invalid_argument "Expected at least one child") | _ -> element let toArray element = [| element |] end let setDisplayName _ _ = () let useTransition () = (false, fun (_cb : unit -> unit) -> ()) let useDebugValue : 'value -> ?format:('value -> string) -> unit = fun [@warning "-16"] _ ?format:_ -> () let useDeferredValue value = value (* `exception Suspend of 'a Lwt` exceptions can't have type params, this is called existential wrapper *) type any_promise = Any_promise : 'a Lwt.t -> any_promise exception Suspend of any_promise module Experimental = struct let use promise = match Lwt.state promise with | Sleep -> raise (Suspend (Any_promise promise)) (* TODO: Fail should raise a FailedSupense and catch at renderTo* *) | Fail e -> raise e | Return v -> v end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>