Packages
lustre
5.6.0
5.7.1
5.7.0
5.6.0
5.5.2
5.5.1
5.5.0
5.4.0
5.3.5
5.3.4
5.3.3
5.3.2
5.3.1
5.3.0
5.2.1
5.2.0
5.1.1
5.1.0
5.0.3
5.0.2
5.0.1
5.0.0
4.6.4
4.6.3
4.6.2
4.6.1
4.6.0
4.5.1
4.5.0
4.4.4
4.4.3
4.4.1
4.4.0
4.3.6
4.3.5
4.3.4
4.3.3
4.3.2
4.3.1
4.3.0
4.2.6
4.2.5
4.2.4
4.2.3
4.2.2
4.2.1
4.2.0
4.1.8
4.1.7
4.1.6
4.1.5
4.1.4
4.1.3
4.1.2
4.1.1
4.1.0
4.0.0
4.0.0-rc1
4.0.0-rc.2
3.1.4
3.1.3
3.1.2
3.1.1
3.1.0
3.0.12
3.0.11
3.0.10
3.0.9
3.0.8
3.0.7
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
3.0.0-rc.8
3.0.0-rc.7
3.0.0-rc.6
3.0.0-rc.5
3.0.0-rc.4
3.0.0-rc.3
3.0.0-rc.2
3.0.0-rc.1
2.0.1
2.0.0
1.3.0
1.2.0
1.1.0
1.0.0
Create HTML templates, single page applications, Web Components, and real-time server components in Gleam!
Current section
Files
Jump to
Current section
Files
src/lustre/runtime/app.gleam
// IMPORTS ---------------------------------------------------------------------
import gleam/dict
import gleam/dynamic/decode.{type Decoder}
import gleam/erlang/process.{type Name}
import gleam/list
import gleam/option
import lustre/effect.{type Effect}
import lustre/internals/constants
import lustre/runtime/server/runtime
import lustre/vdom/vnode.{type Element}
// TYPES -----------------------------------------------------------------------
pub type App(arguments, model, message) {
App(
name: option.Option(Name(runtime.Message(message))),
init: fn(arguments) -> #(model, Effect(message)),
update: fn(model, message) -> #(model, Effect(message)),
view: fn(model) -> Element(message),
config: Config(message),
)
}
pub type Config(message) {
Config(
//
open_shadow_root: Bool,
adopt_styles: Bool,
delegates_focus: Bool,
//
attributes: List(#(String, fn(String) -> Result(message, Nil))),
properties: List(#(String, Decoder(message))),
contexts: List(#(String, Decoder(message))),
//
is_form_associated: Bool,
on_form_autofill: option.Option(fn(String) -> message),
on_form_reset: option.Option(message),
on_form_restore: option.Option(fn(String) -> message),
//
on_connect: option.Option(message),
on_adopt: option.Option(message),
on_disconnect: option.Option(message),
)
}
pub type Option(message) {
Option(apply: fn(Config(message)) -> Config(message))
}
// CONSTANTS -------------------------------------------------------------------
pub const default_config: Config(message) = Config(
open_shadow_root: True,
adopt_styles: True,
delegates_focus: False,
attributes: constants.empty_list,
properties: constants.empty_list,
contexts: constants.empty_list,
is_form_associated: False,
on_form_autofill: option.None,
on_form_reset: option.None,
on_form_restore: option.None,
on_connect: option.None,
on_adopt: option.None,
on_disconnect: option.None,
)
// MANIPULATIONS ---------------------------------------------------------------
pub fn configure(options: List(Option(message))) -> Config(message) {
list.fold(options, default_config, fn(config, option) { option.apply(config) })
}
pub fn configure_server_component(
config: Config(message),
) -> runtime.Config(message) {
runtime.Config(
open_shadow_root: config.open_shadow_root,
adopt_styles: config.adopt_styles,
// we reverse both lists here such that the last added value takes precedence
attributes: dict.from_list(list.reverse(config.attributes)),
properties: dict.from_list(list.reverse(config.properties)),
contexts: dict.from_list(list.reverse(config.contexts)),
//
on_connect: config.on_connect,
on_disconnect: config.on_disconnect,
)
}