bright
Types
Functions
pub fn compute(
bright: Bright(a, b),
compute_: fn(a, b) -> b,
) -> Bright(a, b)
Derives data from the data
state, and potentially the current computed
state. compute
will run at every render, so be careful with computations
as they can block paint or actors.
pub fn update(model: Bright(data, computed), msg: Msg) {
use model <- bright.start(model)
use model <- bright.update(model, update_data(_, msg))
model
|> bright.compute(fn (d, c) { Computed(..c, field1: computation1(d)) })
|> bright.compute(fn (d, c) { Computed(..c, field2: computation2(d)) })
|> bright.compute(fn (d, c) { Computed(..c, field3: computation3(d)) })
}
pub fn computed(bright: Bright(a, b)) -> b
Extracts computed
state from Bright
.
pub fn view(model: Bright(data, computed)) {
let computed = bright.computed(model)
html.div([], [
// Use computed here.
])
}
pub fn data(bright: Bright(a, b)) -> a
Extracts data
state from Bright
.
pub fn view(model: Bright(data, computed)) {
let data = bright.data(model)
html.div([], [
// Use data here.
])
}
pub fn init(data data: a, computed computed: b) -> Bright(a, b)
Creates the initial Bright
. data
& computed
should be initialised with
their correct empty initial state.
pub fn lazy_compute(
bright: Bright(a, b),
selector: fn(a) -> c,
compute_: fn(a, b, c) -> b,
) -> Bright(a, b)
Derives data like compute
lazily. lazy_compute
accepts a
selector as second argument. Each time the selector returns a different data
than previous run, the computation will run. Otherwise, nothing happens.
The computation function will receive data
, computed
and the selected
data (i.e. the result from your selector function), in case accessing the
selected data is needed.
pub fn update(model: Bright(data, computed), msg: Msg) {
use model <- bright.start(model)
use model <- bright.update(model, update_data(_, msg))
model
// Here, e is always the result data.field / 10 (the result from selector).
|> bright.lazy_compute(selector, fn (d, c, e) { Computed(..c, field1: computation1(d)) })
|> bright.lazy_compute(selector, fn (d, c, e) { Computed(..c, field2: computation2(d)) })
|> bright.lazy_compute(selector, fn (d, c, e) { Computed(..c, field3: computation3(d)) })
}
/// Use it with lazy_compute to recompute only when the field when
/// { old_data.field / 10 } != { data.field / 10 }
fn selector(d, _) {
d.field / 10
}
pub fn lazy_schedule(
bright: Bright(a, b),
selector: fn(a) -> c,
schedule_: fn(a, b, c) -> Effect(d),
) -> Bright(a, b)
Plugs in existing data
like schedule
lazily. lazy_schedule
accepts
a selector as second argument. Each time the selector returns a different data
than previous run, the computation will run. Otherwise, nothing happens.
The scheduling function will receive data
, computed
and the selected
data (i.e. the result from your selector function), in case accessing the
selected data is needed.
pub fn update(model: Bright(data, computed), msg: Msg) {
use model <- bright.start(model)
use model <- bright.update(model, update_data(_, msg))
// e is equal to d.field / 10 (the result from selector).
use d, c, e <- bright.lazy_schedule(model, selector)
use dispatch <- effect.from
case d.field == 10 {
True -> dispatch(my_msg)
False -> Nil
}
}
/// Use it with lazy_schedule to recompute only when the field when
/// { old_data.field / 10 } != { data.field / 10 }
fn selector(d, _) {
d.field / 10
}
pub fn schedule(
bright: Bright(a, b),
schedule_: fn(a, b) -> Effect(c),
) -> Bright(a, b)
Plugs in existing data
and computed
state, to issue some side-effects,
when your application needs to run side-effects depending on the current state.
pub fn update(model: Bright(data, computed), msg: Msg) {
use model <- bright.start(model)
use model <- bright.update(model, update_data(_, msg))
use d, c <- bright.schedule(model)
use dispatch <- effect.from
case d.field == 10 {
True -> dispatch(my_msg)
False -> Nil
}
}
pub fn start(
bright: Bright(a, b),
next: fn(Bright(a, b)) -> Bright(a, b),
) -> #(Bright(a, b), Effect(c))
Start the Bright update cycle. Use it as a way to trigger the start of Bright
computations, and chain them with other bright
calls.
pub fn update(model: Bright(data, computed), msg: Msg) {
// Starts the update cycle, and returns #(Bright(data, computed), Effect(msg)).
use model <- bright.start(model)
use model <- bright.update(update_data(_, msg))
model
}
pub fn step(
bright: #(Bright(a, b), Effect(c)),
next: fn(Bright(a, b)) -> #(d, Effect(c)),
) -> #(d, Effect(c))
Allows to run multiple update
on multiple Bright
in the same update cycle.
Every call to step with compute a new Bright
, and will let you chain the
steps.
pub type Model {
Model(
fst_bright: Bright(data, computed),
snd_bright: Bright(data, computed),
)
}
fn update(model: Model, msg: Msg) {
use fst_bright <- bright.step(update_fst(model.fst_bright, msg))
use snd_bright <- bright.step(update_snd(model.snd_bright, msg))
#(Model(fst_bright:, snd_bright:), effect.none())
}
pub fn unwrap(bright: Bright(a, b)) -> #(a, b)
Extracts data
& computed
states from Bright
.
pub fn view(model: Bright(data, computed)) {
let #(data, computed) = bright.unwrap(model)
html.div([], [
// Use data or computed here.
])
}
pub fn update(
bright: Bright(a, b),
update_: fn(a) -> #(a, Effect(c)),
next: fn(Bright(a, b)) -> Bright(a, b),
) -> Bright(a, b)
Update data & effects during update cycle. Use it a way to trigger the start
of Bright
computations, and chain them with other bright
calls.
pub fn update(model: Bright(data, computed), msg: Msg) {
use model <- bright.start(model)
// Run an update, and returns #(data, Effect(msg)).
use model <- bright.update(model, update_data(_, msg))
model
}