Stepper.Core
0.0.6
dotnet add package Stepper.Core --version 0.0.6
NuGet\Install-Package Stepper.Core -Version 0.0.6
<PackageReference Include="Stepper.Core" Version="0.0.6" />
<PackageVersion Include="Stepper.Core" Version="0.0.6" />
<PackageReference Include="Stepper.Core" />
paket add Stepper.Core --version 0.0.6
#r "nuget: Stepper.Core, 0.0.6"
#:package Stepper.Core@0.0.6
#addin nuget:?package=Stepper.Core&version=0.0.6
#tool nuget:?package=Stepper.Core&version=0.0.6
Stepper
Stepper is a state management library derived from classical FRP implementation such as reactive-banana with the idea of TEA (The Elm Architecture) embedded.
Core Concepts
In Functional Reactive Programming (FRP):
- Event represents discrete occurrences over time (
TMsg). - Behavior represents continuous values over time (
TModel).
Stepper implements this duality by accumulating discrete messages to transition a model state, isolating asynchronous side effects using declarative commands (TCmd) and an interpreter.
Installation
dotnet add package Stepper.Core
Architecture
- Messages (
TMsg) are received from external sources (e.g., UI events) or the interpreter. - The message stream is merged and serialized.
- The state transitions are processed sequentially via the
Updatefunction inTransition. - The updated Model (
TModel) is emitted to observers. - Generated Commands (
TCmd) are processed by theInterpreter'sProcessfunction, which translates commands into new messages to complete the feedback loop.
Usage
1. Define Types
public record PaletteModel(string Query, bool IsLoading, List<string> Results);
public abstract record PaletteMsg
{
public record QueryChanged(string Query) : PaletteMsg;
public record ResultsFetched(List<string> Results) : PaletteMsg;
public record SearchError(string Error) : PaletteMsg;
}
public abstract record PaletteCmd
{
public record FetchFromApi(string Query) : PaletteCmd;
public record ReportAnalytics(string Event) : PaletteCmd;
}
2. Define Transition
var transition = new Transition<PaletteModel, PaletteMsg, PaletteCmd>(
Init: (new PaletteModel("", false, new()), default),
Update: state =>
{
var (model, msg) = state;
return msg switch
{
PaletteMsg.QueryChanged(var q) when string.IsNullOrWhiteSpace(q) =>
(model with { Query = q, IsLoading = false, Results = new() }, default),
PaletteMsg.QueryChanged(var q) =>
(model with { Query = q, IsLoading = true }, new PaletteCmd.FetchFromApi(q)),
PaletteMsg.ResultsFetched(var results) =>
(model with { IsLoading = false, Results = results }, new PaletteCmd.ReportAnalytics("Search Completed")),
PaletteMsg.SearchError =>
(model with { IsLoading = false, Results = new() }, default),
_ => (model, default)
};
}
);
3. Define Interpreter
using System.Reactive.Linq;
var interpreter = new Interpreter<PaletteCmd, PaletteMsg>(cmds =>
{
var searchStream = cmds.OfType<PaletteCmd.FetchFromApi>();
var analyticsStream = cmds.OfType<PaletteCmd.ReportAnalytics>();
var searchMsgs = searchStream
.Select(cmd => SearchMockApi(cmd.Query))
.Switch();
var analyticsMsgs = analyticsStream
.Select(cmd => UploadAnalyticsApi(cmd.Event))
.Merge();
return Observable.Merge(searchMsgs, analyticsMsgs);
});
4. Run the Program
var program = new Program<PaletteModel, PaletteMsg, PaletteCmd>(transition, interpreter);
var userInput = new Subject<PaletteMsg>();
using var subscription = program.Run(userInput).Subscribe(model =>
{
Console.WriteLine($"Query: {model.Query}, Loading: {model.IsLoading}, Results: {model.Results.Count}");
});
userInput.OnNext(new PaletteMsg.QueryChanged("f"));
userInput.OnNext(new PaletteMsg.QueryChanged("fo"));
userInput.OnNext(new PaletteMsg.QueryChanged("for"));
Threading & Scheduling
Stepper's state transitions are serialized internally. When binding to a UI framework, configure the thread scheduling on the subscription:
program.Run(userInput)
.ObserveOn(RxApp.MainThreadScheduler) // or your framework's UI scheduler
.Subscribe(model => {
// Update UI elements
});
License
This project is licensed under the MIT License.
| Product | Versions 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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.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. |
-
.NETStandard 2.0
- System.Reactive (>= 6.1.0)
-
net10.0
- System.Reactive (>= 6.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.