package bonsai

  1. Overview
  2. Docs
A library for building dynamic webapps, using Js_of_ocaml

Install

Dune Dependency

Authors

Maintainers

Sources

v0.15.1.tar.gz
sha256=0c4a714146073f421f1a6179561f836b45d8dc012c743207d3481ea63bef74bf

doc/src/bonsai/legacy_api.ml.html

Source file legacy_api.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
open! Core
open! Import

module type S = Module_types.Component_s

type ('i, 'r) t = 'i Proc.Value.t -> 'r Proc.Computation.t

module type Model = Model
module type Action = Action

let const x _ = Proc.const x
let input = Proc.read
let pure ~f i = Proc.read (Proc.Value.map i ~f)
let compose a b i = Proc.Let_syntax.Let_syntax.sub (a i) ~f:b

let map a ~f i =
  Proc.Let_syntax.Let_syntax.sub (a i) ~f:(fun x -> Proc.read (Proc.Value.map ~f x))
;;

let map_input a ~f i = a (Proc.Value.map i ~f)
let of_module = Proc.of_module1
let state_machine model action here = Proc.state_machine1 here model action

let both a b i =
  let open Proc.Let_syntax in
  let%sub a = a i in
  let%sub b = b i in
  return (Proc.Value.both a b)
;;

let enum m ~which ~handle input =
  let match_ = Proc.Value.map input ~f:which in
  let with_ key = handle key input in
  Proc.enum m ~match_ ~with_
;;

let if_ choose ~then_ ~else_ input =
  let open Proc.Let_syntax in
  let cond = Proc.Value.map input ~f:choose in
  if%sub cond then then_ input else else_ input
;;

module Map = struct
  let assoc_input comparator f input = Proc.assoc comparator input ~f:(fun _ -> f)

  let associ_input comparator f input =
    Proc.assoc comparator input ~f:(fun key data -> f (Proc.Value.both key data))
  ;;

  let associ_input_with_extra comparator f input =
    let open Proc.Let_syntax in
    let%pattern_bind input, extra = input in
    Proc.assoc comparator input ~f:(fun key data ->
      f (Tuple3.create <$> key <*> data <*> extra))
  ;;
end

include struct
  open Proc.Let_syntax

  let arr f = pure ~f
  let ( >>^ ) a f = map a ~f
  let ( ^>> ) a f = map_input a ~f

  let first f i =
    let%pattern_bind fst, snd = i in
    let%sub out = f fst in
    return (Proc.Value.both out snd)
  ;;

  let second f i =
    let%pattern_bind fst, snd = i in
    let%sub out = f snd in
    return (Proc.Value.both fst out)
  ;;

  let split f1 f2 i =
    let%pattern_bind fst, snd = i in
    let%sub out1 = f1 fst in
    let%sub out2 = f2 snd in
    return (Proc.Value.both out1 out2)
  ;;

  let extend_first f i =
    let%sub out = f i in
    return (Proc.Value.both out i)
  ;;

  let extend_second f i =
    let%sub out = f i in
    return (Proc.Value.both i out)
  ;;

  let fanout f1 f2 i =
    let%sub out1 = f1 i in
    let%sub out2 = f2 i in
    return (Proc.Value.both out1 out2)
  ;;

  let partial_compose_first f1 f2 i =
    let%sub out1 = f1 i in
    let%pattern_bind shared, out1 = out1 in
    let%sub out2 = f2 (Proc.Value.both i shared) in
    return (Proc.Value.both out1 out2)
  ;;

  let pipe f1 ~into ~via ~finalize i =
    let%sub r1 = f1 i in
    let intermediate = via <$> i <*> r1 in
    let%sub r2 = into intermediate in
    return (finalize <$> i <*> r1 <*> r2)
  ;;

  let ( *** ) = split
  let ( &&& ) = fanout
end

module With_incr = struct
  let of_incr i _ = Proc.read (Proc.Private.conceal_value (Value.of_incr i))

  let of_module
        (type i m a r)
        (component : (i, m, a, r) component_s_incr)
        ~default_model
        input
    : r Proc.Computation.t
    =
    let input = Proc.Private.reveal_value input in
    let (module M) = component in
    let t =
      Computation.Leaf_incr
        { input
        ; dynamic_apply_action = M.apply_action
        ; compute = (fun _ -> M.compute)
        ; name = M.name
        }
    in
    Computation.T
      { t
      ; model = Meta.Model.of_module (module M.Model) ~name:M.name ~default:default_model
      ; dynamic_action = Meta.Action.of_module (module M.Action) ~name:M.name
      ; static_action = Meta.Action.nothing
      ; apply_static = Proc.unusable_static_apply_action
      }
    |> Proc.Private.conceal_computation
  ;;

  let pure (type i r) ~f =
    of_module
      (module struct
        module Input = struct
          type t = i
        end

        module Result = struct
          type t = r
        end

        module Model = Unit
        module Action = Nothing

        let name = "pure"
        let apply_action _ ~inject:_ = Incr.return (fun ~schedule_event:_ _ _ -> ())
        let compute input _ ~inject:_ = f input
      end)
      ~default_model:()
  ;;

  let map a ~f = compose a (pure ~f)
  let model_cutoff f a = Proc.Incr.model_cutoff (f a)

  let value_cutoff ~cutoff =
    map input ~f:(fun input ->
      let input = Incr.map input ~f:Fn.id in
      Incr.set_cutoff input cutoff;
      input)
  ;;
end

module Infix = struct
  let ( >>> ) = compose
  let ( >>| ) a f = map a ~f
  let ( @>> ) f a = map_input a ~f
end

module Let_syntax = struct
  let return = const
  let map = map
  let both = both

  include Infix

  module Let_syntax = struct
    let return = const
    let both = both
    let map = map

    module Open_on_rhs = Infix
  end
end
OCaml

Innovation. Community. Security.