Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Equinox.Codec out to FsCodec #156

Merged
merged 13 commits into from
Aug 30, 2019
Prev Previous commit
Next Next commit
Rebase on FsCodec
Expose IEvent on Event
  • Loading branch information
bartelink committed Aug 30, 2019
commit 54a19621d1b610fabfcf7621d710a77b4f80acf6
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The `Unreleased` section name is replaced by the expected version of next releas
### Added
### Changed

- Extracted `Equinox.Codec` to external project `Gardelloyd`, with Json.net support in `Gardelloyd.NewtonsoftJson`
- Extracted `Equinox.Codec` to external project `FsCodec`, with Json.net support in `FsCodec.NewtonsoftJson`

### Removed
### Fixed
Expand Down
12 changes: 0 additions & 12 deletions Equinox.sln
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Equinox.MemoryStore", "src\
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Equinox.MemoryStore.Integration", "tests\Equinox.MemoryStore.Integration\Equinox.MemoryStore.Integration.fsproj", "{B2C695C3-ED04-4094-B672-926440B5F335}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Gardelloyd", "..\Gardelloyd\src\Gardelloyd\Gardelloyd.fsproj", "{F5491EB1-D072-4262-8184-2A908E1D6175}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Equinox.Tool", "tools\Equinox.Tool\Equinox.Tool.fsproj", "{C8992C1C-6DC5-42CD-A3D7-1C5663433FED}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Equinox.Cosmos", "src\Equinox.Cosmos\Equinox.Cosmos.fsproj", "{54EA6187-9F9F-4D67-B602-163D011E43E6}"
Expand All @@ -60,8 +58,6 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Tutorial", "samples\Tutoria
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Equinox.Tools.TestHarness", "tools\Equinox.Tools.TestHarness\Equinox.Tools.TestHarness.fsproj", "{C2EE7D8E-6982-41AD-ADCC-E6F586E93524}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Gardelloyd.NewtonsoftJson", "..\Gardelloyd\src\Gardelloyd.NewtonsoftJson\Gardelloyd.NewtonsoftJson.fsproj", "{C725B50F-1622-4E36-B013-309D18ED35DD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -112,10 +108,6 @@ Global
{B2C695C3-ED04-4094-B672-926440B5F335}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B2C695C3-ED04-4094-B672-926440B5F335}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B2C695C3-ED04-4094-B672-926440B5F335}.Release|Any CPU.Build.0 = Release|Any CPU
{F5491EB1-D072-4262-8184-2A908E1D6175}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F5491EB1-D072-4262-8184-2A908E1D6175}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F5491EB1-D072-4262-8184-2A908E1D6175}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F5491EB1-D072-4262-8184-2A908E1D6175}.Release|Any CPU.Build.0 = Release|Any CPU
{C8992C1C-6DC5-42CD-A3D7-1C5663433FED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C8992C1C-6DC5-42CD-A3D7-1C5663433FED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C8992C1C-6DC5-42CD-A3D7-1C5663433FED}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -140,10 +132,6 @@ Global
{C2EE7D8E-6982-41AD-ADCC-E6F586E93524}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2EE7D8E-6982-41AD-ADCC-E6F586E93524}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C2EE7D8E-6982-41AD-ADCC-E6F586E93524}.Release|Any CPU.Build.0 = Release|Any CPU
{C725B50F-1622-4E36-B013-309D18ED35DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C725B50F-1622-4E36-B013-309D18ED35DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C725B50F-1622-4E36-B013-309D18ED35DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C725B50F-1622-4E36-B013-309D18ED35DD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The implementations are distilled from [`Jet.com` systems dating all the way bac
- Designed not to invade application code; Domain tests can be written directly against your models without any need to involve or understand Equinox assemblies or constructs as part of writing those tests.
- Extracted from working software; currently used for all data storage within Jet's API gateway and Cart processing.
- Significant test coverage for core facilities, and with baseline and specific tests per Storage system and a comprehensive test and benchmarking story
- Encoding of events via `Gardelloyd.IUnionEncoder` provides for pluggable encoding of events based on either:
- Encoding of events via `FsCodec.IUnionEncoder` provides for pluggable encoding of events based on either:
- a [versionable convention-based approach](https://eiriktsarpalis.wordpress.com/2018/10/30/a-contract-pattern-for-schemaless-datastores/) (using `Typeshape`'s `UnionContractEncoder` under the covers), providing for serializer-agnostic schema evolution with minimal boilerplate
- an explicitly coded pair of `encode` and `tryDecode` functions for when you need to customize
- Independent of the store used, Equinox provides for caching using the .NET `MemoryCache` to minimize roundtrips, latency and bandwidth / Request Charges by maintaining the folded state, without necessitating making the Domain Model folded state serializable
Expand Down Expand Up @@ -50,11 +50,11 @@ The components within this repository are delivered as a series of multi-targete

### Serialization support

- `Gardelloyd` [![Codec NuGet](https://img.shields.io/nuget/v/Gardelloyd.svg)](https://www.nuget.org/packages/Gardelloyd/): [a scheme for the serializing Events modelled as an F# Discriminated Union](https://eiriktsarpalis.wordpress.com/2018/10/30/a-contract-pattern-for-schemaless-datastores/) ([depends](https://www.fuget.org/packages/Gardelloyd) on `TypeShape 7.*`
- `Gardelloyd.IUnionEncoder`: allows tagging of F# Discriminated Union cases in a versionable manner with low-dependency `DataMember(Name=` tags using [TypeShape](https://github.com/eiriktsarpalis/TypeShape)'s [`UnionContractEncoder`](https://github.com/eiriktsarpalis/TypeShape/blob/master/tests/TypeShape.Tests/UnionContractTests.fs)
- `Gardelloyd.Custom`: enables plugging in a serializer and/or Union Encoder of your choice (typically this is used to supply a pair of functions:- `encode` and `tryDecode`)
- `Gardelloyd.NewtonsoftJson` [![Codec NuGet](https://img.shields.io/nuget/v/Gardelloyd.NewtonsoftJson.svg)](https://www.nuget.org/packages/Gardelloyd.NewtonsoftJson/): Implementation of `Gardelloyd.IUnionEncoder` that uses Json.net to serialize the bodies of the union cases. ([depends](https://www.fuget.org/packages/Gardelloyd.NewtonsoftJson) on `Gardelloyd`, `Microsoft.IO.RecyclableMemoryStream 1.2.2`, `Newtonsoft.Json >= 11.0.2`
- (planned) `Gardelloyd.SystemTextJson`: drop in replacement that allows one to target the .NET `System.Text.Json` serializer solely by changing the referenced namespace.
- `FsCodec` [![Codec NuGet](https://img.shields.io/nuget/v/FsCodec.svg)](https://www.nuget.org/packages/FsCodec/): [a scheme for the serializing Events modelled as an F# Discriminated Union](https://eiriktsarpalis.wordpress.com/2018/10/30/a-contract-pattern-for-schemaless-datastores/) ([depends](https://www.fuget.org/packages/FsCodec) on `TypeShape 7.*`
- `FsCodec.IUnionEncoder`: allows tagging of F# Discriminated Union cases in a versionable manner with low-dependency `DataMember(Name=` tags using [TypeShape](https://github.com/eiriktsarpalis/TypeShape)'s [`UnionContractEncoder`](https://github.com/eiriktsarpalis/TypeShape/blob/master/tests/TypeShape.Tests/UnionContractTests.fs)
- `FsCodec.Codec`: enables plugging in a serializer and/or Union Encoder of your choice (typically this is used to supply a pair of functions:- `encode` and `tryDecode`)
- `FsCodec.NewtonsoftJson` [![Codec NuGet](https://img.shields.io/nuget/v/FsCodec.NewtonsoftJson.svg)](https://www.nuget.org/packages/FsCodec.NewtonsoftJson/): Implementation of `FsCodec.IUnionEncoder` that uses Json.net to serialize the bodies of the union cases. ([depends](https://www.fuget.org/packages/FsCodec.NewtonsoftJson) on `FsCodec`, `Microsoft.IO.RecyclableMemoryStream 1.2.2`, `Newtonsoft.Json >= 11.0.2`
- (planned) `FsCodec.SystemTextJson`: drop in replacement that allows one to target the .NET `System.Text.Json` serializer solely by changing the referenced namespace.

### Store libraries

Expand Down
1 change: 0 additions & 1 deletion samples/Infrastructure/Infrastructure.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
<ProjectReference Include="..\..\src\Equinox.Cosmos\Equinox.Cosmos.fsproj" />
<ProjectReference Include="..\..\src\Equinox.EventStore\Equinox.EventStore.fsproj" />
<ProjectReference Include="..\..\src\Equinox.MemoryStore\Equinox.MemoryStore.fsproj" />
<ProjectReference Include="..\..\..\Gardelloyd\src\Gardelloyd.NewtonsoftJson\Gardelloyd.NewtonsoftJson.fsproj" />
<ProjectReference Include="..\Store\Backend\Backend.fsproj" />
<ProjectReference Include="..\Store\Domain\Domain.fsproj" />
<ProjectReference Include="..\TodoBackend\TodoBackend.fsproj" />
Expand Down
2 changes: 1 addition & 1 deletion samples/Infrastructure/Services.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ open System

type StreamResolver(storage) =
member __.Resolve
( codec : Gardelloyd.IUnionEncoder<'event,byte[]>,
( codec : FsCodec.IUnionEncoder<'event,byte[]>,
fold: ('state -> 'event seq -> 'state),
initial: 'state,
snapshot: (('event -> bool) * ('state -> 'event))) =
Expand Down
2 changes: 1 addition & 1 deletion samples/Store/Domain/Cart.fs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module Events =
| ItemQuantityChanged of ItemQuantityChangeInfo
| ItemWaiveReturnsChanged of ItemWaiveReturnsInfo
interface TypeShape.UnionContract.IUnionContract
let codec = Gardelloyd.NewtonsoftJson.Codec.Create<Event>()
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()

module Folds =
type ItemInfo = { skuId: SkuId; quantity: int; returnsWaived: bool }
Expand Down
2 changes: 1 addition & 1 deletion samples/Store/Domain/ContactPreferences.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module Events =
type Event =
| [<System.Runtime.Serialization.DataMember(Name = "contactPreferencesChanged")>]Updated of Value
interface TypeShape.UnionContract.IUnionContract
let codec = Gardelloyd.NewtonsoftJson.Codec.Create<Event>()
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()

module Folds =
type State = Events.Preferences
Expand Down
7 changes: 2 additions & 5 deletions samples/Store/Domain/Domain.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,12 @@
<Compile Include="InventoryItem.fs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\..\Gardelloyd\src\Gardelloyd.NewtonsoftJson\Gardelloyd.NewtonsoftJson.fsproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="FSharp.Core" Version="3.1.2.5" Condition=" '$(TargetFramework)' == 'net461' " />
<PackageReference Include="FSharp.Core" Version="4.3.4" Condition=" '$(TargetFramework)' == 'netstandard2.0' " />

<PackageReference Include="FsCodec.NewtonsoftJson" Version="1.0.0-rc1" />
<PackageReference Include="FSharp.UMX" Version="1.0.0" />
</ItemGroup>

</Project>
</Project>
2 changes: 1 addition & 1 deletion samples/Store/Domain/Favorites.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module Events =
| Favorited of Favorited
| Unfavorited of Unfavorited
interface TypeShape.UnionContract.IUnionContract
let codec = Gardelloyd.NewtonsoftJson.Codec.Create<Event>()
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()

module Folds =
type State = Events.Favorited []
Expand Down
2 changes: 1 addition & 1 deletion samples/Store/Domain/Infrastructure.fs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[<AutoOpen>]
module Domain.Infrastructure

open Gardelloyd.NewtonsoftJson
open FsCodec.NewtonsoftJson
open FSharp.UMX
open Newtonsoft.Json
open System
Expand Down
2 changes: 1 addition & 1 deletion samples/Store/Domain/SavedForLater.fs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module Events =
/// Addition of a collection of skus to the list
| Added of Added
interface TypeShape.UnionContract.IUnionContract
let codec = Gardelloyd.NewtonsoftJson.Codec.Create<Event>()
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()

module Folds =
open Events
Expand Down
4 changes: 2 additions & 2 deletions samples/Store/Integration/CodecIntegration.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type EventWithOption = { age : int option }

type EventWithUnion = { value : Union }
// Using converter to collapse the `fields` of the union into the top level, alongside the `case`
and [<Newtonsoft.Json.JsonConverter(typeof<Gardelloyd.NewtonsoftJson.UnionConverter>)>] Union =
and [<Newtonsoft.Json.JsonConverter(typeof<FsCodec.NewtonsoftJson.UnionConverter>)>] Union =
| I of Int
| S of MaybeInt
and Int = { i : int }
Expand All @@ -38,7 +38,7 @@ let render = function
//| EventE i -> string i
//| EventF s -> Newtonsoft.Json.JsonConvert.SerializeObject s

let codec = Gardelloyd.NewtonsoftJson.Codec.Create()
let codec = FsCodec.NewtonsoftJson.Codec.Create()

[<AutoData(MaxTest=100)>]
let ``Can roundtrip, rendering correctly`` (x: SimpleDu) =
Expand Down
2 changes: 1 addition & 1 deletion samples/TodoBackend/Todo.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module Events =
| Cleared
| Compacted of CompactedInfo
interface TypeShape.UnionContract.IUnionContract
let codec = Gardelloyd.NewtonsoftJson.Codec.Create<Event>()
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()

module Folds =
type State = { items : Todo list; nextId : int }
Expand Down
6 changes: 3 additions & 3 deletions samples/Tutorial/Cosmos.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#r "Newtonsoft.Json.dll"
#r "TypeShape.dll"
#r "Equinox.dll"
#r "Gardelloyd.dll"
#r "Gardelloyd.NewtonsoftJson.dll"
#r "FsCodec.dll"
#r "FsCodec.NewtonsoftJson.dll"
#r "FSharp.Control.AsyncSeq.dll"
#r "Microsoft.Azure.DocumentDb.Core.dll"
#r "System.Net.Http"
Expand All @@ -25,7 +25,7 @@ module Favorites =
| Added of string
| Removed of string
interface TypeShape.UnionContract.IUnionContract
let codec = Gardelloyd.NewtonsoftJson.Codec.Create<Event>()
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()
let initial : string list = []
let evolve state = function
| Added sku -> sku :: state
Expand Down
2 changes: 1 addition & 1 deletion samples/Tutorial/Favorites.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Event =
| Removed of string
// No IUnionContract or Codec required as we're using MemoryStore in this part
// interface TypeShape.UnionContract.IUnionContract
//let codec = Gardelloyd.NewtonsoftJson.Codec.Create<Event>()
//let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()

let initial : string list = []
let evolve state = function
Expand Down
6 changes: 3 additions & 3 deletions samples/Tutorial/Todo.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#r "Newtonsoft.Json.dll"
#r "TypeShape.dll"
#r "Equinox.dll"
#r "Gardelloyd.dll"
#r "Gardelloyd.NewtonsoftJson.dll"
#r "FsCodec.dll"
#r "FsCodec.NewtonsoftJson.dll"
#r "FSharp.Control.AsyncSeq.dll"
#r "Microsoft.Azure.DocumentDb.Core.dll"
#r "Equinox.Cosmos.dll"
Expand All @@ -31,7 +31,7 @@ type Event =
| Cleared
| Compacted of CompactedInfo
interface TypeShape.UnionContract.IUnionContract
let codec = Gardelloyd.NewtonsoftJson.Codec.Create<Event>()
let codec = FsCodec.NewtonsoftJson.Codec.Create<Event>()

type State = { items : Todo list; nextId : int }
let initial = { items = []; nextId = 0 }
Expand Down
1 change: 0 additions & 1 deletion samples/Tutorial/Tutorial.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\Gardelloyd\src\Gardelloyd.NewtonsoftJson\Gardelloyd.NewtonsoftJson.fsproj" />
<ProjectReference Include="..\..\src\Equinox.Cosmos\Equinox.Cosmos.fsproj" />
<ProjectReference Include="..\..\src\Equinox.MemoryStore\Equinox.MemoryStore.fsproj" />
<ProjectReference Include="..\..\src\Equinox\Equinox.fsproj" />
Expand Down
Loading