-
-
Notifications
You must be signed in to change notification settings - Fork 50
/
cmd.gleam
64 lines (55 loc) · 1.91 KB
/
cmd.gleam
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// IMPORTS ---------------------------------------------------------------------
import gleam/list
// TYPES -----------------------------------------------------------------------
/// A `Cmd` represents some side effect we want the Lustre runtime to perform.
/// It is parameterised by our app's `action` type because some effects need to
/// get information back into your program.
///
pub opaque type Cmd(action) {
Cmd(List(fn(fn(action) -> Nil) -> Nil))
}
// CONSTRUCTORS ----------------------------------------------------------------
/// Create a `Cmd` from some custom side effect. This is mostly useful for
/// package authors, or for integrating other libraries into your Lustre app.
///
/// We pass in a function that recieves a `dispatch` callback that can be used
/// to send messages to the Lustre runtime. We could, for example, create a `tick`
/// command that uses the `setTimeout` JavaScript API to send a message to the
/// runtime every second:
///
/// ```gleam
/// import lustre/cmd.{Cmd}
///
/// external fn set_interval(callback: fn() -> any, interval: Int) =
/// "" "window.setInterval"
///
/// pub fn every_second(msg: msg) -> Cmd(msg) {
/// use dispatch <- cmd.from
///
/// set_interval(fn() { dispatch(msg) }, 1000)
/// }
/// ```
///
pub fn from(cmd: fn(fn(action) -> Nil) -> Nil) -> Cmd(action) {
Cmd([cmd])
}
/// Typically our app's `update` function needs to return a tuple of
/// `#(model, Cmd(action))`. When we don't need to perform any side effects we
/// can just return `none()`!
///
pub fn none() -> Cmd(action) {
Cmd([])
}
// MANIPULATIONS ---------------------------------------------------------------
///
///
pub fn batch(cmds: List(Cmd(action))) -> Cmd(action) {
Cmd({
use b, Cmd(a) <- list.fold(cmds, [])
list.append(b, a)
})
}
pub fn map(cmd: Cmd(a), f: fn(a) -> b) -> Cmd(b) {
let Cmd(l) = cmd
Cmd(list.map(l, fn(cmd) { fn(dispatch) { cmd(fn(a) { dispatch(f(a)) }) } }))
}