A state-interface program running in the browser
Create an elm Program
with a given Web.ProgramConfig. Short for
Platform.worker
{ init = \() -> Web.programInit yourAppConfig
, update = Web.programUpdate yourAppConfig
, subscriptions = Web.programSubscriptions yourAppConfig
}Ignore the specific fields, this is just exposed so can annotate a program state like in
main : Program () (Web.State YourState) (Web.Event YourState)
main =
Web.toProgram ...Ignore the specific variants, this is just exposed so can annotate a program event like in
main : Program () (Web.State YourState) (Web.Event YourState)
main =
Web.toProgram ...If you just want to replace a part of your elm app with this architecture. Make sure to wire in all 3:
The "init" part for an embedded program
The "update" part for an embedded program
The "subscriptions" part for an embedded program
Incoming and outgoing effects.
To create one, use the helpers in Web.Time, .Dom, .Http etc.
To combine multiple, use Web.interfaceBatch and Web.interfaceNone
Combine multiple Interfaces into one.
Doing nothing as an Interface. These two examples are equivalent:
Web.interfaceBatch [ a, Web.interfaceNone, b ]and
Web.interfaceBatch
(List.filterMap identity
[ a |> Just, Nothing, b |> Just ]
)Map the state constructed by the Interface.
In practice, this is sometimes used like a kind of event-config pattern:
Web.Time.posixRequest
|> Web.interfaceMap (\timeNow -> TimeReceived timeNow)sometimes like elm's update
...
|> Web.interfaceMap
(\event ->
case event of
MouseMovedTo newMousePoint ->
{ state | mousePoint = newMousePoint }
CounterDecreaseClicked ->
{ state | counter = state.counter - 1 }
CounterIncreaseClicked ->
{ state | counter = state.counter + 1 }
)and sometimes like elm's Cmd.map/Task.map/Sub.map/...:
type State
= MenuState Menu.State
| PlayingState Playing.State
interface : State -> Interface State
interface state =
case state of
MenuState menuState ->
Web.interfaceMap MenuState (Menu.interface menuState)
PlayingState playingState ->
Web.interfaceMap PlayingState (Playing.interface playingState)In all these examples, you end up converting the narrow state representation of part of the interface to a broader representation for the parent interface
Types used by Web.Dom
Plain text or a DomElement for use in an Interface.
A tagged DOM node that can itself contain child nodes
Setting for a listen Web.Dom.Modifier to keep or overwrite the browsers default action.
Types used by Web.Http
An HTTP request for use in an Interface.
You can set custom headers as needed.
The timeout can be set to a number of milliseconds you are willing to wait before giving up
An Http header for configuring a request.
Data send in your http request.
HttpBodyEmpty: Create an empty body for your request.
This is useful for GET requests and POST requests where you are not sending any data.
HttpBodyString: Put a String in the body of your request. Defining Web.Http.jsonBody looks like this:
import Json.Encode
jsonBody : Json.Encode.Value -> Web.HttpBody
jsonBody value =
Web.HttpBodyString "application/json" (Json.Encode.encode 0 value)The first argument is a MIME type of the body.
Describe what you expect to be returned in an http response body.
A Request can fail in a couple ways:
BadUrl means you did not provide a valid URL.Timeout means it took too long to get a response.NetworkError means the user turned off their wifi, went in a cave, etc.BadStatus means you got a response back, but the status code indicates failure. Contains:Metadata.Json.Decode.Value.BadBody means you got a response back with a nice status code, but the body of the response was something unexpected. Contains:Metadata.Json.Decode.Value.Json.Decode.Error that caused the error.Extra information about the response:
Note: It is possible for a response to have the same header multiple times. In that case, all the values end up in a single entry in the headers dictionary. The values are separated by commas, following the rules outlined here.
An "non-batched" Interface.
To create one, use the helpers in Web.Time, .Dom, .Http etc.
An InterfaceSingle that will notify elm some time in the future.
An InterfaceSingle that will never notify elm
Safe to ignore. Individual messages to js. Also used to identify responses with the same part in the interface
Actions that will notify elm some time in the future
Actions that will never notify elm again
Change the current node at a given path using a given ReplacementInEditDomDiff
What parts of a node are replaced. Either all modifiers of a certain kind or the whole node
Safe to ignore. Identification and order of an Interface
Safe to ignore. Tag for the ordering of an InterfaceSingleId
Safe to ignore. Identifier for an Interface
Safe to ignore. Identifier for an InterfaceSingleWithReceive
Safe to ignore. Tag for the identification mapping of an InterfaceSingle → InterfaceSingleId
Safe to ignore. Identifier for a DomElement
Safe to ignore. Identifier for a DomNode
Safe to ignore. Identifier for an HttpRequest
Safe to ignore. Identifier for an HttpExpect
What's needed to create a state-interface program.
stateis what elm calls the modelInterfacecan be created using the helpers inWeb.Time,Web.Dom,Web.Httpetc.