-
Notifications
You must be signed in to change notification settings - Fork 26
/
B0.ml
186 lines (158 loc) · 6.44 KB
/
B0.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
open B0_kit.V000
(* OCaml library names *)
let js_of_ocaml_toplevel = B0_ocaml.libname "js_of_ocaml-toplevel"
let js_of_ocaml_compiler_runtime =
B0_ocaml.libname "js_of_ocaml-compiler.runtime"
let brr = B0_ocaml.libname "brr"
let brr_ocaml_poke = B0_ocaml.libname "brr.ocaml_poke"
let brr_ocaml_poke_ui = B0_ocaml.libname "brr.ocaml_poke_ui"
let brr_poke = B0_ocaml.libname "brr.poke"
let brr_poked = B0_ocaml.libname "brr.poked"
(* Units *)
let brr_lib =
let srcs = [`Dir ~/"src"] in
let requires = [js_of_ocaml_compiler_runtime] in
B0_ocaml.lib brr ~srcs ~requires ~doc:"Brr JavaScript FFI and browser API"
let brr_ocaml_poke_lib =
let doc = "OCaml poke objects interaction" in
let srcs = [`Dir ~/"src/ocaml_poke"] in
let requires = [brr] in
B0_ocaml.lib brr_ocaml_poke ~srcs ~requires ~doc
let brr_ocaml_poke_ui_lib =
let doc = "OCaml poke user interface (toplevel)" in
let srcs = [`Dir ~/"src/ocaml_poke_ui"] in
let requires = [brr; brr_ocaml_poke] in
B0_ocaml.lib brr_ocaml_poke_ui ~srcs ~requires ~doc
let brr_poke_lib =
let srcs = [`Dir ~/"src/poke"] in
let requires = [js_of_ocaml_compiler_runtime; js_of_ocaml_toplevel; brr] in
B0_ocaml.lib brr_poke ~srcs ~requires ~doc:"Poke explicitely"
let brr_poked_lib =
let srcs = [`Dir ~/"src/poked"] in
let requires = [brr_poke] in
B0_ocaml.lib brr_poked ~srcs ~requires ~doc:"Poke by side effect"
(* Web extension *)
let console =
let doc = "Browser developer tool OCaml console" in
let srcs =
[ `Dir ~/"src/console";
(* TODO b0: we want something like ext_js *)
`X ~/"src/console/ocaml_console.js"; (* GNGNGNGN *)
`X ~/"src/console/devtools.js";
`X ~/"src/console/highlight.pack.js" ]
in
let requires = [brr; brr_ocaml_poke; brr_ocaml_poke_ui] in
let meta =
B0_meta.empty
|> ~~ B0_jsoo.compilation_mode `Whole
|> ~~ B0_jsoo.source_map (Some `Inline)
|> ~~ B0_jsoo.compile_opts (Cmd.arg "--pretty")
in
B0_jsoo.html_page "ocaml_console" ~requires ~srcs ~meta ~doc
let test_poke =
let doc = "OCaml console test" in
let srcs = [`File ~/"test/poke.ml"; `File ~/"test/base.css"] in
let requires = [brr; brr_poked] in
let meta = B0_meta.empty |> B0_meta.tag B0_jsoo.toplevel in
B0_jsoo.html_page "test_poke" ~requires ~srcs ~meta ~doc
let top =
let doc = "In page toplevel test" in
let srcs = [
`File ~/"test/top.ml";
(* TODO js_of_ocaml chokes `File "src/console/highlight.pack.js";
TODO it's likely fixed by now. *)
`File ~/"src/console/ocaml_console.css" ] in
let requires =
[ js_of_ocaml_compiler_runtime;
brr; brr_ocaml_poke_ui; brr_poke; brr_ocaml_poke]
in
let meta =
B0_meta.empty
|> ~~ B0_jsoo.compilation_mode `Whole
|> B0_meta.tag B0_jsoo.toplevel
in
B0_jsoo.html_page "top" ~requires ~doc ~srcs ~meta
(* Tests and samples *)
let base_css = `File ~/"test/base.css"
let test ?(meta = B0_meta.empty) ?doc ?(requires = []) ?(srcs = []) src =
let srcs = `File src :: base_css :: srcs in
let requires = brr :: requires in
let name = Fpath.basename ~strip_ext:true src in
let meta =
meta |> B0_meta.(tag test) |> ~~ B0_jsoo.compile_opts Cmd.(arg "--pretty")
in
B0_jsoo.html_page name ~requires ~srcs ~meta ?doc
let test_module ?meta ?doc ?requires ?srcs top m =
let name = Fmt.str "test_%s" (String.Ascii.uncapitalize m) in
let doc = Fmt.str "Test %s.%s module" top m in
let src = Fpath.fmt "test/%s.ml" name in
test ?meta ?requires ?srcs src ~doc
let test_hello = test ~/"test/test_hello.ml" ~doc:"Brr console hello size"
let test_fact =
test ~/"test/test_fact.ml" ~doc:"Test export OCaml to JavaScript"
let test_base64 = test_module "Brr" "Base64"
let test_c2d = test_module "Brr_canvas" "C2d"
let test_clipboard = test_module "Brr_io" "Clipboard"
let test_console = test_module "Brr" "Console"
let test_file = test_module "Brr" "File"
let test_geo = test_module "Brr_io" "Geolocation"
let test_gl = test_module "Brr_canvas" "Gl"
let test_history = test_module "Brr" "History"
let test_media = test_module "Brr_io" "Media"
let test_notif = test_module "Brr_io" "Notification"
let test_webaudio = test_module "Brr_webaudio" "Audio"
let test_webcrypto = test_module "Brr_webcrypto" "Crypto"
let test_webmidi = test_module "Brr_webmidi" "Midi"
let test_webgpu = test_module "Brr_webgpu" "Gpu"
let test_worker = test_module "Brr" "Worker"
let min =
let srcs = [ `File ~/"test/min.ml"; `File ~/"test/min.html" ] in
let requires = [brr] in
B0_jsoo.html_page "min" ~requires ~srcs ~doc:"Brr minimal web page"
let nop =
let srcs = [ `File ~/"test/nop.ml" ] in
B0_jsoo.html_page "nop" ~srcs ~doc:"js_of_ocaml nop web page"
(* Actions *)
let update_console =
let doc = "Update dev console" in
B0_unit.of_action ~units:[console] ~doc "update-console" @@ fun env _ ~args ->
let jsfile = "ocaml_console.js" in
let src = B0_env.in_unit_dir env console ~/jsfile in
let dst = B0_env.in_scope_dir env Fpath.(~/"src/console" / jsfile) in
Os.File.copy ~force:true ~make_path:false src ~dst
(* Packs *)
let test_pack =
let us = [ test_console ] in
let meta = B0_meta.empty |> B0_meta.tag B0_meta.test in
B0_pack.make ~locked:false "test" ~doc:"Brr test suite" ~meta us
let is_toplevel u = B0_unit.has_tag B0_jsoo.toplevel u
let jsoo_toplevels =
let us = List.filter is_toplevel (B0_unit.list ()) in
let doc = "Units with toplevel (slow to build)" in
B0_pack.make ~locked:false "tops" ~doc us
let default =
let meta =
B0_meta.empty
|> ~~ B0_meta.authors ["The brr programmers"]
|> ~~ B0_meta.maintainers ["Daniel Bünzli <daniel.buenzl [email protected]>"]
|> ~~ B0_meta.homepage "https://erratique.ch/software/brr"
|> ~~ B0_meta.online_doc "https://erratique.ch/software/brr/doc/"
|> ~~ B0_meta.licenses ["ISC"; "BSD-3-Clause"]
|> ~~ B0_meta.repo "git+https://erratique.ch/repos/brr.git"
|> ~~ B0_meta.issues "https://github.com/dbuenzli/brr/issues"
|> ~~ B0_meta.description_tags
[ "reactive"; "declarative"; "frp"; "front-end"; "browser";
"org:erratique"]
|> ~~ B0_opam.build
{|[["ocaml" "pkg/pkg.ml" "build" "--dev-pkg" "%{dev}%"]]|}
|> ~~ B0_opam.depends
[ "ocaml", {|>= "4.08.0"|};
"ocamlfind", {|build|};
"ocamlbuild", {|build|};
"topkg", {|build & >= "1.0.3"|};
"js_of_ocaml-compiler", {|>= "5.5.0"|};
"js_of_ocaml-toplevel", {|>= "5.5.0"|} ]
|> B0_meta.tag B0_opam.tag
in
B0_pack.make "default" ~doc:"brr package" ~meta ~locked:true @@
List.filter (Fun.negate is_toplevel) (B0_unit.list ())