packages feed

crdt-event-fold 1.2.1.1 → 1.3.0.0

raw patch · 3 files changed

+77/−24 lines, 3 filesdep +aesondep +monad-loggerPVP ok

version bump matches the API change (PVP)

Dependencies added: aeson, monad-logger

API changes (from Hackage documentation)

- Data.CRDT.EventFold.Monad: class MonadEventFold o p e m | m -> o p e
- Data.CRDT.EventFold.Monad: instance (GHC.Classes.Eq (Data.CRDT.EventFold.Output e), GHC.Classes.Eq e, GHC.Classes.Eq o, Data.CRDT.EventFold.Event e, GHC.Base.Monad m, GHC.Classes.Ord p) => Data.CRDT.EventFold.Monad.MonadEventFold o p e (Data.CRDT.EventFold.Monad.EventFoldT o p e m)
+ Data.CRDT.EventFold: instance (Data.Aeson.Types.ToJSON.ToJSON o, Data.Aeson.Types.ToJSON.ToJSON p, Data.Aeson.Types.ToJSON.ToJSON (Data.CRDT.EventFold.State e), Data.Aeson.Types.ToJSON.ToJSON (f (Data.CRDT.EventFold.Delta p e))) => Data.Aeson.Types.ToJSON.ToJSON (Data.CRDT.EventFold.EventFoldF o p e f)
+ Data.CRDT.EventFold: instance (Data.Aeson.Types.ToJSON.ToJSON o, Data.Aeson.Types.ToJSON.ToJSON p, Data.Aeson.Types.ToJSON.ToJSON e, Data.Aeson.Types.ToJSON.ToJSON (Data.CRDT.EventFold.Output e)) => Data.Aeson.Types.ToJSON.ToJSON (Data.CRDT.EventFold.Diff o p e)
+ Data.CRDT.EventFold: instance (Data.Aeson.Types.ToJSON.ToJSON o, Data.Aeson.Types.ToJSON.ToJSON p, Data.Aeson.Types.ToJSON.ToJSON e, Data.Aeson.Types.ToJSON.ToJSON (Data.CRDT.EventFold.Output e), Data.Aeson.Types.ToJSON.ToJSON (Data.CRDT.EventFold.State e)) => Data.Aeson.Types.ToJSON.ToJSON (Data.CRDT.EventFold.EventFold o p e)
+ Data.CRDT.EventFold: instance (Data.Aeson.Types.ToJSON.ToJSON o, Data.Aeson.Types.ToJSON.ToJSON p, Data.Aeson.Types.ToJSON.ToJSON e, Data.Aeson.Types.ToJSON.ToJSON (Data.CRDT.EventFold.Output e), Data.Aeson.Types.ToJSON.ToJSON (Data.CRDT.EventFold.State e)) => Data.Aeson.Types.ToJSON.ToJSON (Data.CRDT.EventFold.MergeError o p e)
+ Data.CRDT.EventFold: instance (Data.Aeson.Types.ToJSON.ToJSON p, Data.Aeson.Types.ToJSON.ToJSON e, Data.Aeson.Types.ToJSON.ToJSON (Data.CRDT.EventFold.Output e)) => Data.Aeson.Types.ToJSON.ToJSON (Data.CRDT.EventFold.Delta p e)
+ Data.CRDT.EventFold: instance (Data.Aeson.Types.ToJSON.ToJSON s, Data.Aeson.Types.ToJSON.ToJSON p) => Data.Aeson.Types.ToJSON.ToJSON (Data.CRDT.EventFold.Infimum s p)
+ Data.CRDT.EventFold: instance (GHC.Classes.Ord p, Data.Aeson.Types.FromJSON.FromJSON o, Data.Aeson.Types.FromJSON.FromJSON p, Data.Aeson.Types.FromJSON.FromJSON (f (Data.CRDT.EventFold.Delta p e)), Data.Aeson.Types.FromJSON.FromJSON (Data.CRDT.EventFold.State e)) => Data.Aeson.Types.FromJSON.FromJSON (Data.CRDT.EventFold.EventFoldF o p e f)
+ Data.CRDT.EventFold: instance (GHC.Classes.Ord p, Data.Aeson.Types.FromJSON.FromJSON o, Data.Aeson.Types.FromJSON.FromJSON p, Data.Aeson.Types.FromJSON.FromJSON e, Data.Aeson.Types.FromJSON.FromJSON (Data.CRDT.EventFold.Output e)) => Data.Aeson.Types.FromJSON.FromJSON (Data.CRDT.EventFold.Diff o p e)
+ Data.CRDT.EventFold: instance (GHC.Classes.Ord p, Data.Aeson.Types.FromJSON.FromJSON o, Data.Aeson.Types.FromJSON.FromJSON p, Data.Aeson.Types.FromJSON.FromJSON e, Data.Aeson.Types.FromJSON.FromJSON (Data.CRDT.EventFold.Output e), Data.Aeson.Types.FromJSON.FromJSON (Data.CRDT.EventFold.State e)) => Data.Aeson.Types.FromJSON.FromJSON (Data.CRDT.EventFold.EventFold o p e)
+ Data.CRDT.EventFold: instance (GHC.Classes.Ord p, Data.Aeson.Types.FromJSON.FromJSON o, Data.Aeson.Types.FromJSON.FromJSON p, Data.Aeson.Types.FromJSON.FromJSON e, Data.Aeson.Types.FromJSON.FromJSON (Data.CRDT.EventFold.State e), Data.Aeson.Types.FromJSON.FromJSON (Data.CRDT.EventFold.Output e)) => Data.Aeson.Types.FromJSON.FromJSON (Data.CRDT.EventFold.MergeError o p e)
+ Data.CRDT.EventFold: instance (GHC.Classes.Ord p, Data.Aeson.Types.FromJSON.FromJSON p, Data.Aeson.Types.FromJSON.FromJSON e, Data.Aeson.Types.FromJSON.FromJSON (Data.CRDT.EventFold.Output e)) => Data.Aeson.Types.FromJSON.FromJSON (Data.CRDT.EventFold.Delta p e)
+ Data.CRDT.EventFold: instance (GHC.Classes.Ord p, Data.Aeson.Types.FromJSON.FromJSON p, Data.Aeson.Types.FromJSON.FromJSON s) => Data.Aeson.Types.FromJSON.FromJSON (Data.CRDT.EventFold.Infimum s p)
+ Data.CRDT.EventFold: instance Data.Aeson.Types.FromJSON.FromJSON Data.CRDT.EventFold.Word256
+ Data.CRDT.EventFold: instance Data.Aeson.Types.FromJSON.FromJSON p => Data.Aeson.Types.FromJSON.FromJSON (Data.CRDT.EventFold.EventId p)
+ Data.CRDT.EventFold: instance Data.Aeson.Types.FromJSON.FromJSON p => Data.Aeson.Types.FromJSON.FromJSONKey (Data.CRDT.EventFold.EventId p)
+ Data.CRDT.EventFold: instance Data.Aeson.Types.ToJSON.ToJSON Data.CRDT.EventFold.Word256
+ Data.CRDT.EventFold: instance Data.Aeson.Types.ToJSON.ToJSON p => Data.Aeson.Types.ToJSON.ToJSON (Data.CRDT.EventFold.EventId p)
+ Data.CRDT.EventFold: instance Data.Aeson.Types.ToJSON.ToJSON p => Data.Aeson.Types.ToJSON.ToJSONKey (Data.CRDT.EventFold.EventId p)
+ Data.CRDT.EventFold: instance Data.Binary.Class.Binary Data.CRDT.EventFold.Word256
+ Data.CRDT.EventFold: instance GHC.Classes.Eq Data.CRDT.EventFold.Word256
+ Data.CRDT.EventFold: instance GHC.Classes.Ord Data.CRDT.EventFold.Word256
+ Data.CRDT.EventFold: instance GHC.Enum.Enum Data.CRDT.EventFold.Word256
+ Data.CRDT.EventFold: instance GHC.Generics.Generic (Data.CRDT.EventFold.MergeError o p e)
+ Data.CRDT.EventFold: instance GHC.Generics.Generic Data.CRDT.EventFold.Word256
+ Data.CRDT.EventFold: instance GHC.Num.Num Data.CRDT.EventFold.Word256
+ Data.CRDT.EventFold: instance GHC.Show.Show Data.CRDT.EventFold.Word256
+ Data.CRDT.EventFold.Monad: class (Monad m) => MonadInspectEF o p e m | m -> o p e
+ Data.CRDT.EventFold.Monad: class MonadUpdateEF o p e m | m -> o p e
+ Data.CRDT.EventFold.Monad: efAsk :: MonadInspectEF o p e m => m (EventFold o p e)
+ Data.CRDT.EventFold.Monad: efAsks :: MonadInspectEF o p e m => (EventFold o p e -> a) -> m a
+ Data.CRDT.EventFold.Monad: instance (GHC.Classes.Eq (Data.CRDT.EventFold.Output e), GHC.Classes.Eq e, GHC.Classes.Eq o, Data.CRDT.EventFold.Event e, GHC.Base.Monad m, GHC.Classes.Ord p) => Data.CRDT.EventFold.Monad.MonadUpdateEF o p e (Data.CRDT.EventFold.Monad.EventFoldT o p e m)
+ Data.CRDT.EventFold.Monad: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Data.CRDT.EventFold.Monad.EventFoldT o p e m)
+ Data.CRDT.EventFold.Monad: instance Control.Monad.Logger.MonadLogger m => Control.Monad.Logger.MonadLogger (Data.CRDT.EventFold.Monad.EventFoldT o p e m)
+ Data.CRDT.EventFold.Monad: instance Control.Monad.Logger.MonadLoggerIO m => Control.Monad.Logger.MonadLoggerIO (Data.CRDT.EventFold.Monad.EventFoldT o p e m)
+ Data.CRDT.EventFold.Monad: instance GHC.Base.Monad m => Data.CRDT.EventFold.Monad.MonadInspectEF o p e (Data.CRDT.EventFold.Monad.EventFoldT o p e m)
- Data.CRDT.EventFold.Monad: diffMerge :: MonadEventFold o p e m => Diff o p e -> m (Either (MergeError o p e) ())
+ Data.CRDT.EventFold.Monad: diffMerge :: MonadUpdateEF o p e m => Diff o p e -> m (Either (MergeError o p e) ())
- Data.CRDT.EventFold.Monad: disassociate :: MonadEventFold o p e m => p -> m (EventId p)
+ Data.CRDT.EventFold.Monad: disassociate :: MonadUpdateEF o p e m => p -> m (EventId p)
- Data.CRDT.EventFold.Monad: event :: MonadEventFold o p e m => e -> m (Output e, EventId p)
+ Data.CRDT.EventFold.Monad: event :: MonadUpdateEF o p e m => e -> m (Output e, EventId p)
- Data.CRDT.EventFold.Monad: fullMerge :: MonadEventFold o p e m => EventFold o p e -> m (Either (MergeError o p e) ())
+ Data.CRDT.EventFold.Monad: fullMerge :: MonadUpdateEF o p e m => EventFold o p e -> m (Either (MergeError o p e) ())
- Data.CRDT.EventFold.Monad: participate :: MonadEventFold o p e m => p -> m (EventId p)
+ Data.CRDT.EventFold.Monad: participate :: MonadUpdateEF o p e m => p -> m (EventId p)

