carlos / todomvc-bakeoff Public
LIVE https://todo-ocaml.bfj.oncarlos.com a24ca85
Checks
make test: 16 Alcotest tests pass (form parsing, Unicode trimming, escaping, and the request handler against an in-memory database).- Shared suite against
dist/app --listen 127.0.0.1: 67 passed, 3 skipped (the two JS-only edit tests with JS off, and the screenshot with JS off). scripts/boot-check.sh dist/app-linux-arm64: /healthz and /api/version 200, clean exit on SIGTERM.- Deployed with
make deploy;/api/versionreportsa24ca85. - Shared suite against https://todo-ocaml.bfj.oncarlos.com: 67 passed, 3 skipped.
Review fixes (a24ca85)
- Unbounded request heads.
bin/main.mlnow runs cohttp-eio's per-connection loop itself instead ofCohttp_eio.Server.run(which hard-codesmax_size:max_int). Each connection reads through a byte budget: 64 KiB for a request line plus headers, then 1 MiB + 64 KiB per request after that, with at most 256 connections. Checked locally: a 10 MB header line and 100,000 small headers both get431 Request Header Fields Too Large, and the process stays at about 17 MB RSS. - Edits lost on re-render.
app.jskeeps an open editor across a response: the same item stays in edit mode with its unsaved text, focus and selection, and losing focus during the swap doesn't count as a save. Checked in Chromium with a toggle response held back while another item was being edited. - Unicode whitespace.
Form.trimstrips Unicode White_Space (plus U+FEFF) and is used for both adding and editing. A title of only non-breaking spaces adds nothing, and editing to one deletes the item. - SQLite from source.
tools/sqlite.shdownloads the SQLite 3.54.1 amalgamation once into.cache/src(checked against sqlite.org's SHA3-256) and compiles it into.cache/sqlite-<arch>. Thesqlite3opam package finds it throughpkg-config.make clean-depsdeletes those builds and keeps the tarball. The shipped binary contains SQLite 3.54.1 (source id 2026-10-16), not the arm64 root's 3.46.1.
Notes
- The shipped binary is static glibc (aarch64), built in the emulated arm64 root with Debian's OCaml 5.3.0 as
ocaml-system. The linker warns aboutgetpwnam,gethostbynameand the like (pulled in by OCaml'sunixlibrary). The app never calls them. make clean-deps && make build-arm64took 20.5 minutes here: SQLite and every OCaml library compiled under qemu. After that, a rebuild of the app alone takes about 15 seconds.- docs-t1 has no
pkg-config, so the x86 build unpacks Debian'spkgconfinto.cache/withapt-get download(see README).