bright

Types

Bright holds raw data and computed data, and is used to compute caching. Bright is instanciated using init, with initial data and computed data.

pub opaque type Bright(data, computed)

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.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 guard(
  bright: Bright(a, b),
  guard_: 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.update(model, update_data(_, msg))
  use d, c <- bright.guard(model)
  use dispatch <- effect.from
  case d.field == 10 {
    True -> dispatch(my_msg)
    False -> Nil
  }
}
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) -> 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.

pub fn update(model: Bright(data, computed), msg: Msg) {
  use model <- bright.update(model, update_data(_, msg))
  model
  |> bright.lazy_compute(selector, fn (d, c) { Computed(..c, field1: computation1(d)) })
  |> bright.lazy_compute(selector, fn (d, c) { Computed(..c, field2: computation2(d)) })
  |> bright.lazy_compute(selector, fn (d, c) { 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_guard(
  bright: Bright(a, b),
  selector: fn(a) -> c,
  guard_: fn(a, b) -> Effect(d),
) -> Bright(a, b)

Plugs in existing data like guard lazily. lazy_guard accepts a selector as second argument. Each time the selector returns a different data than previous run, the computation will run. Otherwise, nothing happens.

pub fn update(model: Bright(data, computed), msg: Msg) {
  use model <- bright.update(model, update_data(_, msg))
  use d, c <- bright.lazy_guard(model, selector)
  use dispatch <- effect.from
  case d.field == 10 {
    True -> dispatch(my_msg)
    False -> Nil
  }
}

/// Use it with lazy_guard to recompute only when the field when
/// { old_data.field / 10 } != { data.field / 10 }
fn selector(d, _) {
  d.field / 10
}
pub fn return(a: a) -> #(a, Effect(b))

Helper to write bright update cycle. Equivalent to #(a, effect.none()).

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))
  bright.return(Model(fst_bright:, snd_bright:))
}
pub fn update(
  bright: Bright(a, b),
  update_: fn(a) -> #(a, Effect(c)),
  next: fn(Bright(a, b)) -> Bright(a, b),
) -> #(Bright(a, b), Effect(c))

Entrypoint for the 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) {
  // Starts the update cycle, and returns #(Bright(data, computed), Effect(msg)).
  use model <- bright.update(model, update_data(_, msg))
  bright.return(model)
}
pub fn view(bright: Bright(a, b), viewer: fn(a, b) -> c) -> c

Injects Bright(data, computed) in the view function, like a middleware. Used to extract data & computed states from Bright.

pub fn view(model: Bright(data, computed)) {
  use data, computed <- bright.view(model)
  html.div([], [
    // Use data or computed here.
  ])
}
Search Document