ron-rdt 0.8 → 0.9
raw patch · 8 files changed
+234/−104 lines, 8 files
Files
- CHANGELOG.md +15/−1
- lib/RON/Data.hs +9/−18
- lib/RON/Data/Internal.hs +43/−24
- lib/RON/Data/LWW.hs +2/−2
- lib/RON/Data/ORSet.hs +148/−41
- lib/RON/Data/RGA.hs +11/−10
- lib/RON/Data/VersionVector.hs +5/−7
- ron-rdt.cabal +1/−1
CHANGELOG.md view
@@ -7,6 +7,19 @@ ## [Unreleased] +## [0.9] - 2019-09-06+### Added+- Function `ORSet.getFieldObject`+- Export `ORSetRep` constructor+- Extend error reporting+- `ORSet.removeObjectIf`+- `ORSet.addFieldValue`+- `ORSet.removeFieldValue`+- `ORSet.removeFieldValueIf`++### Changed+- Renamed `getObject` to `readObject`+ ## [0.8] - 2019-08-10 ### Added - Function `reduceState`@@ -182,7 +195,8 @@ - RON-Schema - RON-Schema TemplateHaskell code generator -[Unreleased]: https://github.com/ff-notes/ron/compare/ron-rdt-0.8...HEAD+[Unreleased]: https://github.com/ff-notes/ron/compare/ron-rdt-0.9...HEAD+[0.9]: https://github.com/ff-notes/ron/compare/ron-rdt-0.8...ron-rdt-0.9 [0.8]: https://github.com/ff-notes/ron/compare/ron-rdt-0.7...ron-rdt-0.8 [0.7]: https://github.com/ff-notes/ron/compare/ron-rdt-0.6...ron-rdt-0.7 [0.6]: https://github.com/ff-notes/ff/compare/v0.5...ron-rdt-0.6
lib/RON/Data.hs view
@@ -50,11 +50,11 @@ import RON.Data.RGA (RgaRep) import RON.Data.VersionVector (VersionVector) import RON.Error (MonadE, throwErrorString)-import RON.Types (ClosedOp (..), Object (Object),- ObjectFrame (ObjectFrame, frame, uuid), Op (..),- StateChunk (..), StateFrame, UUID,- WireChunk (Closed, Query, Value), WireFrame,- WireReducedChunk (..),+import RON.Types (ClosedOp (..),+ ObjectFrame (ObjectFrame, frame, uuid),+ ObjectRef (ObjectRef), Op (..), StateChunk (..),+ StateFrame, UUID, WireChunk (Closed, Query, Value),+ WireFrame, WireReducedChunk (..), WireStateChunk (WireStateChunk, stateBody, stateType)) import RON.UUID (pattern Zero) @@ -190,19 +190,10 @@ | otherwise = mof1 -- | Run ObjectFrame action-evalObjectState :: Monad m => ObjectFrame b -> ObjectStateT b m a -> m a-evalObjectState ObjectFrame{uuid, frame} action =- evalStateT (runReaderT action $ Object uuid) frame---- | Run ObjectFrame action, starting with an empty frame-evalObjectState_ :: Monad m => StateT StateFrame m a -> m a-evalObjectState_ action = evalStateT action mempty---- | Run ObjectFrame action execObjectState :: Monad m => ObjectFrame b -> ObjectStateT b m a -> m (ObjectFrame b) execObjectState state@ObjectFrame{uuid, frame} action = do- frame' <- execStateT (runReaderT action $ Object uuid) frame+ frame' <- execStateT (runReaderT action $ ObjectRef uuid) frame pure state{frame = frame'} -- | Run ObjectFrame action, starting with an empty frame@@ -216,7 +207,7 @@ -> ObjectStateT b m a -> m (a, ObjectFrame b) runObjectState state@ObjectFrame{uuid, frame} action =- runStateT (runReaderT action $ Object uuid) frame+ runStateT (runReaderT action $ ObjectRef uuid) frame <&> \(a, frame') -> (a, state{frame = frame'}) -- | Run ObjectFrame action, starting with an empty frame@@ -225,6 +216,6 @@ -- | Create new 'ObjectFrame' with an action newObjectFrameWith- :: Functor m => StateT StateFrame m (Object a) -> m (ObjectFrame a)+ :: Functor m => StateT StateFrame m (ObjectRef a) -> m (ObjectFrame a) newObjectFrameWith action =- runObjectState_ action <&> \(Object uuid, frame) -> ObjectFrame{uuid, frame}+ runObjectState_ action <&> \(ObjectRef uuid, frame) -> ObjectFrame{uuid, frame}
lib/RON/Data/Internal.hs view
@@ -24,6 +24,8 @@ advanceToObject, eqPayload, eqRef,+ evalObjectState,+ evalObjectState_, getObjectState, getObjectStateChunk, modifyObjectStateChunk,@@ -59,8 +61,9 @@ liftMaybe) import RON.Event (ReplicaClock, advanceToUuid) import RON.Semilattice (BoundedSemilattice)-import RON.Types (Atom (AInteger, AString, AUuid), Object (Object),+import RON.Types (Atom (AInteger, AString, AUuid), ObjectFrame (ObjectFrame, frame, uuid),+ ObjectRef (ObjectRef), Op (Op, opId, payload, refId), Payload, StateChunk (StateChunk), StateFrame, UUID (UUID), WireChunk,@@ -178,9 +181,9 @@ objectEncoding :: ReplicatedAsObject a => Encoding a objectEncoding = Encoding { encodingNewRon = \a -> do- Object uuid <- newObject a+ ObjectRef uuid <- newObject a pure [AUuid uuid]- , encodingFromRon = objectFromRon $ runReaderT getObject+ , encodingFromRon = objectFromRon $ runReaderT readObject } -- | Standard implementation of 'Replicated' for 'ReplicatedAsPayload' types.@@ -243,30 +246,30 @@ type Rep a -- | Encode data. Write frame and return id.- newObject :: (ReplicaClock m, MonadState StateFrame m) => a -> m (Object a)+ newObject+ :: (ReplicaClock m, MonadState StateFrame m) => a -> m (ObjectRef a) -- | Decode data- getObject :: (MonadE m, MonadObjectState a m) => m a-- -- | Counterpart of 'mempty', but without an explicit 'Semigroup'- -- rempty :: a+ readObject :: (MonadE m, MonadObjectState a m) => m a -objectFromRon :: MonadE m => (Object a -> m a) -> Payload -> m a-objectFromRon handler atoms = case atoms of- [AUuid uuid] -> handler $ Object uuid- _ -> throwError "Expected object UUID"+objectFromRon :: MonadE m => (ObjectRef a -> m a) -> Payload -> m a+objectFromRon handler atoms =+ errorContext "objectFromRon" $+ case atoms of+ [AUuid uuid] -> handler $ ObjectRef uuid+ _ -> throwError "Expected object UUID" -- | Create new 'ObjectFrame' from a value newObjectFrame :: (ReplicatedAsObject a, ReplicaClock m) => a -> m (ObjectFrame a) newObjectFrame a = do- (Object uuid, frame) <- runStateT (newObject a) mempty+ (ObjectRef uuid, frame) <- runStateT (newObject a) mempty pure $ ObjectFrame{uuid, frame} getObjectStateChunk :: forall a m . (MonadE m, MonadObjectState a m) => m (StateChunk (Rep a)) getObjectStateChunk = do- Object uuid <- ask+ ObjectRef uuid <- ask frame <- get WireStateChunk{stateType, stateBody} <- liftMaybe "no such object in chunk" $ Map.lookup uuid frame@@ -284,7 +287,7 @@ => (StateChunk (Rep a) -> m (b, StateChunk (Rep a))) -> m b modifyObjectStateChunk f = do advanceToObject- Object uuid <- ask+ ObjectRef uuid <- ask chunk <- getObjectStateChunk (a, StateChunk chunk') <- f chunk modify' $@@ -299,8 +302,8 @@ chunk' <- f chunk pure ((), chunk') -eqRef :: Object a -> Payload -> Bool-eqRef (Object uuid) atoms = case atoms of+eqRef :: ObjectRef a -> Payload -> Bool+eqRef (ObjectRef uuid) atoms = case atoms of [AUuid ref] -> uuid == ref _ -> False @@ -325,14 +328,14 @@ [AFalse] -> pure False _ -> throwError "Expected single UUID `true` or `false`" -type ObjectStateT b m a = ReaderT (Object b) (StateT StateFrame m) a+type ObjectStateT b m a = ReaderT (ObjectRef b) (StateT StateFrame m) a type MonadObjectState a m =- (MonadReader (Object a) m, MonadState StateFrame m, Reducible (Rep a))+ (MonadReader (ObjectRef a) m, MonadState StateFrame m, Reducible (Rep a)) advanceToObject :: (MonadE m, MonadObjectState a m, ReplicaClock m) => m () advanceToObject = do- Object uuid <- ask+ ObjectRef uuid <- ask StateChunk chunk <- getObjectStateChunk advanceToUuid $ maximumDef@@ -355,13 +358,13 @@ reduceObjectStates :: forall a m . (MonadE m, MonadState StateFrame m, ReplicatedAsObject a)- => NonEmpty (Object a) -> m (Object a)+ => NonEmpty (ObjectRef a) -> m (ObjectRef a) reduceObjectStates (obj :| objs) = do c :| cs <- for (obj :| objs) $ runReaderT getObjectStateChunk let chunk = foldl' (reduceState @(Rep a)) c cs- oid = minimum [i | Object i <- obj:objs]+ oid = minimum [i | ObjectRef i <- obj:objs] modify' $ Map.insert oid $ wireStateChunk chunk- pure $ Object oid+ pure $ ObjectRef oid rconcat :: forall a m@@ -369,7 +372,7 @@ => NonEmpty UUID -> m a rconcat uuids = errorContext "rconcat" $ do- Object ref <- reduceObjectStates @a $ Object <$> uuids+ ObjectRef ref <- reduceObjectStates @a $ ObjectRef <$> uuids fromRon [AUuid ref] tryFromRon@@ -404,3 +407,19 @@ wireStateChunk :: forall rep . Reducible rep => StateChunk rep -> WireStateChunk wireStateChunk (StateChunk stateBody) = WireStateChunk{stateType = reducibleOpType @rep, stateBody}++-- | Run ObjectFrame action+evalObjectState :: Monad m => ObjectFrame b -> ObjectStateT b m a -> m a+evalObjectState ObjectFrame{uuid, frame} action =+ evalStateT (runReaderT action $ ObjectRef uuid) frame++-- | Run ObjectFrame action, starting with an empty frame+evalObjectState_ :: Monad m => StateT StateFrame m a -> m a+evalObjectState_ action = evalStateT action mempty++instance Replicated (ObjectRef a) where+ encoding = payloadEncoding++instance ReplicatedAsPayload (ObjectRef a) where+ toPayload (ObjectRef uuid) = toPayload uuid+ fromPayload = fmap ObjectRef . fromPayload
lib/RON/Data/LWW.hs view
@@ -34,7 +34,7 @@ import RON.Error (MonadE, errorContext) import RON.Event (ReplicaClock, getEventUuid) import RON.Semilattice (Semilattice)-import RON.Types (Atom (AUuid), Object (Object),+import RON.Types (Atom (AUuid), ObjectRef (ObjectRef), Op (Op, opId, payload, refId), StateChunk (StateChunk), StateFrame, UUID, WireStateChunk (WireStateChunk, stateBody, stateType))@@ -144,4 +144,4 @@ fieldObjectId <- errorContext "inner object" $ case payload of [AUuid oid] -> pure oid _ -> throwError "Expected object UUID"- lift $ runReaderT innerModifier $ Object fieldObjectId+ lift $ runReaderT innerModifier $ ObjectRef fieldObjectId
lib/RON/Data/ORSet.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE NamedFieldPuns #-}@@ -13,17 +14,22 @@ ORSet (..), ORSetItem (..), ORSetMap,- ORSetRep,+ ORSetRep (..), addRef, addValue, findAnyAlive, findAnyAlive',+ removeObjectIf, removeRef, removeValue, zoomItem, -- * struct_set+ addFieldValue, assignField,+ getFieldObject, newStruct,+ removeFieldValue,+ removeFieldValueIf, viewField, viewFieldLWW, viewFieldMax,@@ -38,18 +44,20 @@ import RON.Data.Internal (MonadObjectState, ObjectStateT, Reducible, Rep, Replicated (encoding),- ReplicatedAsObject, ReplicatedAsPayload,- eqPayload, eqRef, fromPayload, fromRon,- getObject, getObjectState,- getObjectStateChunk,+ ReplicatedAsObject,+ ReplicatedAsPayload (fromPayload),+ eqPayload, eqRef, evalObjectState, fromRon,+ getObjectState, getObjectStateChunk, modifyObjectStateChunk_, newObject, newRon,- objectEncoding, rconcat, reduceObjectStates,- reducibleOpType, stateFromChunk,- stateToChunk)+ objectEncoding, rconcat, readObject,+ reduceObjectStates, reducibleOpType,+ stateFromChunk, stateToChunk) import RON.Error (MonadE, errorContext, throwErrorText) import RON.Event (ReplicaClock, getEventUuid) import RON.Semilattice (Semilattice)-import RON.Types (Atom (AUuid), Object (Object),+import RON.Types (Atom (AUuid),+ ObjectFrame (ObjectFrame, frame, uuid),+ ObjectRef (ObjectRef), Op (Op, opId, payload, refId), Payload, StateChunk (StateChunk), StateFrame, UUID, WireStateChunk (WireStateChunk, stateBody, stateType))@@ -122,9 +130,9 @@ pure $ Op event Zero payload oid <- getEventUuid modify' $ Map.insert oid $ wireStateChunk ops- pure $ Object oid+ pure $ ObjectRef oid - getObject = do+ readObject = do StateChunk ops <- getObjectStateChunk mItems <- for ops $ \Op{refId, payload} -> case refId of Zero -> do@@ -133,8 +141,6 @@ _ -> pure Nothing pure . ORSet $ catMaybes mItems - -- rempty = ORSet []- -- | XXX Internal. Common implementation of 'addValue' and 'addRef'. commonAdd :: (MonadE m, MonadObjectState a m, ReplicaClock m) => Payload -> m () commonAdd payload =@@ -152,21 +158,24 @@ addRef :: (ReplicaClock m, MonadE m, MonadObjectState (ORSet a) m)- => Object a -> m ()-addRef (Object itemUuid) = commonAdd [AUuid itemUuid]+ => ObjectRef a -> m ()+addRef (ObjectRef itemUuid) = commonAdd [AUuid itemUuid] -- | XXX Internal. Common implementation of 'removeValue' and 'removeRef'. commonRemove :: (MonadE m, ReplicaClock m, MonadObjectState (ORSet a) m)- => (Payload -> Bool) -> m ()+ => (Payload -> m Bool) -> m () commonRemove isTarget = modifyObjectStateChunk_ $ \(StateChunk chunk) -> do let state0@(ORSetRep opMap) = stateFromChunk chunk- let targetEvents =- [ op- | op@Op{refId = Zero, payload} <- toList opMap- , isTarget payload- ]+ targetEvents <-+ fmap catMaybes+ $ for (toList opMap) $ \op@Op{refId, payload} ->+ case refId of+ Zero -> do+ t <- isTarget payload+ pure $ if t then Just op else Nothing+ _ -> pure Nothing StateChunk <$> case targetEvents of [] -> pure chunk@@ -179,19 +188,77 @@ let state' = state0 <> stateFromChunk patch pure $ stateToChunk state' +removeObjectIf+ :: (MonadE m, ReplicaClock m, MonadObjectState (ORSet a) m)+ => ObjectStateT a m Bool -> m ()+removeObjectIf isTarget = commonRemove $ \case+ AUuid uuid' : _ -> do+ frame <- get+ evalObjectState ObjectFrame{uuid = uuid', frame} isTarget+ _ -> pure False+ -- | Remove an atomic value from the OR-Set removeValue :: ( ReplicatedAsPayload a , MonadE m, ReplicaClock m, MonadObjectState (ORSet a) m ) => a -> m ()-removeValue = commonRemove . eqPayload+removeValue v = commonRemove $ pure . eqPayload v +-- | Remove from a field all values that equal to the specified value.+removeFieldValue+ :: ( MonadE m+ , MonadObjectState struct m+ , ReplicaClock m+ , ReplicatedAsPayload a+ )+ => UUID -- ^ Field name+ -> a -- ^ Value+ -> m ()+removeFieldValue field value =+ removeFieldValueIfP field $ pure . eqPayload value++-- | Remove from a field all values that obey the predicate.+removeFieldValueIf+ :: ( MonadE m+ , MonadObjectState struct m+ , ReplicaClock m+ , ReplicatedAsPayload a+ )+ => UUID -- ^ Field name+ -> (a -> m Bool)+ -> m ()+removeFieldValueIf field isTarget =+ removeFieldValueIfP field $ \valuePayload -> do+ value <- fromPayload valuePayload+ isTarget value++-- | Remove from a field all payloads that obey the predicate.+removeFieldValueIfP+ :: (MonadE m, MonadObjectState struct m, ReplicaClock m)+ => UUID -- ^ Field name+ -> (Payload -> m Bool)+ -> m ()+removeFieldValueIfP field isTarget =+ modifyObjectStateChunk_ $ \(StateChunk stateBody) -> do+ (observedOps, stateBody1) <-+ partitionM isFieldAliveAndSameValue stateBody+ removeOps <- for observedOps $ \op@Op{opId = observedEvent} -> do+ tombstone <- getEventUuid -- TODO(2019-07-10, cblp) sequential+ pure op{opId = tombstone, refId = observedEvent}+ let stateBody2 = stateBody1 ++ removeOps+ pure $ StateChunk stateBody2+ where+ isFieldAliveAndSameValue = \case+ Op{refId = Zero, payload = AUuid field' : valuePayload}+ | field' == field -> isTarget valuePayload+ _ -> pure False+ -- | Remove an object reference from the OR-Set removeRef :: (MonadE m, ReplicaClock m, MonadObjectState (ORSet a) m)- => Object a -> m ()-removeRef = commonRemove . eqRef+ => ObjectRef a -> m ()+removeRef r = commonRemove $ pure . eqRef r -- | Reference to an item inside an 'ORSet'. newtype ORSetItem a = ORSetItem UUID@@ -211,7 +278,7 @@ Just Op{payload} -> case payload of [AUuid itemValueRef] -> pure itemValueRef _ -> throwErrorText "item payload is not an object ref"- lift $ runReaderT innerModifier $ Object itemValueRef+ lift $ runReaderT innerModifier $ ObjectRef itemValueRef -- | Find any alive item. If no alive item found, return 'Nothing'. findAnyAlive@@ -234,7 +301,8 @@ type ORSetMap k v = ORSet (k, v) --- | Assign a value to a field+-- | Assign a value to a field, deleting all previous (observed) values.+-- Assignment of 'Nothing' just deletes all values. assignField :: (Replicated a, ReplicaClock m, MonadE m, MonadObjectState struct m) => UUID -- ^ Field name@@ -242,19 +310,38 @@ -> m () assignField field mvalue = modifyObjectStateChunk_ $ \(StateChunk stateBody) -> do+ addOp <- case mvalue of+ Just value -> do+ event <- getEventUuid+ valuePayload <- newRon value+ pure $ Just Op+ { opId = event+ , refId = Zero+ , payload = AUuid field : valuePayload+ }+ Nothing -> pure Nothing+ let (observedOps, stateBody1) = partition (isAliveField field) stateBody+ removeOps <- for observedOps $ \op@Op{opId = observedEvent} -> do+ tombstone <- getEventUuid -- TODO(2019-07-10, cblp) sequential+ pure op{opId = tombstone, refId = observedEvent}+ let stateBody2 = stateBody1 ++ toList addOp ++ removeOps+ pure $ StateChunk stateBody2++addFieldValue+ :: (Replicated a, ReplicaClock m, MonadE m, MonadObjectState struct m)+ => UUID -- ^ Field name+ -> a -- ^ Value+ -> m ()+addFieldValue field value =+ modifyObjectStateChunk_ $ \(StateChunk stateBody) -> do event <- getEventUuid- valuePayload <- maybe (pure []) newRon mvalue+ valuePayload <- newRon value let addOp = Op { opId = event , refId = Zero , payload = AUuid field : valuePayload }- let (observedOps, stateBody1) = partition (isAliveField field) stateBody- removeOps <- for observedOps $ \op@Op{opId = observedEvent} -> do- tombstone <- getEventUuid -- TODO(2019-07-10, cblp) sequential- pure op{opId = tombstone, refId = observedEvent}- let stateBody2 = sortOn opId $ addOp : removeOps ++ stateBody1- pure $ StateChunk stateBody2+ pure $ StateChunk $ stateBody ++ [addOp] isAliveField :: UUID -> Op -> Bool isAliveField field = \case@@ -281,6 +368,20 @@ , field' == field ] +-- | Find object field, merge all versions, return 'Nothing' if no versions+getFieldObject+ :: (MonadE m, MonadObjectState struct m, ReplicatedAsObject a)+ => UUID -- ^ Field name+ -> m (Maybe (ObjectRef a))+getFieldObject field =+ errorContext "ORSet.getFieldObject" $ do+ StateChunk ops <- getObjectStateChunk+ let payloads = filterAliveFieldPayloads field ops+ refs = [ref | AUuid ref : _ <- payloads]+ case refs of+ [] -> pure Nothing+ p:ps -> fmap Just $ reduceObjectStates $ fmap ObjectRef $ p :| ps+ -- | Decode field value, merge all versions, return 'Nothing' if no versions viewField :: (MonadE m, MonadState StateFrame m, ReplicatedAsObject a)@@ -358,29 +459,35 @@ -> ObjectStateT field m a -- ^ Inner object modifier -> ObjectStateT struct m a zoomFieldObject field innerModifier =- errorContext ("ORSet.zoomFieldObject" <> show field) $ do+ errorContext ("ORSet.zoomFieldObject " <> show field) $ do (StateChunk stateBody) <- getObjectStateChunk let objectIds = [ objectId | AUuid objectId : _ <- filterAliveFieldPayloads field stateBody ] object <- case objectIds of- [] -> Object <$> getEventUuid -- create empty object- oid:oids -> reduceObjectStates @field $ fmap Object $ oid :| oids+ [] -> ObjectRef <$> getEventUuid -- create empty object+ oid:oids -> reduceObjectStates @field $ fmap ObjectRef $ oid :| oids lift $ runReaderT innerModifier object -- | Create an ORSet object from a list of named fields. newStruct :: (MonadState StateFrame m, ReplicaClock m)- => [(UUID, Maybe (Instance Replicated))] -> m UUID+ => [(UUID, Instance Replicated)] -> m UUID newStruct fields = do objectId <- getEventUuid stateBody <-- for fields $ \(name, mvalue) -> do+ for fields $ \(name, Instance value) -> do opId <- getEventUuid -- TODO(2019-07-12, cblp, #15) sequential uuids- valuePayload <- case mvalue of- Just (Instance value) -> newRon value- Nothing -> pure []+ valuePayload <- newRon value pure Op{opId, refId = Zero, payload = AUuid name : valuePayload} modify' $ Map.insert objectId $ wireStateChunk stateBody pure objectId++partitionM :: Applicative m => (a -> m Bool) -> [a] -> m ([a], [a])+partitionM f = \case+ [] -> pure ([], [])+ x:xs -> do+ res <- f x+ (as, bs) <- partitionM f xs+ pure ([x | res] ++ as, [x | not res] ++ bs)
lib/RON/Data/RGA.hs view
@@ -45,16 +45,17 @@ ReducedChunk (ReducedChunk, rcBody, rcRef), Reducible, Rep, Replicated (encoding), ReplicatedAsObject, ReplicatedAsPayload,- Unapplied, applyPatches, fromRon, getObject,+ Unapplied, applyPatches, fromRon, getObjectStateChunk, modifyObjectStateChunk_, newObject, newRon,- objectEncoding, reduceUnappliedPatches,- reducibleOpType, stateFromChunk,- stateToChunk, toPayload)+ objectEncoding, readObject,+ reduceUnappliedPatches, reducibleOpType,+ stateFromChunk, stateToChunk, toPayload) import RON.Error (MonadE, errorContext, throwErrorText) import RON.Event (ReplicaClock, getEventUuid, getEventUuids) import RON.Semilattice (Semilattice)-import RON.Types (Object (Object), Op (Op, opId, payload, refId),+import RON.Types (ObjectRef (ObjectRef),+ Op (Op, opId, payload, refId), StateChunk (StateChunk), StateFrame, UUID, WireStateChunk (WireStateChunk, stateBody, stateType)) import RON.Util.Word (pattern B11, ls60)@@ -337,9 +338,9 @@ payload <- newRon item pure $ Op vertexId Zero payload modify' $ Map.insert oid $ wireStateChunk ops- pure $ Object oid+ pure $ ObjectRef oid - getObject = do+ readObject = do StateChunk stateBody <- getObjectStateChunk mItems <- for stateBody $ \Op{refId, payload} -> case refId of Zero -> Just <$> fromRon payload@@ -399,13 +400,13 @@ -- | Create an RGA from a list newFromList :: (Replicated a, MonadState StateFrame m, ReplicaClock m)- => [a] -> m (Object (RGA a))+ => [a] -> m (ObjectRef (RGA a)) newFromList = newObject . RGA -- | Create an 'RgaString' from a text newFromText :: (MonadState StateFrame m, ReplicaClock m)- => Text -> m (Object RgaString)+ => Text -> m (ObjectRef RgaString) newFromText = newFromList . Text.unpack getAliveIndices :: (MonadE m, MonadObjectState (RGA a) m) => m [UUID]@@ -421,7 +422,7 @@ -- | Read elements from RGA getList :: (Replicated a, MonadE m, MonadObjectState (RGA a) m) => m [a]-getList = coerce <$> getObject+getList = coerce <$> readObject -- | Read characters from 'RgaString' getText :: (MonadE m, MonadObjectState RgaString m) => m Text
lib/RON/Data/VersionVector.hs view
@@ -16,13 +16,13 @@ import qualified Data.Map.Strict as Map import RON.Data.Internal (Reducible, Rep, Replicated (encoding),- ReplicatedAsObject, getObject,- getObjectState, newObject, objectEncoding,+ ReplicatedAsObject, getObjectState,+ newObject, objectEncoding, readObject, reducibleOpType, stateFromChunk, stateToChunk) import RON.Event (getEventUuid) import RON.Semilattice (Semilattice)-import RON.Types (Object (Object), Op (Op, opId), UUID (UUID), WireStateChunk (WireStateChunk, stateBody, stateType))+import RON.Types (ObjectRef (ObjectRef), Op (Op, opId), UUID (UUID), WireStateChunk (WireStateChunk, stateBody, stateType)) import qualified RON.UUID as UUID type Origin = Word64@@ -79,8 +79,6 @@ oid <- getEventUuid let ops = Map.elems vv modify' $ Map.insert oid $ wireStateChunk ops- pure $ Object oid-- getObject = getObjectState+ pure $ ObjectRef oid - -- rempty = mempty+ readObject = getObjectState
ron-rdt.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.2 name: ron-rdt-version: 0.8+version: 0.9 bug-reports: https://github.com/ff-notes/ron/issues category: Distributed Systems, Protocol, Database