Sesame x OCurrent
Sesame
is a platform-agnostic tool providing a set of utilities for building websites. OCurrent is a tool for building data-graphs expressing inputs and outputs to achieve incremental computation.
Current_sesame
is the bringing together of OCurrent
and Sesame
to build incremental site generators.
Collections
Just like Sesame.Collection
, Current_sesame
exposes an OCurrent-powered version via to Current_sesame.Make
functor. Part of Sesame's redesign was to ensure some of the modules over in Sesame
provided the functionality needed to work with OCurrent
's caching model.
You can now specify things like:
(* A simple current-sesame pipeline that generate HTML
from jekyll-format files and comes complete with hot-reloading *)
module Meta = struct
type t = { title : string } [@@deriving yaml]
end
(* First some boiler-plate to get the modules we need *)
(* Plain old Sesame modules that build a collection from a
file and HTML from a collection *)
module C = Sesame.Collection.Make (Meta)
module H = Sesame.Collection.Html (Meta)
(* OCurrent-powered versions with cachine and incremental building *)
module CC = Current_sesame.Make (C)
module HC = Current_sesame.Make (H)
Building the resulting collection is then possible with a bit of OCurrent magic :) We can even add a little watcher to get some hot-reloading goodness.
let watcher = Current_sesame.Watcher.create ()
(* ~~~ The pipeline ~~~ *)
let pipeline dst () =
(* Build a collection and pass in the watcher to record the association *)
let c =
CC.build ~watcher ~label:"fetching collection"
(Fpath.v "data/index.md" |> Current.return)
in
(* Build the HTML from the collection using the default build functionality from Sesame *)
let html = HC.build ~label:"building html" c in
(* Save the HTML string to a file *)
Current_sesame.Local.save (Fpath.(dst / "index.html") |> Current.return) html
After that you just add the traditional OCurrent boiler-plate and a little bit of mangling to get the Lwt_condition.t
variable to our development server and you are done!
let main dst =
let dest = Fpath.v dst in
(* The OCurrent Engine *)
let engine = Current.Engine.create (pipeline dest) in
(* Tell the watcher to watch our data directory and get back
a condition variable that is broadcast to on changes *)
let f =
Lwt.map
(fun (f, cond, _) -> (f, cond))
(Current_sesame.Watcher.FS.watch ~watcher ~engine "data")
in
Lwt_main.run
(Lwt.choose
[
Current.Engine.thread engine;
Lwt_result.ok
@@ Lwt.bind f (fun (_, reload) ->
(* Pass the condition variable into the development server *)
Current_sesame.Server.dev_server ~port:8080 ~reload dst);
])
Images
Current_sesame.Image
provides the OCurrent-powered forms of Sesame.Image
Server and Watcher
Current_sesame.Watcher
and Current_sesame.Server
together provide hot-reloading functionality thanks to web-sockets and irmin-watcher