map : Effect(a), (a -> b) -> Effect(b)
Re-target an effect to a parent message type: the response callback's
message is passed through f on its way to update, so components can
own their effects too.
:= [
CloseModal(Str),
ConsoleLog(Str),
CryptoDigest(Str, List(U8), Box(List(U8) -> Box(msg))),
CryptoDigestFile(Str, U32, U64, U64, Box(List(U8) -> Box(msg))),
HttpSend(Str, Str, List({ name : Str, value : Str }), List(U8), U64, Box({ status : U16, headers : List({ name : Str, value : Str }), body : List(U8) } -> Box(msg))),
HttpSendFile(Str, Str, List({ name : Str, value : Str }), U32, U64, U64, U64, Box({ status : U16, headers : List({ name : Str, value : Str }), body : List(U8) } -> Box(msg))),
Navigate(Str),
PortSend(Str, Str),
PushUrl(Str),
ReplaceUrl(Str),
ShowModal(Str),
TimeAfter(U32, Box(I64 -> Box(msg))),
TimeCancel(Str),
TimeDebounce(Str, U32, Box(I64 -> Box(msg))),
]
An effect: an asynchronous action described as *data*, returned from init
or update and executed by the host. The response callback is a real typed
function (... -> msg), boxed so the host can store and call it without
knowing the app's Msg layout.
Why data instead of effectful platform functions: hosted functions are
monomorphic C symbols, so they cannot accept a callback that is generic
over the app's msg. Effects flow through update's return type, where
msg is properly in scope. Msg-free effects (logging, navigation,
modals, timer cancellation) are data too: as data they can be matched
on, so a pure test can assert exactly which effects an update produced.
The boundary rule: every app entrypoint is pure and the compiler
enforces it, every observable effect is an Effect value returned from
init or update, and init receives the app's flags string, into
which the embedder puts any boot data the app needs (time, url,
whatever). Recurring event sources are subscriptions (see Sub).
Apps normally use the constructors in Http, Time and WebCrypto rather
than these variants directly. Payload fields are positional for a simpler
host walk. File ids come from a file input's Attribute.on_file; the
browser side holds the actual File object, so its bytes never cross into
wasm unless you hash or upload them.
map : Effect(a), (a -> b) -> Effect(b)
Re-target an effect to a parent message type: the response callback's
message is passed through f on its way to update, so components can
own their effects too.
close_modal : Str -> Effect(msg)
console_log : Str -> Effect(msg)
replace_url : Str -> Effect(msg)
show_modal : Str -> Effect(msg)
time_after : U32, (I64 -> msg) -> Effect(msg)
time_cancel : Str -> Effect(msg)
time_debounce : Str, U32, (I64 -> msg) -> Effect(msg)