ryannhg/elm-spa/5.1.0

NOTE: the latest version is 6.0.0

Renamed to ryan-haskell/elm-spa. It is published under that name, and new versions come out there.

Versions published as ryannhg/elm-spa still install under that name. 13 versions of 13 come from the new location (see their notes).

Rerouted (renamed, verified). The GitHub user or repository was renamed. The tag is still there, at the new name. The Lamdera package server serves a copy recovered from https://github.com/ryan-haskell/elm-spa.

What we checked: The repo moved to github.com/ryan-haskell/elm-spa. Rebuilt with git archive from commit 0f8cc5975728 of https://github.com/ryan-haskell/elm-spa (zip prefix ryannhg-elm-spa-a6cff43/, America/Los_Angeles times): the zip is byte-identical to the one package.elm-lang.org recorded, SHA-1 a78b13a810a6d2699c69edddb9e5621190a3e006.

The Lamdera compiler uses this copy and prints a one-line notice saying so. elm itself fails to download this version.

Details · package.elm-lang.org's zip: https://github.com/ryannhg/elm-spa/zipball/5.1.0/

ElmSpa.Internals.Page

Pages

type Page shared route effect view model msg

Pages are the building blocks of elm-spa.

Instead of importing this module, your project will have a Page module with a much simpler type:

module Page exposing (Page, ...)


type Page model msg

This makes all the generic route, effect, and view arguments disappear!

static : effect -> { view : view } -> Page shared route effect view () msg

A page that only needs to render a static view.

import Page


page : Page () Never
page =
    Page.static
        { view = view
        }


-- view : View Never
effect
-> { init : model
, update : msg -> model -> model
, view : model -> view
}
-> Page shared route effect view model msg

A page that can keep track of application state.

( Inspired by Browser.sandbox )

import Page


page : Page Model Msg
page =
    Page.sandbox
        { init = init
        , update = update
        , view = view
        }


-- init : Model
-- update : Msg -> Model -> Model
-- view : Model -> View Msg
(Cmd msg -> effect)
-> { init : ( model, Cmd msg )
, update : msg -> model -> ( model, Cmd msg )
, view : model -> view
, subscriptions : model -> Sub msg
}
-> Page shared route effect view model msg

A page that can handle effects like HTTP requests or subscriptions.

( Inspired by Browser.element )

import Page


page : Page Model Msg
page =
    Page.element
        { init = init
        , update = update
        , view = view
        , subscriptions = subscriptions
        }


-- init : ( Model, Cmd Msg )
-- update : Msg -> Model -> ( Model, Cmd Msg )
-- view : Model -> View Msg
-- subscriptions : Model -> Sub Msg
{ init : ( model, effect )
, update : msg -> model -> ( model, effect )
, view : model -> view
, subscriptions : model -> Sub msg
}
-> Page shared route effect view model msg

A page that can handles custom effects like sending a Shared.Msg or other general user-defined effects.

import Effect
import Page


page : Page Model Msg
page =
    Page.advanced
        { init = init
        , update = update
        , view = view
        , subscriptions = subscriptions
        }


-- init : ( Model, Effect Msg )
-- update : Msg -> Model -> ( Model, Effect Msg )
-- view : Model -> View Msg
-- subscriptions : Model -> Sub Msg

User Authentication

{ effectNone : effect
, fromCmd : Cmd msg -> effect
, user : shared -> Request route () -> Maybe user
, route : route
}
-> { static :
{ view : user -> view } -> Page shared route effect view () msg
, sandbox :
{ init : user -> model
, update : user -> msg -> model -> model
, view : user -> model -> view
}
-> Page shared route effect view model msg
, element :
{ init : user -> ( model, Cmd msg )
, update : user -> msg -> model -> ( model, Cmd msg )
, view : user -> model -> view
, subscriptions : user -> model -> Sub msg
}
-> Page shared route effect view model msg
, advanced :
{ init : user -> ( model, effect )
, update : user -> msg -> model -> ( model, effect )
, view : user -> model -> view
, subscriptions : user -> model -> Sub msg
}
-> Page shared route effect view model msg
}

Prefixing any of the four functions above with protected will guarantee that the page has access to a user. Here's an example with sandbox:

import Page


page : Page Model Msg
page =
    Page.protected.sandbox
        { init = init
        , update = update
        , view = view
        }


-- init : User -> Model
-- update : User -> Msg -> Model -> Model
-- update : User -> Model -> View Msg

For generated code

type alias Bundle params model msg shared effect pagesModel pagesMsg pagesView =
{ init : params -> shared -> Url -> Key -> ( pagesModel, effect )
, update :
params -> msg -> model -> shared -> Url -> Key -> ( pagesModel, effect )
, view : params -> model -> shared -> Url -> Key -> pagesView
, subscriptions : params -> model -> shared -> Url -> Key -> Sub pagesMsg
}
{ redirecting :
{ model : pagesModel
, view : pagesView
}
, toRoute : Url -> route
, toUrl : route -> String
, fromCmd : Cmd any -> pagesEffect
, mapEffect : effect -> pagesEffect
, mapView : view -> pagesView
, page :
shared
-> Request route params
-> Page shared route effect view model msg
, toModel : params -> model -> pagesModel
, toMsg : msg -> pagesMsg
}
-> Bundle
params
model
msg
shared
pagesEffect
pagesModel
pagesMsg
pagesView

This function is used by the generated code to connect your pages together.

It's big, spooky, and makes writing elm-spa pages really nice!