Skip to content

Instantly share code, notes, and snippets.

@kspeakman
kspeakman / EmailerExample.fs
Last active December 2, 2021 02:36
UMP - MVU-style back end workflow
module Emailer
type Model =
{ SendLimitPerSecond: int
Today: DateTime
ToSend: Email list list }
type Effect =
| FindDueEmails of DateTime
| ScheduleSend of DateTimeOffset
@kspeakman
kspeakman / _README.md
Last active August 30, 2022 12:54
On Subscription IDs

Ref: elmish/elmish PR #248.

An early prototype of the "live subs" demo used the subscription settings + Msg type as the subscription ID. This worked as long as you only needed a single subscription. But it did not allow, for example, two timers on the same page with the same settings. That led me to switch to a user-provided Sub ID. This gives the user full control on when subscriptions are different or the same. It also gave ID the responsibility of triggering changes to a running subscription.

Subscriptions only have start/stop semantics. So "change" means stopping the running one and starting a new one with different settings. How ID controls this is illustrated in the live subs demo. Notice under Subscriptions -- which lists subscription IDs -- that the timer interval is part of the ID. When the user changes the interval from 1000 to 2000, the subscription ID goes from ".../interval/1000" to ".../interval/2000". T

@kspeakman
kspeakman / EventParser.fs
Last active September 8, 2022 19:19
Event parser
namespace Utilities
type EventType = string
type EventData = string
type EventParser<'union, 'meta> =
{
Deserializers : Map<EventType, EventData option -> Result<'union, exn>>
Serialize : 'union -> Result<EventType * EventData option, exn>
ParseMeta : string -> Result<'meta, exn>
@kspeakman
kspeakman / Ump.fs
Created October 27, 2022 00:45
Update Model Perform (UMP) -- MVU for back-end
namespace Utilities
(*
UMP (Update Model Perform) is a reformulation of MVU (Model View Update).
Here are the differences:
* `Cmd<Msg>` is replaced by a user-defined `Effect` (list) and a `perform` function
- allows testing that the correct side effects were chosen, using simple value equality (`=`)
- `Effect` is a DU, each case represents a side effect and its required data
- `perform` executes the `Effect`, returns a `Msg`
- without Cmd, all types are user-defined, so UMP code doesn't depend on UMP lib