Current section
Files
Jump to
Current section
Files
src/glamour/app.gleam
import gleam/dynamic/decode.{type Decoder}
import gleam/json
import lustre.{type App}
import lustre/element.{type Element}
/// Describes a Glamour-enabled Lustre application.
///
/// Glamour assumes that the Lustre application's `start_args` type is the same
/// as its model. On the client we will pass the reclaimed model into
/// `lustre.start` so the runtime can attach event listeners without performing a
/// throwaway re-render.
///
/// Provide JSON encoder/decoder functions so Glamour can transport the initial
/// model between server and client.
pub type Spec(model, msg) {
Spec(
app: App(model, model, msg),
view: fn(model) -> Element(msg),
encode: fn(model) -> json.Json,
decoder: Decoder(model),
selector: String,
state_script_id: String,
)
}
/// Create a new Glamour spec using the provided Lustre application, JSON
/// encoder, and decoder. The default mount selector is `#app` and the embedded
/// state script id is `glamour-state`.
pub fn new(
app app: App(model, model, msg),
view view: fn(model) -> Element(msg),
encode encode: fn(model) -> json.Json,
decoder decoder: Decoder(model),
) -> Spec(model, msg) {
Spec(
app:,
view:,
encode:,
decoder:,
selector: "#app",
state_script_id: "glamour-state",
)
}
/// Change the CSS selector Glamour should target when claiming the DOM.
pub fn with_selector(
spec: Spec(model, msg),
selector selector: String,
) -> Spec(model, msg) {
Spec(..spec, selector:)
}
/// Change the id used for the embedded JSON script tag.
pub fn with_state_script_id(
spec: Spec(model, msg),
id: String,
) -> Spec(model, msg) {
Spec(..spec, state_script_id: id)
}
/// Produce an option so the selector can be customised ergonomically with
/// `option.Option` pipelines.
pub fn selector(selector: String) -> fn(Spec(model, msg)) -> Spec(model, msg) {
fn(spec) { with_selector(spec, selector) }
}
/// Produce an option so the state script id can be adjusted via pipelines.
pub fn state_script_id(id: String) -> fn(Spec(model, msg)) -> Spec(model, msg) {
fn(spec) { with_state_script_id(spec, id) }
}