webbhuset/elm-actor-model/1.0.0

NOTE: the latest version is 4.0.0

Webbhuset.Actor

Actor

When a component is incorporated in a system it becomes an Actor. The actor module implements the connections to the other components in the system. In practice that means mapping and sending the component's out messages to other actors in the system.

Here is an example of wrapping a login form component to an actor in a system.

This is the global model for the System:

module AppModel exposing (..)

type AppModel
    = LoginFormModel LoginForm.Model
    | OtherComponent ...

This is the global appMsg type for the System:

module AppMsg exposing (..)

type AppMsg
    = FormMsg LoginForm.MsgIn
    | AuthServiceMsg AuthService.MsgIn
    | OtherComponent ...

This is the login form actor:

module Actor.LoginForm exposing (..)

import Webbhuset.ActorSystem as System
import Webbhuset.Actor as Actor exposing (Actor)
import Component.LoginForm as LoginForm
import Component.AuthService as AuthService
import AppMsg exposing (AppMsg)
import AppModel exposing (AppModel)


actor : Actor LoginForm.Model AppModel AppMsg
actor =
    Actor.fromUI
        { wrapModel = AppModel.LoginFormModel
        , wrapMsg = AppMsg.FormMsg
        , mapIn = mapFormIn
        , mapOut = mapFormOut
        }
        LoginForm.component


mapFormIn : AppMsg -> Maybe LoginForm.MsgIn
mapFormIn appMsg =
    case appMsg of
        AppMsg.FormMsg formMsg ->
            Just formMsg

        _ ->
            Nothing


mapFormOut : PID -> LoginForm.MsgOut -> System.SysMsg name AppMsg
mapFormOut self formMsg =
    case formMsg of
        LoginForm.Submit user password ->
            AuthService.Login user password self
                |> AppMsg.AuthServiceMsg
                |> System.toAppMsg
                |> System.sendToSingleton AuthService
type alias PID =
PID

A PID is an identifier for a Process.

Create Actors from Components

{ wrapModel : compModel -> appModel
, wrapMsg : msgIn -> appMsg
, mapIn : appMsg -> Maybe msgIn
, mapOut : PID -> msgOut -> SysMsg name appMsg
}
-> UI compModel msgIn msgOut
-> Actor compModel appModel (SysMsg name appMsg)

Create an actor from a UI Component

{ wrapModel : compModel -> appModel
, wrapMsg : msgIn -> appMsg
, mapIn : appMsg -> Maybe msgIn
, mapOut : PID -> msgOut -> SysMsg name appMsg
}
-> Service compModel msgIn msgOut
-> Actor compModel appModel (SysMsg name appMsg)

Create an actor from a Service Component

{ wrapModel : compModel -> appModel
, wrapMsg : msgIn -> appMsg
, mapIn : appMsg -> Maybe msgIn
, mapOut : PID -> msgOut -> SysMsg name appMsg
}
-> Layout compModel msgIn msgOut (SysMsg name appMsg)
-> Actor compModel appModel (SysMsg name appMsg)

Create an actor from a Layout Component

Bootstrap

type alias Actor compModel appModel msg =
{ init : PID -> ( appModel, msg )
, update : compModel -> msg -> PID -> ( appModel, msg )
, view : compModel -> PID -> (PID -> Html msg) -> Html msg
, kill : compModel -> PID -> msg
, subs : compModel -> PID -> Sub msg
}

An actor is acomponent where the types are wrapped to fit the System types.