This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.
1.0.0
README

StartApp

This module helps you start your application in a typical Elm workflow. It assumes you are following the Elm Architecture and using elm-effects. From there it will wire everything up for you!

Be sure to read the Elm Architecture tutorial to learn how this all works!

Start your Application

start : Config model action -> App model action

Start an application. It requires a bit of wiring once you have created an App. It should pretty much always look like this:

app =
    start { init = init, update = update, inputs = [] }

port tasks : Signal (Task.Task Never ())
port tasks =
    app.tasks

So once we start the App we feed the resulting tasks into a port that will run them all.

type alias Config model action = { init : (model, Effects action) , update : action -> model -> (model, Effects action) , inputs : List (Signal.Signal action) }

The configuration of an app follows the basic model / update / view pattern that you see in every Elm program.

The init transaction will give you an initial model and create any tasks that are needed on start up.

The update describe how to step over the model based on requests coming in

The inputs field is for any external signals you might need. If you need to get values from JavaScript, they will come in through a port as a signal which you can pipe into your app as one of the inputs.

type alias App model action = { model : Signal model , tasks : Signal (Task.Task Never ()) , address : Signal.Address action }

An App is made up of a couple signals:

  • model — a signal representing the current model. Generally you will not need this one, but it is there just in case. You will know if you need this.

  • tasks — a signal of tasks that need to get run. Your app is going to be producing tasks in response to all sorts of events, so this needs to be hooked up to a port to ensure they get run.

module StartApp ( start, Config, App ) where
{-| This module helps you start your application in a typical Elm workflow.
It assumes you are following [the Elm Architecture][arch] and using
[elm-effects][]. From there it will wire everything up for you!

**Be sure to [read the Elm Architecture tutorial][arch] to learn how this all
works!**

[arch]: https://github.com/evancz/elm-architecture-tutorial
[elm-effects]: http://package.elm-lang.org/packages/evancz/elm-effects/latest

# Start your Application
@docs start, Config, App

-}

import Task
import Effects exposing (Effects, Never)


{-| The configuration of an app follows the basic model / update / view pattern
that you see in every Elm program.

The `init` transaction will give you an initial model and create any tasks that
are needed on start up.

The `update` describe how to step over the model based on requests coming in

The `inputs` field is for any external signals you might need. If you need to
get values from JavaScript, they will come in through a port as a signal which
you can pipe into your app as one of the `inputs`.
-}
type alias Config model action =
    { init : (model, Effects action)
    , update : action -> model -> (model, Effects action)
    , inputs : List (Signal.Signal action)
    }


{-| An `App` is made up of a couple signals:

  * `model` — a signal representing the current model. Generally you
    will not need this one, but it is there just in case. You will know if you
    need this.

  * `tasks` — a signal of tasks that need to get run. Your app is going
    to be producing tasks in response to all sorts of events, so this needs to
    be hooked up to a `port` to ensure they get run.
-}
type alias App model action =
    { model : Signal model
    , tasks : Signal (Task.Task Never ())
    , address : Signal.Address action
    }


{-| Start an application. It requires a bit of wiring once you have created an
`App`. It should pretty much always look like this:

    app =
        start { init = init, update = update, inputs = [] }

    port tasks : Signal (Task.Task Never ())
    port tasks =
        app.tasks

So once we start the `App` we feed the resulting
tasks into a `port` that will run them all.
-}
start : Config model action -> App model action
start config =
    let
        singleton action = [ action ]

        -- messages : Signal.Mailbox (List action)
        messages =
            Signal.mailbox []

        -- address : Signal.Address action
        address =
            Signal.forwardTo messages.address singleton

        -- updateStep : action -> (model, Effects action) -> (model, Effects action)
        updateStep action (oldModel, accumulatedEffects) =
            let
                (newModel, additionalEffects) = config.update action oldModel
            in
                (newModel, Effects.batch [accumulatedEffects, additionalEffects])

        -- update : List action -> (model, Effects action) -> (model, Effects action)
        update actions (model, _) =
            List.foldl updateStep (model, Effects.none) actions

        -- inputs : Signal (List action)
        inputs =
            Signal.mergeMany (messages.signal :: List.map (Signal.map singleton) config.inputs)

        -- effectsAndModel : Signal (model, Effects action)
        effectsAndModel =
            Signal.foldp update config.init inputs

        model =
            Signal.map fst effectsAndModel
    in
        { model = model
        , tasks = Signal.map (Effects.toTask messages.address << snd) effectsAndModel
        , address = address
        }