Files

crdt-event-fold.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                crdt-event-fold-version:             1.2.1.1+version:             1.3.0.0 synopsis:            Garbage collected event folding CRDT. description:         Garbage collected event folding CRDT. Consistently                      apply arbitrary operations to replicated data.@@ -24,11 +24,13 @@   -- other-modules:          -- other-extensions:       build-depends:+    aeson              >= 1.4.7.1 && < 1.5,     base               >= 4.13    && < 4.14,     binary             >= 0.8.7.0 && < 0.9,     containers         >= 0.6.2.1 && < 0.7,     data-default-class >= 0.1.2.0 && < 0.2,     data-dword         >= 0.3.2   && < 0.4,+    monad-logger       >= 0.3.35  && < 0.4,     mtl                >= 2.2.2   && < 2.3,     transformers       >= 0.5.6.2 && < 0.6   hs-source-dirs:      src
src/Data/CRDT/EventFold.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE FlexibleContexts #-}@@ -9,6 +10,7 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -Wmissing-deriving-strategies #-}+{-# OPTIONS_GHC -Wmissing-import-lists #-}  {- | Description: Garbage collected event folding CRDT. -} module Data.CRDT.EventFold (@@ -164,16 +166,17 @@ ) where  +import Data.Aeson (FromJSON(parseJSON), ToJSON(toEncoding, toJSON),+  FromJSONKey, ToJSONKey) import Data.Bifunctor (first) import Data.Binary (Binary(get, put)) import Data.Default.Class (Default(def))-import Data.DoubleWord (Word128(Word128), Word256(Word256)) import Data.Functor.Identity (Identity(Identity), runIdentity) import Data.Map (Map, keys, toAscList, toDescList, unionWith) import Data.Maybe (catMaybes) import Data.Set ((\\), Set, member, union)-import Data.Word (Word64) import GHC.Generics (Generic)+import qualified Data.DoubleWord as DW import qualified Data.Map as Map import qualified Data.Map.Merge.Lazy as Map.Merge import qualified Data.Set as Set@@ -183,7 +186,10 @@      psOrigin :: o,     psInfimum :: Infimum (State e) p,      psEvents :: Map (EventId p) (f (Delta p e), Set p)-  } deriving stock (Generic)+  }+  deriving stock (Generic)+deriving anyclass instance (ToJSON o, ToJSON p, ToJSON (State e), ToJSON (f (Delta p e))) => ToJSON (EventFoldF o p e f)+deriving anyclass instance (Ord p, FromJSON o, FromJSON p, FromJSON (f (Delta p e)), FromJSON (State e)) => FromJSON (EventFoldF o p e f) deriving stock instance     ( Eq (f (Delta p e))     , Eq (Output e)@@ -239,6 +245,8 @@   difficult to detect) behavior. -} newtype EventFold o p e = EventFold { unEventFold :: EventFoldF o p e Identity}+deriving newtype instance (ToJSON o, ToJSON p, ToJSON e, ToJSON (Output e), ToJSON (State e)) => ToJSON (EventFold o p e)+deriving newtype instance (Ord p, FromJSON o, FromJSON p, FromJSON e, FromJSON (Output e), FromJSON (State e)) => FromJSON (EventFold o p e) deriving stock instance     (Show o, Show p, Show e, Show (Output e), Show (State e))   =>@@ -261,7 +269,9 @@          eventId :: EventId p,     participants :: Set p,       stateValue :: s-  } deriving stock (Generic, Show)+  }+  deriving stock (Generic, Show)+  deriving anyclass (ToJSON, FromJSON) instance (Binary s, Binary p) => Binary (Infimum s p) instance (Eq p) => Eq (Infimum s p) where   Infimum s1 _ _ == Infimum s2 _ _ = s1 == s2@@ -278,23 +288,34 @@   = BottomEid   | Eid Word256 p   deriving stock (Generic, Eq, Ord, Show)-instance (Binary p) => Binary (EventId p) where-  put = put . toMaybe-    where-      toMaybe :: EventId p -> Maybe (Word64, Word64, Word64, Word64, p)-      toMaybe BottomEid =-        Nothing-      toMaybe (Eid (Word256 (Word128 a b) (Word128 c d)) p) =-        Just (a, b, c, d, p)-  get = do-    theThing <- get-    return $ case theThing of-      Nothing -> BottomEid-      Just (a, b, c, d, p) -> Eid (Word256 (Word128 a b) (Word128 c d)) p+  deriving anyclass (ToJSON, FromJSON, ToJSONKey, FromJSONKey, Binary) instance Default (EventId p) where   def = BottomEid  +{- | Newtype around 'DW.Word256' to supply typeclass instances. -}+newtype Word256 = Word256 {+    unWord256 :: DW.Word256+  }+  deriving stock (Generic)+  deriving newtype (Eq, Ord, Show, Enum, Num)+instance FromJSON Word256 where+  parseJSON v = do+    (a, b, c, d) <- parseJSON v+    pure (Word256 (DW.Word256 (DW.Word128 a b) (DW.Word128 c d)))+instance ToJSON Word256 where+  toJSON (Word256 (DW.Word256 (DW.Word128 a b) (DW.Word128 c d))) =+    toJSON (a, b, c, d)+  toEncoding (Word256 (DW.Word256 (DW.Word128 a b) (DW.Word128 c d))) =+    toEncoding (a, b, c, d)+instance Binary Word256 where+  put (Word256 (DW.Word256 (DW.Word128 a b) (DW.Word128 c d))) =+    put (a, b, c, d)+  get = do+    (a, b, c, d) <- get+    pure (Word256 (DW.Word256 (DW.Word128 a b) (DW.Word128 c d)))++ {- |   This is the exception type for illegal merges. These errors indicate   serious programming bugs.@@ -324,6 +345,9 @@       or else some other participant erroneously acknowledged some events       on our behalf.     -}+  deriving stock (Generic)+deriving anyclass instance (Ord p, FromJSON o, FromJSON p, FromJSON e, FromJSON (State e), FromJSON (Output e)) => FromJSON (MergeError o p e)+deriving anyclass instance (ToJSON o, ToJSON p, ToJSON e, ToJSON (Output e), ToJSON (State e)) => ToJSON (MergeError o p e) deriving stock instance     ( Show (Output e)     , Show o@@ -342,6 +366,8 @@   | Event e   | Error (Output e) (Set p)   deriving stock (Generic)+deriving anyclass instance (ToJSON p, ToJSON e, ToJSON (Output e)) => ToJSON (Delta p e)+deriving anyclass instance (Ord p, FromJSON p, FromJSON e, FromJSON (Output e)) => (FromJSON (Delta p e)) deriving stock instance (Eq p, Eq e, Eq (Output e)) => Eq (Delta p e) deriving stock instance (Show p, Show e, Show (Output e)) => Show (Delta p e) instance (Binary p, Binary e, Binary (Output e)) => Binary (Delta p e)@@ -485,6 +511,8 @@     diffInfimum :: EventId p   }   deriving stock (Generic)+deriving anyclass instance (ToJSON o, ToJSON p, ToJSON e, ToJSON (Output e)) => ToJSON (Diff o p e)+deriving anyclass instance (Ord p, FromJSON o, FromJSON p, FromJSON e, FromJSON (Output e)) => FromJSON (Diff o p e) deriving stock instance (     Show o, Show p, Show e, Show (Output e)   ) =>
src/Data/CRDT/EventFold/Monad.hs view
@@ -12,17 +12,20 @@  {- | Description: Monadic interaction with an EventFold. -} module Data.CRDT.EventFold.Monad (-  MonadEventFold(..),+  MonadUpdateEF(..),+  MonadInspectEF(..),   EventFoldT,   runEventFoldT, ) where  +import Control.Monad.IO.Class (MonadIO)+import Control.Monad.Logger (MonadLogger, MonadLoggerIO) import Control.Monad.Reader (MonadReader(ask), ReaderT(runReaderT))-import Control.Monad.State (MonadState(state), StateT, runStateT)+import Control.Monad.State (MonadState(state), StateT, gets, runStateT) import Control.Monad.Trans.Class (MonadTrans(lift)) import Data.CRDT.EventFold (Event(Output), UpdateResult(UpdateResult),-  Diff, EventFold, EventId, MergeError)+  Diff, EventFold, EventId, MergeError, urEventFold) import qualified Data.CRDT.EventFold as EF (diffMerge, disassociate,   event, fullMerge, participate) @@ -36,7 +39,7 @@   - The accumulated consistent outputs.   - Whether the 'EventFold' needs to be propagated to other participants. -}-class MonadEventFold o p e m | m -> o p e where+class MonadUpdateEF o p e m | m -> o p e where   {- | Apply an event. See 'EF.event'. -}   event :: e -> m (Output e, EventId p) @@ -56,7 +59,20 @@   {- | Remove a peer from participation. See 'EF.disassociate'. -}   disassociate :: p -> m (EventId p) -{- | A transformer providing 'MonadEventFold'. -}++{- |+  Interface for inspecting an Eventfold contained within the monadic+  context.+-}+class (Monad m) => MonadInspectEF o p e m | m -> o p e where+  efAsks :: (EventFold o p e -> a) -> m a+  efAsks f = f <$> efAsk++  efAsk :: m (EventFold o p e)+  efAsk = efAsks id+++{- | A transformer providing 'MonadUpdateEF' and 'MonadInspectEF'. -} newtype EventFoldT o p e m a = EventFoldT {     unEventFoldT ::       StateT (UpdateResult o p e) (@@ -67,10 +83,17 @@     ( Applicative     , Functor     , Monad+    , MonadIO+    , MonadLogger+    , MonadLoggerIO     ) instance MonadTrans (EventFoldT o p e) where   lift = EventFoldT . lift . lift +instance (Monad m) => MonadInspectEF o p e (EventFoldT o p e m) where+  efAsks f = EventFoldT $ gets (f . urEventFold)+  efAsk = EventFoldT $ gets urEventFold+ instance     ( Eq (Output e)     , Eq e@@ -80,7 +103,7 @@     , Ord p     )   =>-    MonadEventFold o p e (EventFoldT o p e m)+    MonadUpdateEF o p e (EventFoldT o p e m)   where     event e =       withEF