elmish


Program

Core abstractions for creating and running the dispatch loop.

  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
namespace Elmish

open System

/// Program type captures various aspects of program behavior
type Program<'arg, 'model, 'msg, 'view> = {
    init : 'arg -> 'model * Cmd<'msg>
    update : 'msg -> 'model -> 'model * Cmd<'msg>
    subscribe : 'model -> Cmd<'msg>
    view : 'model -> Dispatch<'msg> -> 'view
    setState : 'model -> Dispatch<'msg> -> unit
    onError : (string*exn) -> unit
}

/// Program module - functions to manipulate program instances
[<RequireQualifiedAccess>]
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Program =
    /// Typical program, new commands are produced by `init` and `update` along with the new state.
    let mkProgram 
        (init : 'arg -> 'model * Cmd<'msg>) 
        (update : 'msg -> 'model -> 'model * Cmd<'msg>)
        (view : 'model -> Dispatch<'msg> -> 'view) =
        { init = init
          update = update
          view = view
          setState = fun model -> view model >> ignore
          subscribe = fun _ -> Cmd.none
          onError = Log.onError }

    /// Simple program that produces only new state with `init` and `update`.
    let mkSimple 
        (init : 'arg -> 'model) 
        (update : 'msg -> 'model -> 'model)
        (view : 'model -> Dispatch<'msg> -> 'view) =
        { init = init >> fun state -> state,Cmd.none
          update = fun msg -> update msg >> fun state -> state,Cmd.none
          view = view
          setState = fun model -> view model >> ignore
          subscribe = fun _ -> Cmd.none
          onError = Log.onError }

    /// Subscribe to external source of events.
    /// The subscription is called once - with the initial model, but can dispatch new messages at any time.
    let withSubscription (subscribe : 'model -> Cmd<'msg>) (program: Program<'arg, 'model, 'msg, 'view>) =
        let sub model =
            Cmd.batch [ program.subscribe model
                        subscribe model ]
        { program with subscribe = sub }

    /// Trace all the updates to the console
    let withConsoleTrace (program: Program<'arg, 'model, 'msg, 'view>) =
        let traceInit (arg:'arg) =
            let initModel,cmd = program.init arg
            Log.toConsole ("Initial state:", initModel)
            initModel,cmd

        let traceUpdate msg model =
            Log.toConsole ("New message:", msg)
            let newModel,cmd = program.update msg model
            Log.toConsole ("Updated state:", newModel)
            newModel,cmd

        { program with
            init = traceInit 
            update = traceUpdate }

    /// Trace all the messages as they update the model
    let withTrace trace (program: Program<'arg, 'model, 'msg, 'view>) =
        { program
            with update = fun msg model -> trace msg model; program.update msg model}

    /// Handle dispatch loop exceptions
    let withErrorHandler onError (program: Program<'arg, 'model, 'msg, 'view>) =
        { program
            with onError = onError }

    /// Start the program loop.
    /// arg: argument to pass to the init() function.
    /// program: program created with 'mkSimple' or 'mkProgram'.
    let runWith (arg: 'arg) (program: Program<'arg, 'model, 'msg, 'view>) =
        let (model,cmd) = program.init arg
        let inbox = MailboxProcessor.Start(fun (mb:MailboxProcessor<'msg>) ->
            let rec loop (state:'model) =
                async {
                    let! msg = mb.Receive()
                    let newState =
                        try
                            let (model',cmd') = program.update msg state
                            program.setState model' mb.Post
                            cmd' |> List.iter (fun sub -> sub mb.Post)
                            model'
                        with ex ->
                            program.onError ("Unable to process a message:", ex)
                            state
                    return! loop newState
                }
            loop model
        )
        program.setState model inbox.Post
        let sub = 
            try 
                program.subscribe model 
            with ex ->
                program.onError ("Unable to subscribe:", ex)
                Cmd.none
        sub @ cmd |> List.iter (fun sub -> sub inbox.Post)

    /// Start the dispatch loop with `unit` for the init() function.
    let run (program: Program<unit, 'model, 'msg, 'view>) = runWith () program
namespace System
type Program<'arg,'model,'msg,'view> =
  {init: 'arg -> 'model * obj;
   update: 'msg -> 'model -> 'model * obj;
   subscribe: 'model -> obj;
   view: 'model -> obj -> 'view;
   setState: 'model -> obj -> unit;
   onError: string * exn -> unit;}

Full name: Elmish.Program<_,_,_,_>


 Program type captures various aspects of program behavior
Program.init: 'arg -> 'model * obj
Program.update: 'msg -> 'model -> 'model * obj
Program.subscribe: 'model -> obj
Program.view: 'model -> obj -> 'view
Program.setState: 'model -> obj -> unit
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
Program.onError: string * exn -> unit
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
type exn = Exception

Full name: Microsoft.FSharp.Core.exn
Multiple items
type RequireQualifiedAccessAttribute =
  inherit Attribute
  new : unit -> RequireQualifiedAccessAttribute

Full name: Microsoft.FSharp.Core.RequireQualifiedAccessAttribute

--------------------
new : unit -> RequireQualifiedAccessAttribute
Multiple items
type CompilationRepresentationAttribute =
  inherit Attribute
  new : flags:CompilationRepresentationFlags -> CompilationRepresentationAttribute
  member Flags : CompilationRepresentationFlags

Full name: Microsoft.FSharp.Core.CompilationRepresentationAttribute

--------------------
new : flags:CompilationRepresentationFlags -> CompilationRepresentationAttribute
type CompilationRepresentationFlags =
  | None = 0
  | Static = 1
  | Instance = 2
  | ModuleSuffix = 4
  | UseNullAsTrueValue = 8
  | Event = 16

Full name: Microsoft.FSharp.Core.CompilationRepresentationFlags
CompilationRepresentationFlags.ModuleSuffix: CompilationRepresentationFlags = 4
Multiple items
module Program

from Elmish


 Program module - functions to manipulate program instances


--------------------
type Program<'arg,'model,'msg,'view> =
  {init: 'arg -> 'model * obj;
   update: 'msg -> 'model -> 'model * obj;
   subscribe: 'model -> obj;
   view: 'model -> obj -> 'view;
   setState: 'model -> obj -> unit;
   onError: string * exn -> unit;}

Full name: Elmish.Program<_,_,_,_>


 Program type captures various aspects of program behavior
val mkProgram : init:('arg -> 'model * obj) -> update:('msg -> 'model -> 'model * obj) -> view:('model -> obj -> 'view) -> Program<'arg,'model,'msg,'view>

Full name: Elmish.ProgramModule.mkProgram


 Typical program, new commands are produced by `init` and `update` along with the new state.
val init : ('arg -> 'model * obj)
val update : ('msg -> 'model -> 'model * obj)
val view : ('model -> obj -> 'view)
val model : 'model
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
val mkSimple : init:('arg -> 'model) -> update:('msg -> 'model -> 'model) -> view:('model -> obj -> 'view) -> Program<'arg,'model,'msg,'view>

Full name: Elmish.ProgramModule.mkSimple


 Simple program that produces only new state with `init` and `update`.
val init : ('arg -> 'model)
val update : ('msg -> 'model -> 'model)
val state : 'model
val msg : 'msg
val withSubscription : subscribe:('model -> 'a) -> program:Program<'arg,'model,'msg,'view> -> Program<'arg,'model,'msg,'view>

Full name: Elmish.ProgramModule.withSubscription


 Subscribe to external source of events.
 The subscription is called once - with the initial model, but can dispatch new messages at any time.
val subscribe : ('model -> 'a)
val program : Program<'arg,'model,'msg,'view>
val sub : ('b -> 'c)
val model : 'b
val withConsoleTrace : program:Program<'arg,'model,'msg,'view> -> Program<'arg,'model,'msg,'view>

Full name: Elmish.ProgramModule.withConsoleTrace


 Trace all the updates to the console
val traceInit : ('arg -> 'model * obj)
val arg : 'arg
val initModel : 'model
val cmd : obj
val traceUpdate : ('msg -> 'model -> 'model * obj)
val newModel : 'model
val withTrace : trace:('msg -> 'model -> unit) -> program:Program<'arg,'model,'msg,'view> -> Program<'arg,'model,'msg,'view>

Full name: Elmish.ProgramModule.withTrace


 Trace all the messages as they update the model
val trace : ('msg -> 'model -> unit)
val withErrorHandler : onError:(string * exn -> unit) -> program:Program<'arg,'model,'msg,'view> -> Program<'arg,'model,'msg,'view>

Full name: Elmish.ProgramModule.withErrorHandler


 Handle dispatch loop exceptions
val onError : (string * exn -> unit)
val runWith : arg:'arg -> program:Program<'arg,'model,'msg,'view> -> unit

Full name: Elmish.ProgramModule.runWith


 Start the program loop.
 arg: argument to pass to the init() function.
 program: program created with 'mkSimple' or 'mkProgram'.
val inbox : MailboxProcessor<'msg>
Multiple items
type MailboxProcessor<'Msg> =
  interface IDisposable
  new : body:(MailboxProcessor<'Msg> -> Async<unit>) * ?cancellationToken:CancellationToken -> MailboxProcessor<'Msg>
  member Post : message:'Msg -> unit
  member PostAndAsyncReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout:int -> Async<'Reply>
  member PostAndReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout:int -> 'Reply
  member PostAndTryAsyncReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout:int -> Async<'Reply option>
  member Receive : ?timeout:int -> Async<'Msg>
  member Scan : scanner:('Msg -> Async<'T> option) * ?timeout:int -> Async<'T>
  member Start : unit -> unit
  member TryPostAndReply : buildMessage:(AsyncReplyChannel<'Reply> -> 'Msg) * ?timeout:int -> 'Reply option
  ...

Full name: Microsoft.FSharp.Control.MailboxProcessor<_>

--------------------
new : body:(MailboxProcessor<'Msg> -> Async<unit>) * ?cancellationToken:Threading.CancellationToken -> MailboxProcessor<'Msg>
static member MailboxProcessor.Start : body:(MailboxProcessor<'Msg> -> Async<unit>) * ?cancellationToken:Threading.CancellationToken -> MailboxProcessor<'Msg>
val mb : MailboxProcessor<'msg>
val loop : ('model -> Async<'a>)
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
member MailboxProcessor.Receive : ?timeout:int -> Async<'Msg>
val newState : 'model
val model' : 'model
val cmd' : obj
member MailboxProcessor.Post : message:'Msg -> unit
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IReadOnlyCollection<'T>
  interface IEnumerable
  interface IEnumerable<'T>
  member GetSlice : startIndex:int option * endIndex:int option -> 'T list
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val iter : action:('T -> unit) -> list:'T list -> unit

Full name: Microsoft.FSharp.Collections.List.iter
val ex : exn
val sub : obj
val sub : (('msg -> unit) -> unit)
val run : program:Program<unit,'model,'msg,'view> -> unit

Full name: Elmish.ProgramModule.run


 Start the dispatch loop with `unit` for the init() function.
val program : Program<unit,'model,'msg,'view>