-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Append-only cooperative agreement
@package appendful
@version 0.0.0.0
-- | A way to synchronise items without merge conflicts.
--
-- This concept has a few requirements:
--
--
-- - Items must be immutable.
-- - Items must allow for a centrally unique identifier monotone
-- identifier.
-- - Items must allow for a client-side unique identifier.
-- - Identifiers for items must be generated in such a way that they
-- are certainly unique.
--
--
-- Should mutation be a requirement, then there is another library:
-- mergeful for exactly this purpose.
--
-- There are a few obvious candidates for identifiers:
--
--
-- - incremental identifiers
-- - universally unique identifiers (recommended).
--
--
-- The typical setup is as follows:
--
--
-- - A central server is set up to synchronise with
-- - Each client synchronises with the central server, but never with
-- eachother
--
--
-- A central server should operate as follows:
--
--
--
-- A client should operate as follows:
--
--
module Data.Appendful.Collection
-- | A client-side store of items with Client Id's of type ci,
-- Server Id's of type i and values of type a
data ClientStore ci si a
ClientStore :: !Map ci a -> !Map si a -> ClientStore ci si a
[clientStoreAdded] :: ClientStore ci si a -> !Map ci a
[clientStoreSynced] :: ClientStore ci si a -> !Map si a
-- | A synchronisation request for items with Client Id's of type
-- ci, Server Id's of type i and values of type
-- a
data SyncRequest ci si a
SyncRequest :: !Map ci a -> !Maybe si -> SyncRequest ci si a
[syncRequestAdded] :: SyncRequest ci si a -> !Map ci a
[syncRequestMaximumSynced] :: SyncRequest ci si a -> !Maybe si
-- | A synchronisation response for items with identifiers of type
-- i and values of type a
data SyncResponse ci si a
SyncResponse :: !Map ci si -> !Map si a -> SyncResponse ci si a
[syncResponseClientAdded] :: SyncResponse ci si a -> !Map ci si
[syncResponseServerAdded] :: SyncResponse ci si a -> !Map si a
data ClientSyncProcessor ci si a m
ClientSyncProcessor :: (Map ci si -> m ()) -> (Map si a -> m ()) -> ClientSyncProcessor ci si a m
[clientSyncProcessorSyncClientAdded] :: ClientSyncProcessor ci si a m -> Map ci si -> m ()
[clientSyncProcessorSyncServerAdded] :: ClientSyncProcessor ci si a m -> Map si a -> m ()
mergeSyncResponseCustom :: Monad m => ClientSyncProcessor ci si a m -> SyncResponse ci si a -> m ()
-- | The client store with no items.
emptyClientStore :: ClientStore ci si a
-- | A Client-side identifier for items for use with pure client stores
--
-- These only need to be unique at the client.
newtype ClientId
ClientId :: Word64 -> ClientId
[unClientId] :: ClientId -> Word64
-- | The number of items in a store
--
-- This does not count the deleted items, so that those really look
-- deleted.
storeSize :: ClientStore ci si a -> Int
-- | Add an item to a client store as an added item.
--
-- This will take care of the uniqueness constraint of the cis
-- in the map.
--
-- The values wrap around when reaching maxBound.
addItemToClientStore :: (Enum ci, Bounded ci, Ord ci) => a -> ClientStore ci si a -> ClientStore ci si a
emptySyncRequest :: SyncRequest ci si a
-- | Produce a synchronisation request for a client-side store.
--
-- This request can then be sent to a central store for synchronisation.
makeSyncRequest :: ClientStore ci si a -> SyncRequest ci si a
-- | Merge a synchronisation response back into a client-side store.
mergeSyncResponse :: forall ci si a. (Ord ci, Ord si) => ClientStore ci si a -> SyncResponse ci si a -> ClientStore ci si a
pureClientSyncProcessor :: forall ci si a. (Ord ci, Ord si) => ClientSyncProcessor ci si a (State (ClientStore ci si a))
-- | A record of the basic operations that are necessary to build a
-- synchronisation processor.
data ServerSyncProcessor ci si a m
ServerSyncProcessor :: m (Map si a) -> (Map ci a -> m (Map ci si)) -> ServerSyncProcessor ci si a m
[serverSyncProcessorRead] :: ServerSyncProcessor ci si a m -> m (Map si a)
[serverSyncProcessorAddItems] :: ServerSyncProcessor ci si a m -> Map ci a -> m (Map ci si)
processServerSyncCustom :: forall ci si a m. (Ord si, Monad m) => ServerSyncProcessor ci si a m -> SyncRequest ci si a -> m (SyncResponse ci si a)
-- | A central store of items with identifiers of type i and
-- values of type a
newtype ServerStore si a
ServerStore :: Map si a -> ServerStore si a
[serverStoreItems] :: ServerStore si a -> Map si a
-- | An empty central store to start with
emptyServerStore :: ServerStore si a
emptySyncResponse :: SyncResponse ci si a
-- | Process a server-side synchronisation request using a server id
-- generator
--
-- see processSyncCustom
processServerSync :: forall m ci si a. (Ord si, Monad m) => m si -> ServerStore si a -> SyncRequest ci si a -> m (SyncResponse ci si a, ServerStore si a)
instance Data.Aeson.Types.FromJSON.FromJSONKey Data.Appendful.Collection.ClientId
instance Data.Aeson.Types.FromJSON.FromJSON Data.Appendful.Collection.ClientId
instance Data.Aeson.Types.ToJSON.ToJSONKey Data.Appendful.Collection.ClientId
instance Data.Aeson.Types.ToJSON.ToJSON Data.Appendful.Collection.ClientId
instance GHC.Generics.Generic Data.Appendful.Collection.ClientId
instance GHC.Enum.Bounded Data.Appendful.Collection.ClientId
instance GHC.Enum.Enum Data.Appendful.Collection.ClientId
instance GHC.Classes.Ord Data.Appendful.Collection.ClientId
instance GHC.Classes.Eq Data.Appendful.Collection.ClientId
instance GHC.Show.Show Data.Appendful.Collection.ClientId
instance GHC.Generics.Generic (Data.Appendful.Collection.ClientStore ci si a)
instance (GHC.Classes.Ord ci, GHC.Classes.Ord a, GHC.Classes.Ord si) => GHC.Classes.Ord (Data.Appendful.Collection.ClientStore ci si a)
instance (GHC.Classes.Eq ci, GHC.Classes.Eq a, GHC.Classes.Eq si) => GHC.Classes.Eq (Data.Appendful.Collection.ClientStore ci si a)
instance (GHC.Show.Show ci, GHC.Show.Show a, GHC.Show.Show si) => GHC.Show.Show (Data.Appendful.Collection.ClientStore ci si a)
instance GHC.Generics.Generic (Data.Appendful.Collection.SyncRequest ci si a)
instance (GHC.Classes.Ord ci, GHC.Classes.Ord a, GHC.Classes.Ord si) => GHC.Classes.Ord (Data.Appendful.Collection.SyncRequest ci si a)
instance (GHC.Classes.Eq ci, GHC.Classes.Eq a, GHC.Classes.Eq si) => GHC.Classes.Eq (Data.Appendful.Collection.SyncRequest ci si a)
instance (GHC.Show.Show ci, GHC.Show.Show a, GHC.Show.Show si) => GHC.Show.Show (Data.Appendful.Collection.SyncRequest ci si a)
instance GHC.Generics.Generic (Data.Appendful.Collection.SyncResponse ci si a)
instance (GHC.Classes.Ord ci, GHC.Classes.Ord si, GHC.Classes.Ord a) => GHC.Classes.Ord (Data.Appendful.Collection.SyncResponse ci si a)
instance (GHC.Classes.Eq ci, GHC.Classes.Eq si, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Appendful.Collection.SyncResponse ci si a)
instance (GHC.Show.Show ci, GHC.Show.Show si, GHC.Show.Show a) => GHC.Show.Show (Data.Appendful.Collection.SyncResponse ci si a)
instance GHC.Generics.Generic (Data.Appendful.Collection.ClientSyncProcessor ci si a m)
instance GHC.Generics.Generic (Data.Appendful.Collection.ServerSyncProcessor ci si a m)
instance (Data.Aeson.Types.ToJSON.ToJSON a, Data.Aeson.Types.ToJSON.ToJSONKey si) => Data.Aeson.Types.ToJSON.ToJSON (Data.Appendful.Collection.ServerStore si a)
instance (Data.Aeson.Types.FromJSON.FromJSONKey si, GHC.Classes.Ord si, Data.Aeson.Types.FromJSON.FromJSON a) => Data.Aeson.Types.FromJSON.FromJSON (Data.Appendful.Collection.ServerStore si a)
instance GHC.Generics.Generic (Data.Appendful.Collection.ServerStore si a)
instance (GHC.Classes.Ord si, GHC.Classes.Ord a) => GHC.Classes.Ord (Data.Appendful.Collection.ServerStore si a)
instance (GHC.Classes.Eq si, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Appendful.Collection.ServerStore si a)
instance (GHC.Show.Show si, GHC.Show.Show a) => GHC.Show.Show (Data.Appendful.Collection.ServerStore si a)
instance (Control.DeepSeq.NFData si, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Data.Appendful.Collection.ServerStore si a)
instance (Data.Validity.Validity si, Data.Validity.Validity a, GHC.Show.Show si, GHC.Show.Show a, GHC.Classes.Ord si) => Data.Validity.Validity (Data.Appendful.Collection.ServerStore si a)
instance (Control.DeepSeq.NFData ci, Control.DeepSeq.NFData si, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Data.Appendful.Collection.SyncResponse ci si a)
instance (Data.Validity.Validity ci, Data.Validity.Validity si, Data.Validity.Validity a, GHC.Show.Show ci, GHC.Show.Show si, GHC.Classes.Ord ci, GHC.Classes.Ord si) => Data.Validity.Validity (Data.Appendful.Collection.SyncResponse ci si a)
instance (GHC.Classes.Ord ci, GHC.Classes.Ord si, Data.Aeson.Types.FromJSON.FromJSON ci, Data.Aeson.Types.FromJSON.FromJSON si, Data.Aeson.Types.FromJSON.FromJSONKey ci, Data.Aeson.Types.FromJSON.FromJSONKey si, GHC.Classes.Ord a, Data.Aeson.Types.FromJSON.FromJSON a) => Data.Aeson.Types.FromJSON.FromJSON (Data.Appendful.Collection.SyncResponse ci si a)
instance (Data.Aeson.Types.ToJSON.ToJSON ci, Data.Aeson.Types.ToJSON.ToJSON si, Data.Aeson.Types.ToJSON.ToJSONKey ci, Data.Aeson.Types.ToJSON.ToJSONKey si, Data.Aeson.Types.ToJSON.ToJSON a) => Data.Aeson.Types.ToJSON.ToJSON (Data.Appendful.Collection.SyncResponse ci si a)
instance (Control.DeepSeq.NFData ci, Control.DeepSeq.NFData si, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Data.Appendful.Collection.SyncRequest ci si a)
instance (Data.Validity.Validity ci, Data.Validity.Validity si, Data.Validity.Validity a, GHC.Classes.Ord ci, GHC.Classes.Ord si, GHC.Show.Show ci) => Data.Validity.Validity (Data.Appendful.Collection.SyncRequest ci si a)
instance (Data.Aeson.Types.FromJSON.FromJSON ci, Data.Aeson.Types.FromJSON.FromJSON si, Data.Aeson.Types.FromJSON.FromJSON a, Data.Aeson.Types.FromJSON.FromJSONKey ci, GHC.Classes.Ord ci, GHC.Classes.Ord si, GHC.Classes.Ord a) => Data.Aeson.Types.FromJSON.FromJSON (Data.Appendful.Collection.SyncRequest ci si a)
instance (Data.Aeson.Types.ToJSON.ToJSON ci, Data.Aeson.Types.ToJSON.ToJSON si, Data.Aeson.Types.ToJSON.ToJSON a, Data.Aeson.Types.ToJSON.ToJSONKey ci) => Data.Aeson.Types.ToJSON.ToJSON (Data.Appendful.Collection.SyncRequest ci si a)
instance (Control.DeepSeq.NFData ci, Control.DeepSeq.NFData si, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Data.Appendful.Collection.ClientStore ci si a)
instance (Data.Validity.Validity ci, Data.Validity.Validity si, Data.Validity.Validity a, GHC.Show.Show ci, GHC.Show.Show si, GHC.Classes.Ord ci, GHC.Classes.Ord si) => Data.Validity.Validity (Data.Appendful.Collection.ClientStore ci si a)
instance (GHC.Classes.Ord ci, Data.Aeson.Types.FromJSON.FromJSON ci, Data.Aeson.Types.FromJSON.FromJSONKey ci, GHC.Classes.Ord si, Data.Aeson.Types.FromJSON.FromJSON si, Data.Aeson.Types.FromJSON.FromJSONKey si, Data.Aeson.Types.FromJSON.FromJSON a) => Data.Aeson.Types.FromJSON.FromJSON (Data.Appendful.Collection.ClientStore ci si a)
instance (GHC.Classes.Ord ci, Data.Aeson.Types.ToJSON.ToJSON ci, Data.Aeson.Types.ToJSON.ToJSONKey ci, GHC.Classes.Ord si, Data.Aeson.Types.ToJSON.ToJSON si, Data.Aeson.Types.ToJSON.ToJSONKey si, Data.Aeson.Types.ToJSON.ToJSON a) => Data.Aeson.Types.ToJSON.ToJSON (Data.Appendful.Collection.ClientStore ci si a)
instance Data.Validity.Validity Data.Appendful.Collection.ClientId
instance Control.DeepSeq.NFData Data.Appendful.Collection.ClientId
module Data.Appendful