This commit is contained in:
2026-03-14 07:05:56 +01:00
parent c8bb7585ee
commit 9c57ea69f2
8 changed files with 149 additions and 0 deletions

1
.gitignore vendored
View File

@@ -10,3 +10,4 @@ input.txt
greek.csv
node_modules
target
_build

3
ocaml/README.md Normal file
View File

@@ -0,0 +1,3 @@
_Climbing on the camel's back._ 🐫
Experiments with OCaml, inspired by [Bobkonf](https://bobkonf.de) 2026.

5
ocaml/dune Normal file
View File

@@ -0,0 +1,5 @@
(executable
(name main)
(modes js)
(libraries js_of_ocaml)
(preprocess (pps js_of_ocaml-ppx)))

2
ocaml/dune-project Normal file
View File

@@ -0,0 +1,2 @@
(lang dune 3.10)
(name ocaml_js_demo)

27
ocaml/flake.lock generated Normal file
View File

@@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1773282481,
"narHash": "sha256-b/GV2ysM8mKHhinse2wz+uP37epUrSE+sAKXy/xvBY4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "fe416aaedd397cacb33a610b33d60ff2b431b127",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

73
ocaml/flake.nix Normal file
View File

@@ -0,0 +1,73 @@
{
description = "OCaml -> JavaScript demo using js_of_ocaml";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs =
{ self, nixpkgs }:
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
in
{
devShells.${system}.default = pkgs.mkShell {
packages = with pkgs; [
ocaml
dune_3
ocamlPackages.js_of_ocaml
ocamlPackages.js_of_ocaml-compiler
nodejs
tmux
ocamlPackages.ocaml-lsp
ocamlPackages.ocamlformat
(pkgs.writeShellApplication {
name = "dev";
runtimeInputs = [ dune nodejs tmux ];
text = ''
SESSION=ocaml-js
tmux new-session -d -s "$SESSION"
tmux new-window -t "$SESSION" -n build
tmux send-keys -t "$SESSION:0" "dune build main.bc.js --watch" C-m
tmux new-window -t "$SESSION" -n server
tmux send-keys -t "$SESSION:1" "npx live-server result" C-m
tmux attach -t "$SESSION"
'';
})
];
shellHook = ''
echo "Run 'dev' to start tmux dev environment."
'';
};
packages.${system}.default = pkgs.stdenv.mkDerivation {
pname = "ocaml-js-demo";
version = "0.1";
src = ./.;
nativeBuildInputs = with pkgs; [
ocaml
dune_3
ocamlPackages.js_of_ocaml
ocamlPackages.js_of_ocaml-compiler
ocamlPackages.js_of_ocaml-ppx
];
buildPhase = ''
dune build main.bc.js
'';
installPhase = ''
mkdir -p $out
cp _build/default/main.bc.js $out/
cp index.html $out/
'';
};
};
}

15
ocaml/index.html Normal file
View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>OCaml DOM demo</title>
</head>
<body>
<h1 id="title">OCaml DOM Demo</h1>
<button id="btn">Click me</button>
<p id="output"></p>
<script src="main.bc.js"></script>
</body>
</html>

23
ocaml/main.ml Normal file
View File

@@ -0,0 +1,23 @@
open Js_of_ocaml
(* open Js_of_ocaml.Dom_html *)
let document = Dom_html.document
let by_id id =
Js.Opt.get
(document##getElementById (Js.string id))
(fun () -> failwith ("Missing element: " ^ id))
let () =
let button = by_id "btn" in
let output = by_id "output" in
let clicks = ref 0 in
button##.onclick :=
Dom_html.handler (fun _ ->
incr clicks;
output##.textContent :=
Js.some (Js.string ("Clicked " ^ string_of_int !clicks ^ " times"));
Js._false
)