mergeless-0.2.0.1

Safe HaskellNone
LanguageHaskell2010

Data.Mergeless.Collection

Contents

Description

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.
  • Identifiers for items must be generatable in such a way that they are certainly unique.

Should mutation be a requirement, then it can be build such that it entails deleting the old version and creating a new version that is the modification of the old version.

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:

Synopsis

Documentation

newtype ClientId Source #

A Client-side identifier for items.

These only need to be unique at the client.

Constructors

ClientId 

Fields

Instances
Bounded ClientId Source # 
Instance details

Defined in Data.Mergeless.Collection

Enum ClientId Source # 
Instance details

Defined in Data.Mergeless.Collection

Eq ClientId Source # 
Instance details

Defined in Data.Mergeless.Collection

Ord ClientId Source # 
Instance details

Defined in Data.Mergeless.Collection

Show ClientId Source # 
Instance details

Defined in Data.Mergeless.Collection

Generic ClientId Source # 
Instance details

Defined in Data.Mergeless.Collection

Associated Types

type Rep ClientId :: Type -> Type #

Methods

from :: ClientId -> Rep ClientId x #

to :: Rep ClientId x -> ClientId #

ToJSON ClientId Source # 
Instance details

Defined in Data.Mergeless.Collection

ToJSONKey ClientId Source # 
Instance details

Defined in Data.Mergeless.Collection

FromJSON ClientId Source # 
Instance details

Defined in Data.Mergeless.Collection

FromJSONKey ClientId Source # 
Instance details

Defined in Data.Mergeless.Collection

NFData ClientId Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

rnf :: ClientId -> () #

Validity ClientId Source # 
Instance details

Defined in Data.Mergeless.Collection

type Rep ClientId Source # 
Instance details

Defined in Data.Mergeless.Collection

type Rep ClientId = D1 (MetaData "ClientId" "Data.Mergeless.Collection" "mergeless-0.2.0.1-EJEJ0UxqAftGrZfjWZKWS3" True) (C1 (MetaCons "ClientId" PrefixI True) (S1 (MetaSel (Just "unClientId") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Word64)))

data ClientStore i a Source #

A client-side store of items with Id's of type i and values of type a

Constructors

