Fable.Reaction 0.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Fable.Reaction --version 0.2.0                
NuGet\Install-Package Fable.Reaction -Version 0.2.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Fable.Reaction" Version="0.2.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Fable.Reaction --version 0.2.0                
#r "nuget: Fable.Reaction, 0.2.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Fable.Reaction as a Cake Addin
#addin nuget:?package=Fable.Reaction&version=0.2.0

// Install Fable.Reaction as a Cake Tool
#tool nuget:?package=Fable.Reaction&version=0.2.0                

Fable Reaction

Fable Reaction is a lightweight Async Reactive (Rx) Elmish-ish library for F# targeting Fable and React.

Fable Reaction is built on top of Reaction, and is currently a playground project (WIP) for experimenting with MVU-based web applications using async reactive functional programming (Async Observables) in F#. The project is heavily inspired by Elm and Elmish but currently lives as a separate project.

The difference from Elmish and Elm is that Fable.Reaction does not need any commands (Cmd) or subscriptions. Instead we use a ReactiveX (Rx) style query that transforms the stream of messages (Msg).

Reactive MVU Architecture

Fable Reaction is very similar to Elm and Elmish in regards to the MVU architecture.

<img src="R-MVU.png" width="400">

  • Model, application state as immutable data
  • View, a pure function that takes the model to produce the output view (HTML elements)
  • Message, a data event that represents a change. Messages are generated by the view, or they may be generated out of "thin air" by the reaction query, e.g. timer or initial message events.
  • Update, a pure function that produces a new model based on a received message and the previous model

In addition, Fable Reaction may also have a reaction, a query that transforms the "stream" of messages.

  • Reaction, a query function that takes the message stream and produces a new (transformed) message stream. Note that this also replaces Elm(ish) commands (Cmd) since the reaction is free to produce initial messages out of thin air, transform, filter, time-shift messages and combine side-effects such as web requests (fetch) etc.

Composition

Fable Reaction follows the Elm and Elmish style of functional composition. TBD.

Examples

Examples of how to use Fable Reaction can be found in the examples folder. Current list of examples includes:

The Timeflies example (source code) implements the classic Time Flies example from RxJS. This code is very simplar to Elmish but the difference is that we can compose powerful reactive queries to transform, filter, aggregate and time-shift our stream of messages.

// The model holds data that you want to keep track of while the
// application is running
type Model = {
    Letters: Map<int, string * int * int>
}

// The Msg type defines what events/actions can occur while the
// application is running. The state of the application changes *only*
// in reaction to these events
type Msg =
    | Letter of int * string * int * int

// The update function computes the next state of the application based
// on the current state and the incoming messages
let update (currentModel : Model) (msg : Msg) : Model =
    match currentModel.Letters, msg with
    | _, Letter (i, c, x, y) ->
        { currentModel with Letters = currentModel.Letters.Add (i, (c, x, y)) }

let view (model : Model) (dispatch : Dispatch<Msg>) =
    let letters = model.Letters
    let offsetX x i = x + i * 10 + 15

    div [ Style [ FontFamily "Consolas, monospace"]] [
        for KeyValue(i, (c, x, y)) in letters do
            yield span [ Style [Top y; Left (offsetX x i); Position "absolute"] ] [
                str c
            ]
    ]

let init () : Model = { Letters = Map.empty }

// Message stream transformation.
let query (msgs : AsyncObservable<Msg>) : AsyncObservable<Msg>) =
    rx {
        let! i, c = Seq.toList "TIME FLIES LIKE AN ARROW"
                    |> Seq.mapi (fun i c -> i, c)
                    |> ofSeq

        let ms = fromMouseMoves () |> delay (100 * i)
        for m in ms do
            yield Letter (i, string c, int m.clientX, int m.clientY)
    }

Program.mkProgram init update view
|> Program.withMsgs query
|> Program.withReact "elmish-app"
|> Program.run
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Fable.Reaction:

Package Downloads
Fable.Elmish.Nile

Extension to Fable.Elmish that enables transforming the stream of dispatched messages from the view to messages that are dispatched to the update function. It's an alternative approach to Fable.Elmish.Streams. However Fable.Elmish.Streams has some nice helpers that you might want to use with Fable.Elmish.Nile.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.5.0 2,107 10/25/2020
3.4.2 960 10/25/2020
3.4.1 506 10/25/2020
3.4.0 446 10/24/2020
3.3.3 1,509 5/17/2020
3.3.2 477 5/16/2020
3.3.1 454 5/16/2020
3.3.0 1,203 5/13/2020
3.2.1 4,044 9/10/2019
3.2.0 505 9/9/2019
3.1.1 527 9/9/2019
3.0.11 551 9/6/2019
2.2.0 1,078 10/28/2018
2.1.2 779 10/25/2018
2.0.2 716 10/24/2018
2.0.1 743 10/20/2018
2.0.0 725 10/19/2018
2.0.0-beta2 672 10/10/2018
2.0.0-beta1 608 9/30/2018
2.0.0-alpha1 592 9/29/2018
0.7.1 765 9/27/2018
0.6.8 781 9/21/2018
0.4.1 819 9/5/2018
0.4.0 774 9/4/2018
0.3.0 757 9/2/2018
0.2.0 748 8/30/2018