-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Real-time collaborative editing with Operational Transformation -- -- Real-time collaborative editing with Operational Transformation @package ot @version 0.2.0.0 module Control.OperationalTransformation.List data N Z :: N S :: N -> N data Vector :: * -> N -> * EmptyV :: Vector a Z ConsV :: a -> Vector a n -> Vector a (S n) data Operation :: * -> N -> N -> * EmptyOp :: Operation a Z Z RetainOp :: Operation a n m -> Operation a (S n) (S m) InsertOp :: a -> Operation a n m -> Operation a n (S m) DeleteOp :: Operation a n m -> Operation a (S n) m apply :: Operation a n m -> Vector a n -> Vector a m compose :: Operation a n m -> Operation a m k -> Operation a n k data TransformedPair :: * -> N -> N -> * TP :: Operation a n k -> Operation a m k -> TransformedPair a n m transform :: Operation a n m -> Operation a n k -> TransformedPair a k m instance Eq N instance Show N module Control.OperationalTransformation class OTOperation op transform :: OTOperation op => op -> op -> Either String (op, op) class OTOperation op => OTComposableOperation op compose :: OTComposableOperation op => op -> op -> Either String op -- | Cursor position class OTCursor cursor op updateCursor :: OTCursor cursor op => op -> cursor -> cursor class OTOperation op => OTSystem doc op apply :: OTSystem doc op => op -> doc -> Either String doc instance (OTSystem doca a, OTSystem docb b, OTSystem docc c, OTSystem docd d, OTSystem doce e) => OTSystem (doca, docb, docc, docd, doce) (a, b, c, d, e) instance (OTComposableOperation a, OTComposableOperation b, OTComposableOperation c, OTComposableOperation d, OTComposableOperation e) => OTComposableOperation (a, b, c, d, e) instance (OTOperation a, OTOperation b, OTOperation c, OTOperation d, OTOperation e) => OTOperation (a, b, c, d, e) instance (OTSystem doca a, OTSystem docb b, OTSystem docc c, OTSystem docd d) => OTSystem (doca, docb, docc, docd) (a, b, c, d) instance (OTComposableOperation a, OTComposableOperation b, OTComposableOperation c, OTComposableOperation d) => OTComposableOperation (a, b, c, d) instance (OTOperation a, OTOperation b, OTOperation c, OTOperation d) => OTOperation (a, b, c, d) instance (OTSystem doca a, OTSystem docb b, OTSystem docc c) => OTSystem (doca, docb, docc) (a, b, c) instance (OTComposableOperation a, OTComposableOperation b, OTComposableOperation c) => OTComposableOperation (a, b, c) instance (OTOperation a, OTOperation b, OTOperation c) => OTOperation (a, b, c) instance (OTSystem doca a, OTSystem docb b) => OTSystem (doca, docb) (a, b) instance (OTComposableOperation a, OTComposableOperation b) => OTComposableOperation (a, b) instance (OTOperation a, OTOperation b) => OTOperation (a, b) instance (OTCursor a op, OTCursor b op, OTCursor c op, OTCursor d op, OTCursor e op) => OTCursor (a, b, c, d, e) op instance (OTCursor a op, OTCursor b op, OTCursor c op, OTCursor d op) => OTCursor (a, b, c, d) op instance (OTCursor a op, OTCursor b op, OTCursor c op) => OTCursor (a, b, c) op instance (OTCursor a op, OTCursor b op) => OTCursor (a, b) op instance OTCursor cursor op => OTCursor [cursor] op instance OTCursor () op instance OTSystem doc op => OTSystem doc [op] instance OTOperation op => OTComposableOperation [op] instance OTOperation op => OTOperation [op] module Control.OperationalTransformation.Text -- | An action changes the text at the current position or advances the -- cursor. data Action -- | Skip the next n characters. Retain :: !Int -> Action -- | Insert the given text at the current position. Insert :: !Text -> Action -- | Delete the next n characters. Delete :: !Int -> Action -- | An edit on plain text documents. An operation consists of multiple -- actions that change the document at the current cursor position or -- advance the cursor. After applying all actions, the cursor must be at -- the end of the document. newtype TextOperation TextOperation :: [Action] -> TextOperation -- | Computes the inverse of an operation. Useful for implementing undo. invertOperation :: TextOperation -> Text -> Either String TextOperation instance Typeable Action instance Typeable TextOperation instance Eq Action instance Read Action instance Show Action instance Read TextOperation instance Show TextOperation instance Binary TextOperation instance FromJSON TextOperation instance ToJSON TextOperation instance OTSystem Text TextOperation instance OTComposableOperation TextOperation instance OTOperation TextOperation instance Eq TextOperation instance IsList TextOperation instance FromJSON Action instance ToJSON Action instance Binary Action module Control.OperationalTransformation.Selection -- | Range has anchor and head properties, which are -- zero-based indices into the document. The anchor is the side -- of the selection that stays fixed, head is the side of the -- selection where the cursor is. When both are equal, the range -- represents a cursor. data Range Range :: !Int -> !Int -> Range rangeAnchor :: Range -> !Int rangeHead :: Range -> !Int -- | A selection consists of a list of ranges. Each range may represent a -- selected part of the document or a cursor in the document. newtype Selection Selection :: [Range] -> Selection ranges :: Selection -> [Range] -- | Create a selection that represents a cursor. createCursor :: Int -> Selection -- | Number of selected characters size :: Selection -> Int -- | Does the selection contain any characters? somethingSelected :: Selection -> Bool instance Show Range instance Read Range instance Eq Range instance Ord Range instance Monoid Selection instance Show Selection instance Read Selection instance IsList Selection instance FromJSON Selection instance ToJSON Selection instance Ord Selection instance Eq Selection instance OTCursor Selection TextOperation instance OTCursor Range TextOperation instance FromJSON Range instance ToJSON Range module Control.OperationalTransformation.Properties -- | (b ∘ a)(d) = a(b(d)) where a and b are two -- consecutive operations and d is the initial document. prop_compose_apply :: (OTSystem doc op, OTComposableOperation op, Arbitrary doc, Show doc, Eq doc) => (doc -> Gen op) -> Property -- | b'(a(d)) = a'(b(d)) where a and b are random -- operations, d is the initial document and (a', b') = -- transform(a, b). prop_transform_apply :: (OTSystem doc op, Arbitrary doc, Show doc, Eq doc) => (doc -> Gen op) -> Property -- | b' ∘ a = a' ∘ b where a and b are random -- operations and (a', b') = transform(a, b). Note that this is -- a stronger property than prop_transform_apply, because -- prop_transform_compose and prop_compose_apply imply -- prop_transform_apply. prop_transform_compose :: (OTSystem doc op, OTComposableOperation op, Arbitrary doc, Show op, Eq op) => (doc -> Gen op) -> Property -- | Transformation is compatible with composition on the left. That is, if -- we have two consecutive operations a and b and a -- concurrent operation c, then it doesn't make a difference -- whether we transform c against a and then against -- b or transform c against the composition of a and -- b. In other terms, c'_1 = c'_2 where (_, c'_1) = -- transform(b ∘ a, c), (_, c') = transform(a, c) and -- (_, c'_2) = transform(b, c'). prop_transform_compose_compat_l :: (OTSystem doc op, OTComposableOperation op, Arbitrary doc, Show op, Eq op) => (doc -> Gen op) -> Property -- | Transformation is compatible with composition on the right. prop_transform_compose_compat_r :: (OTSystem doc op, OTComposableOperation op, Arbitrary doc, Show op, Eq op) => (doc -> Gen op) -> Property module Control.OperationalTransformation.Client -- | At every moment, the client is in one of three states. data ClientState op -- | All of the client's operations have been acknowledged by the server. ClientSynchronized :: ClientState op -- | The client has sent an operation to the server and it is still waiting -- for an acknowledgement. ClientWaiting :: op -> ClientState op -- | The client is waiting for an acknowledgement for a pending operation -- and the client is buffering local changes. ClientWaitingWithBuffer :: op -> op -> ClientState op -- | The state a newly connected client starts in (synonym for -- ClientSynchronized). initialClientState :: ClientState op -- | Handle user-generated operations. applyClient :: OTComposableOperation op => ClientState op -> op -> Either String (Bool, ClientState op) -- | Handle incoming operations from the server. applyServer :: OTComposableOperation op => ClientState op -> op -> Either String (op, ClientState op) -- | Handle acknowledgements. serverAck :: ClientState op -> Maybe (Maybe op, ClientState op) instance Eq op => Eq (ClientState op) instance Show op => Show (ClientState op) instance Read op => Read (ClientState op) module Control.OperationalTransformation.Server type Revision = Integer -- | The server keeps the current revision number and a list of previous -- operations to transform incoming operations against. data ServerState doc op ServerState :: Revision -> doc -> [op] -> ServerState doc op initialServerState :: doc -> ServerState doc op -- | Handles incoming operations. applyOperation :: (OTSystem doc op, OTCursor cursor op) => ServerState doc op -> Revision -> op -> cursor -> Either String (op, cursor, ServerState doc op)