ClientStore 
Instances
(Eq a, Eq i) => Eq (ClientStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

(==) :: ClientStore i a -> ClientStore i a -> Bool #

(/=) :: ClientStore i a -> ClientStore i a -> Bool #

(Ord a, Ord i) => Ord (ClientStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

compare :: ClientStore i a -> ClientStore i a -> Ordering #

(<) :: ClientStore i a -> ClientStore i a -> Bool #

(<=) :: ClientStore i a -> ClientStore i a -> Bool #

(>) :: ClientStore i a -> ClientStore i a -> Bool #

(>=) :: ClientStore i a -> ClientStore i a -> Bool #

max :: ClientStore i a -> ClientStore i a -> ClientStore i a #

min :: ClientStore i a -> ClientStore i a -> ClientStore i a #

(Show a, Show i) => Show (ClientStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

showsPrec :: Int -> ClientStore i a -> ShowS #

show :: ClientStore i a -> String #

showList :: [ClientStore i a] -> ShowS #

Generic (ClientStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Associated Types

type Rep (ClientStore i a) :: Type -> Type #

Methods

from :: ClientStore i a -> Rep (ClientStore i a) x #

to :: Rep (ClientStore i a) x -> ClientStore i a #

(Ord i, ToJSON i, ToJSONKey i, ToJSON a) => ToJSON (ClientStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

(Ord i, FromJSON i, FromJSONKey i, FromJSON a) => FromJSON (ClientStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

(NFData i, NFData a) => NFData (ClientStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

rnf :: ClientStore i a -> () #

(Validity i, Validity a, Show i, Show a, Ord i, Ord a) => Validity (ClientStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

validate :: ClientStore i a -> Validation #

type Rep (ClientStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

type Rep (ClientStore i a) = D1 (MetaData "ClientStore" "Data.Mergeless.Collection" "mergeless-0.2.0.1-EJEJ0UxqAftGrZfjWZKWS3" False) (C1 (MetaCons "ClientStore" PrefixI True) (S1 (MetaSel (Just "clientStoreAdded") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (Map ClientId a)) :*: (S1 (MetaSel (Just "clientStoreSynced") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (Map i a)) :*: S1 (MetaSel (Just "clientStoreDeleted") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (Set i)))))

emptyClientStore :: ClientStore i a Source #

The store with no items.

storeSize :: ClientStore i a -> Int Source #

The number of items in a store

This does not count the deleted items, so that those really look deleted.

addItemToClientStore :: (Ord i, Ord a) => a -> ClientStore i a -> ClientStore i a Source #

Add an item to a client store as an added item.

This will take care of the uniqueness constraint of the ClientIds in the map.

data SyncRequest i a Source #

A synchronisation request for items with identifiers of type i and values of type a

Constructors

SyncRequest 
Instances
(Eq a, Eq i) => Eq (SyncRequest i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

(==) :: SyncRequest i a -> SyncRequest i a -> Bool #

(/=) :: SyncRequest i a -> SyncRequest i a -> Bool #

(Ord a, Ord i) => Ord (SyncRequest i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

compare :: SyncRequest i a -> SyncRequest i a -> Ordering #

(<) :: SyncRequest i a -> SyncRequest i a -> Bool #

(<=) :: SyncRequest i a -> SyncRequest i a -> Bool #

(>) :: SyncRequest i a -> SyncRequest i a -> Bool #

(>=) :: SyncRequest i a -> SyncRequest i a -> Bool #

max :: SyncRequest i a -> SyncRequest i a -> SyncRequest i a #

min :: SyncRequest i a -> SyncRequest i a -> SyncRequest i a #

(Show a, Show i) => Show (SyncRequest i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

showsPrec :: Int -> SyncRequest i a -> ShowS #

show :: SyncRequest i a -> String #

showList :: [SyncRequest i a] -> ShowS #

Generic (SyncRequest i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Associated Types

type Rep (SyncRequest i a) :: Type -> Type #

Methods

from :: SyncRequest i a -> Rep (SyncRequest i a) x #

to :: Rep (SyncRequest i a) x -> SyncRequest i a #

(ToJSON i, ToJSON a) => ToJSON (SyncRequest i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

(FromJSON i, FromJSON a, Ord i, Ord a) => FromJSON (SyncRequest i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

(NFData i, NFData a) => NFData (SyncRequest i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

rnf :: SyncRequest i a -> () #

(Validity i, Validity a, Ord i, Ord a) => Validity (SyncRequest i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

validate :: SyncRequest i a -> Validation #

type Rep (SyncRequest i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

type Rep (SyncRequest i a) = D1 (MetaData "SyncRequest" "Data.Mergeless.Collection" "mergeless-0.2.0.1-EJEJ0UxqAftGrZfjWZKWS3" False) (C1 (MetaCons "SyncRequest" PrefixI True) (S1 (MetaSel (Just "syncRequestAdded") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (Map ClientId a)) :*: (S1 (MetaSel (Just "syncRequestSynced") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (Set i)) :*: S1 (MetaSel (Just "syncRequestDeleted") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (Set i)))))

data SyncResponse i a Source #

A synchronisation response for items with identifiers of type i and values of type a

Instances
(Eq i, Eq a) => Eq (SyncResponse i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

(==) :: SyncResponse i a -> SyncResponse i a -> Bool #

(/=) :: SyncResponse i a -> SyncResponse i a -> Bool #

(Ord i, Ord a) => Ord (SyncResponse i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

(Show i, Show a) => Show (SyncResponse i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Generic (SyncResponse i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Associated Types

type Rep (SyncResponse i a) :: Type -> Type #

Methods

from :: SyncResponse i a -> Rep (SyncResponse i a) x #

to :: Rep (SyncResponse i a) x -> SyncResponse i a #

(ToJSON i, ToJSONKey i, ToJSON a) => ToJSON (SyncResponse i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

(Ord i, FromJSON i, FromJSONKey i, Ord a, FromJSON a) => FromJSON (SyncResponse i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

(NFData i, NFData a) => NFData (SyncResponse i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

rnf :: SyncResponse i a -> () #

(Validity i, Validity a, Show i, Show a, Ord i, Ord a) => Validity (SyncResponse i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

type Rep (SyncResponse i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

type Rep (SyncResponse i a) = D1 (MetaData "SyncResponse" "Data.Mergeless.Collection" "mergeless-0.2.0.1-EJEJ0UxqAftGrZfjWZKWS3" False) (C1 (MetaCons "SyncResponse" PrefixI True) ((S1 (MetaSel (Just "syncResponseClientAdded") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (Map ClientId i)) :*: S1 (MetaSel (Just "syncResponseClientDeleted") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (Set i))) :*: (S1 (MetaSel (Just "syncResponseServerAdded") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (Map i a)) :*: S1 (MetaSel (Just "syncResponseServerDeleted") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 (Set i)))))

Client-side Synchronisation

makeSyncRequest :: (Ord i, Ord a) => ClientStore i a -> SyncRequest i a Source #

Produce a synchronisation request for a client-side store.

This request can then be sent to a central store for synchronisation.

mergeSyncResponse :: forall i a. (Ord i, Ord a) => ClientStore i a -> SyncResponse i a -> ClientStore i a Source #

Merge a synchronisation response back into a client-side store.

addAddedItems :: forall i a. (Ord i, Ord a) => Map ClientId i -> ClientStore i a -> ClientStore i a Source #

Server-side Synchronisation

General synchronisation

data ServerSyncProcessor i a m Source #

A record of the basic operations that are necessary to build a synchronisation processor.

Constructors

ServerSyncProcessor 

Fields

Instances
Generic (ServerSyncProcessor i a m) Source # 
Instance details

Defined in Data.Mergeless.Collection

Associated Types

type Rep (ServerSyncProcessor i a m) :: Type -> Type #

type Rep (ServerSyncProcessor i a m) Source # 
Instance details

Defined in Data.Mergeless.Collection

type Rep (ServerSyncProcessor i a m) = D1 (MetaData "ServerSyncProcessor" "Data.Mergeless.Collection" "mergeless-0.2.0.1-EJEJ0UxqAftGrZfjWZKWS3" False) (C1 (MetaCons "ServerSyncProcessor" PrefixI True) ((S1 (MetaSel (Just "serverSyncProcessorDeleteMany") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Set i -> m (Set i))) :*: S1 (MetaSel (Just "serverSyncProcessorQueryNoLongerSynced") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Set i -> m (Set i)))) :*: (S1 (MetaSel (Just "serverSyncProcessorQueryNewRemote") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Set i -> m (Map i a))) :*: S1 (MetaSel (Just "serverSyncProcessorInsertMany") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Map ClientId a -> m (Map ClientId i))))))

processServerSyncCustom :: forall i a m. (Ord i, Ord a, Monad m) => ServerSyncProcessor i a m -> SyncRequest i a -> m (SyncResponse i a) Source #

Process a server-side synchronisation request using a custom synchronisation processor

WARNING: The identifier generation function must produce newly unique identifiers such that each new item gets a unique identifier.

You can use this function with deterministically-random identifiers or incrementing identifiers.

Synchronisation with a simple central store

newtype ServerStore i a Source #

A central store of items with identifiers of type i and values of type a

Constructors

ServerStore 

Fields

Instances
(Eq i, Eq a) => Eq (ServerStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

(==) :: ServerStore i a -> ServerStore i a -> Bool #

(/=) :: ServerStore i a -> ServerStore i a -> Bool #

(Ord i, Ord a) => Ord (ServerStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

compare :: ServerStore i a -> ServerStore i a -> Ordering #

(<) :: ServerStore i a -> ServerStore i a -> Bool #

(<=) :: ServerStore i a -> ServerStore i a -> Bool #

(>) :: ServerStore i a -> ServerStore i a -> Bool #

(>=) :: ServerStore i a -> ServerStore i a -> Bool #

max :: ServerStore i a -> ServerStore i a -> ServerStore i a #

min :: ServerStore i a -> ServerStore i a -> ServerStore i a #

(Show i, Show a) => Show (ServerStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

showsPrec :: Int -> ServerStore i a -> ShowS #

show :: ServerStore i a -> String #

showList :: [ServerStore i a] -> ShowS #

Generic (ServerStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Associated Types

type Rep (ServerStore i a) :: Type -> Type #

Methods

from :: ServerStore i a -> Rep (ServerStore i a) x #

to :: Rep (ServerStore i a) x -> ServerStore i a #

(ToJSON a, ToJSONKey i) => ToJSON (ServerStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

(FromJSONKey i, Ord i, FromJSON a) => FromJSON (ServerStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

(NFData i, NFData a) => NFData (ServerStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

rnf :: ServerStore i a -> () #

(Validity i, Validity a, Show i, Show a, Ord i, Ord a) => Validity (ServerStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

Methods

validate :: ServerStore i a -> Validation #

type Rep (ServerStore i a) Source # 
Instance details

Defined in Data.Mergeless.Collection

type Rep (ServerStore i a) = D1 (MetaData "ServerStore" "Data.Mergeless.Collection" "mergeless-0.2.0.1-EJEJ0UxqAftGrZfjWZKWS3" True) (C1 (MetaCons "ServerStore" PrefixI True) (S1 (MetaSel (Just "serverStoreItems") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Map i a))))

emptyServerStore :: ServerStore i a Source #

An empty central store to start with

processServerSync :: forall m i a. (Ord i, Ord a, Monad m) => m i -> ServerStore i a -> SyncRequest i a -> m (SyncResponse i a, ServerStore i a) Source #

Process a server-side synchronisation request using getCurrentTime

see processSyncCustom