You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Typically that binding module can live with your test helpers rather than
@@ -479,7 +521,7 @@ events on a given category of stream:
479
521
tests and used to parameterize the Category's storage configuration._.
480
522
Sometimes named `apply`)
481
523
482
-
-`interpret: (context/command etc ->) 'state -> event' list` or `decide: (context/command etc ->) 'state -> 'result*'event list`: responsible for _Deciding_ (in an [idempotent](https://en.wikipedia.org/wiki/Idempotence) manner) how the intention represented by `context/command` should be mapped with regard to the provided `state` in terms of:
524
+
-`interpret: (context/command etc ->) 'state -> 'event[]` or `decide: (context/command etc ->) 'state -> 'result * 'event[]`: responsible for _Deciding_ (in an [idempotent](https://en.wikipedia.org/wiki/Idempotence) manner) how the intention represented by `context/command` should be mapped with regard to the provided `state` in terms of:
483
525
a) the `'events` that should be written to the stream to record the decision
484
526
b) (for the `'result` in the `decide` signature) any response to be returned to the invoker (NB returning a result likely represents a violation of the [CQS](https://en.wikipedia.org/wiki/Command%E2%80%93query_separation) and/or CQRS principles, [see Synchronous Query in the Glossary](#glossary))
485
527
@@ -574,10 +616,10 @@ type Command =
574
616
| Remove of itemId: int
575
617
576
618
let interpret command state =
577
-
let has id = state |> List.exits (is id)
619
+
let has id = state |> List.exists (is id)
578
620
match command with
579
-
| Add item -> if has item.id then [] else [Added item]
580
-
| Remove id -> if has id then [Removed id] else []
621
+
| Add item -> if has item.id then [||] else [| Added item |]
622
+
| Remove id -> if has id then [| Removed id |] else [||]
581
623
582
624
(*
583
625
* Optional: Snapshot/Unfold-related functions to allow establish state
@@ -710,15 +752,15 @@ follow!
710
752
711
753
```fsharp
712
754
type Equinox.Decider(...) =
713
-
StoreIntegration
755
+
714
756
// Run interpret function with present state, retrying with Optimistic Concurrency
715
-
member _.Transact(interpret: State -> Event list): Async<unit>
757
+
member _.Transact(interpret: 'state -> 'event[]): Async<unit>
716
758
717
759
// Run decide function with present state, retrying with Optimistic Concurrency, yielding Result on exit
718
-
member _.Transact(decide: State -> Result*Event list): Async<Result>
760
+
member _.Transact(decide: 'state -> 'result * 'event[]): Async<'result>
719
761
720
762
// Runs a Null Flow that simply yields a `projection` of `Context.State`
721
-
member _.Query(projection: State -> View): Async<View>
763
+
member _.Query(projection: 'state -> 'view): Async<'view>
722
764
```
723
765
724
766
### Favorites walkthrough
@@ -789,8 +831,8 @@ type Command =
789
831
| Remove of string
790
832
let interpret command state =
791
833
match command with
792
-
| Add sku -> if state |> List.contains sku then [] else [Added sku]
793
-
| Remove sku -> if state |> List.contains sku |> not then [] else [Removed sku]
834
+
| Add sku -> if state |> List.contains sku then [||] else [| Added sku |]
835
+
| Remove sku -> if state |> List.contains sku |> not then [||] else [| Removed sku |]
794
836
```
795
837
796
838
Command handling should almost invariably be implemented in an
@@ -1006,13 +1048,13 @@ let fold = Array.fold evolve
1006
1048
type Command = Add of Todo | Update of Todo | Delete of id: int | Clear
1007
1049
let interpret c (state: State) =
1008
1050
match c with
1009
-
| Add value -> [Added { value with id = state.nextId }]
1051
+
| Add value -> [| Added { value with id = state.nextId } |]
1010
1052
| Update value ->
1011
1053
match state.items |> List.tryFind (function { id = id } -> id = value.id) with
1012
-
| Some current when current <> value -> [Updated value]
1013
-
| _ -> []
1014
-
| Delete id -> if state.items |> List.exists (fun x -> x.id = id) then [Deleted id] else []
1015
-
| Clear -> if state.items |> List.isEmpty then [] else [Cleared]
1054
+
| Some current when current <> value -> [| Updated value |]
1055
+
| _ -> [||]
1056
+
| Delete id -> if state.items |> List.exists (fun x -> x.id = id) then [| Deleted id |] else [||]
1057
+
| Clear -> if state.items |> List.isEmpty then [||] else [| Cleared |]
1016
1058
```
1017
1059
1018
1060
- Note `Add` does not adhere to the normal idempotency constraint, being
@@ -1130,7 +1172,7 @@ In this case, the Decision Process is `interpret`ing the _Command_ in the
member _.Run(cartId, optimistic, commands: Command seq, ?prepare): Async<Fold.State> =
1381
1423
let decider = resolve cartId
1382
-
let opt = if optimistic then Equinox.AnyCachedValue else Equinox.RequireLoad
1424
+
let opt = if optimistic then Equinox.LoadOption.AnyCachedValue else Equinox.LoadOption.RequireLoad
1383
1425
decider.Transact(fun state -> async {
1384
1426
match prepare with None -> () | Some prep -> do! prep
1385
1427
let acc = Accumulator(Fold.fold, state)
@@ -1453,11 +1495,8 @@ Key aspects relevant to the Equinox programming model:
1453
1495
- In general, EventStore provides excellent caching and performance
1454
1496
characteristics intrinsically by virtue of its design
1455
1497
1456
-
- Projections can be managed by either tailing streams (including the synthetic
1457
-
`$all` stream) or using the Projections facility - there's no obvious reason
1458
-
to wrap it, aside from being able to uniformly target CosmosDB (i.e. one
1459
-
could build an `Equinox.EventStore.Projection` library and an `eqx project
1460
-
stats es` with very little code).
1498
+
- Projections can be managed by the `Propulsion.EventStoreDb` library; there is also
1499
+
an `eqx project stats es` feature).
1461
1500
1462
1501
- In general event streams should be considered append only, with no mutations
1463
1502
or deletes
@@ -2339,7 +2378,7 @@ For Domain Events in an event-sourced model, their permanence and immutability i
2339
2378
2340
2379
It should be noted with regard to such requirements:
2341
2380
- EventStoreDB does not present any APIs for mutation of events, though deleting events is a fully supported operation (although that can be restricted). Rewrites are typically approached by doing an offline database rebuild.
2342
-
-`Equinox.Cosmos` and `Equinox.CosmosStore`include support for pruning events (only) from the head of a stream. Obviously, there's nothing stopping you deleting or altering the Batch documents out of band via the underlying CosmosDB APIs directly (Note however that the semantics of document ordering within a logical partition means its strongly advised not to mutate any event Batch documents as this will cause their ordering to become incorrect relative to other events, invalidating a key tenet that Change Feed Processors rely on).
2381
+
-`Equinox.CosmosStore`includes support for pruning events (only) from the head of a stream. Obviously, there's nothing stopping you deleting or altering the Batch documents out of band via the underlying CosmosDB APIs directly (Note however that the semantics of document ordering within a logical partition means its strongly advised not to mutate any event Batch documents as this will cause their ordering to become incorrect relative to other events, invalidating a key tenet that Change Feed Processors rely on).
0 commit comments