瀏覽代碼

chore: rename delta

appflowy 2 年之前
父節點
當前提交
450482c1a9
共有 69 個文件被更改,包括 724 次插入711 次删除
  1. 2 2
      frontend/rust-lib/flowy-folder/src/services/folder_editor.rs
  2. 2 2
      frontend/rust-lib/flowy-folder/src/services/web_socket.rs
  3. 2 2
      frontend/rust-lib/flowy-grid/src/services/block_editor.rs
  4. 2 2
      frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
  5. 2 2
      frontend/rust-lib/flowy-grid/src/services/grid_view_manager.rs
  6. 1 1
      frontend/rust-lib/flowy-revision/src/cache/disk/document_impl.rs
  7. 1 1
      frontend/rust-lib/flowy-revision/src/cache/disk/grid_block_impl.rs
  8. 1 1
      frontend/rust-lib/flowy-revision/src/cache/disk/grid_impl.rs
  9. 1 1
      frontend/rust-lib/flowy-revision/src/cache/disk/grid_view_impl.rs
  10. 13 13
      frontend/rust-lib/flowy-revision/src/conflict_resolve.rs
  11. 6 4
      frontend/rust-lib/flowy-revision/src/rev_manager.rs
  12. 10 10
      frontend/rust-lib/flowy-text-block/src/editor.rs
  13. 16 16
      frontend/rust-lib/flowy-text-block/src/queue.rs
  14. 6 6
      frontend/rust-lib/flowy-text-block/src/web_socket.rs
  15. 2 2
      frontend/rust-lib/flowy-text-block/tests/document/script.rs
  16. 6 6
      frontend/rust-lib/flowy-text-block/tests/editor/attribute_test.rs
  17. 12 12
      frontend/rust-lib/flowy-text-block/tests/editor/mod.rs
  18. 118 118
      frontend/rust-lib/flowy-text-block/tests/editor/op_test.rs
  19. 11 11
      frontend/rust-lib/flowy-text-block/tests/editor/serde_test.rs
  20. 4 4
      shared-lib/flowy-sync/src/client_document/default/mod.rs
  21. 22 18
      shared-lib/flowy-sync/src/client_document/document_pad.rs
  22. 2 2
      shared-lib/flowy-sync/src/client_document/extensions/delete/default_delete.rs
  23. 3 3
      shared-lib/flowy-sync/src/client_document/extensions/delete/preserve_line_format_merge.rs
  24. 2 2
      shared-lib/flowy-sync/src/client_document/extensions/format/resolve_block_format.rs
  25. 2 2
      shared-lib/flowy-sync/src/client_document/extensions/format/resolve_inline_format.rs
  26. 3 3
      shared-lib/flowy-sync/src/client_document/extensions/helper.rs
  27. 2 2
      shared-lib/flowy-sync/src/client_document/extensions/insert/auto_exit_block.rs
  28. 4 4
      shared-lib/flowy-sync/src/client_document/extensions/insert/auto_format.rs
  29. 5 5
      shared-lib/flowy-sync/src/client_document/extensions/insert/default_insert.rs
  30. 15 3
      shared-lib/flowy-sync/src/client_document/extensions/insert/mod.rs
  31. 4 4
      shared-lib/flowy-sync/src/client_document/extensions/insert/preserve_block_format.rs
  32. 4 4
      shared-lib/flowy-sync/src/client_document/extensions/insert/preserve_inline_format.rs
  33. 4 4
      shared-lib/flowy-sync/src/client_document/extensions/insert/reset_format_on_new_line.rs
  34. 4 4
      shared-lib/flowy-sync/src/client_document/extensions/mod.rs
  35. 9 9
      shared-lib/flowy-sync/src/client_document/history.rs
  36. 10 5
      shared-lib/flowy-sync/src/client_document/view.rs
  37. 2 2
      shared-lib/flowy-sync/src/client_folder/builder.rs
  38. 2 2
      shared-lib/flowy-sync/src/client_grid/block_revision_pad.rs
  39. 2 2
      shared-lib/flowy-sync/src/client_grid/grid_revision_pad.rs
  40. 2 2
      shared-lib/flowy-sync/src/client_grid/view_revision_pad.rs
  41. 13 19
      shared-lib/flowy-sync/src/entities/revision.rs
  42. 4 4
      shared-lib/flowy-sync/src/entities/text_block.rs
  43. 1 1
      shared-lib/flowy-sync/src/lib.rs
  44. 4 4
      shared-lib/flowy-sync/src/server_document/document_manager.rs
  45. 14 13
      shared-lib/flowy-sync/src/server_document/document_pad.rs
  46. 11 10
      shared-lib/flowy-sync/src/server_folder/folder_pad.rs
  47. 37 29
      shared-lib/flowy-sync/src/synchronizer.rs
  48. 17 31
      shared-lib/flowy-sync/src/util.rs
  49. 28 28
      shared-lib/lib-ot/src/core/attributes/attribute.rs
  50. 10 10
      shared-lib/lib-ot/src/core/delta/builder.rs
  51. 17 17
      shared-lib/lib-ot/src/core/delta/cursor.rs
  52. 27 27
      shared-lib/lib-ot/src/core/delta/iterator.rs
  53. 8 8
      shared-lib/lib-ot/src/core/delta/operation/builder.rs
  54. 53 57
      shared-lib/lib-ot/src/core/delta/operation/operation.rs
  55. 11 11
      shared-lib/lib-ot/src/core/delta/operation/operation_serde.rs
  56. 83 82
      shared-lib/lib-ot/src/core/delta/ops.rs
  57. 6 6
      shared-lib/lib-ot/src/core/delta/ops_serde.rs
  58. 11 8
      shared-lib/lib-ot/src/core/node_tree/node.rs
  59. 3 3
      shared-lib/lib-ot/src/core/node_tree/node_serde.rs
  60. 9 9
      shared-lib/lib-ot/src/core/node_tree/operation.rs
  61. 3 3
      shared-lib/lib-ot/src/core/node_tree/operation_serde.rs
  62. 8 8
      shared-lib/lib-ot/src/core/node_tree/transaction.rs
  63. 6 6
      shared-lib/lib-ot/src/core/node_tree/tree.rs
  64. 4 4
      shared-lib/lib-ot/src/text_delta/attributes.rs
  65. 4 4
      shared-lib/lib-ot/src/text_delta/delta.rs
  66. 2 2
      shared-lib/lib-ot/tests/node/editor_test.rs
  67. 2 2
      shared-lib/lib-ot/tests/node/operation_test.rs
  68. 4 4
      shared-lib/lib-ot/tests/node/script.rs
  69. 3 3
      shared-lib/lib-ot/tests/node/tree_test.rs

+ 2 - 2
frontend/rust-lib/flowy-folder/src/services/folder_editor.rs

@@ -4,7 +4,7 @@ use flowy_error::{FlowyError, FlowyResult};
 use flowy_revision::{
     RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionWebSocket,
 };
-use flowy_sync::util::make_text_delta_from_revisions;
+use flowy_sync::util::make_delta_from_revisions;
 use flowy_sync::{
     client_folder::{FolderChangeset, FolderPad},
     entities::{revision::Revision, ws_data::ServerRevisionWSData},
@@ -131,7 +131,7 @@ impl FolderEditor {
 pub struct FolderRevisionCompactor();
 impl RevisionCompactor for FolderRevisionCompactor {
     fn bytes_from_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
-        let delta = make_text_delta_from_revisions(revisions)?;
+        let delta = make_delta_from_revisions(revisions)?;
         Ok(delta.json_bytes())
     }
 }

+ 2 - 2
frontend/rust-lib/flowy-folder/src/services/web_socket.rs

@@ -52,7 +52,7 @@ struct FolderConflictResolver {
 }
 
 impl ConflictResolver<EmptyAttributes> for FolderConflictResolver {
-    fn compose_delta(&self, delta: Delta) -> BoxResultFuture<DeltaMD5, FlowyError> {
+    fn compose_delta(&self, delta: Delta) -> BoxResultFuture<OperationsMD5, FlowyError> {
         let folder_pad = self.folder_pad.clone();
         Box::pin(async move {
             let md5 = folder_pad.write().compose_remote_delta(delta)?;
@@ -82,7 +82,7 @@ impl ConflictResolver<EmptyAttributes> for FolderConflictResolver {
         })
     }
 
-    fn reset_delta(&self, delta: Delta) -> BoxResultFuture<DeltaMD5, FlowyError> {
+    fn reset_delta(&self, delta: Delta) -> BoxResultFuture<OperationsMD5, FlowyError> {
         let folder_pad = self.folder_pad.clone();
         Box::pin(async move {
             let md5 = folder_pad.write().reset_folder(delta)?;

+ 2 - 2
frontend/rust-lib/flowy-grid/src/services/block_editor.rs

@@ -5,7 +5,7 @@ use flowy_grid_data_model::revision::{CellRevision, GridBlockRevision, RowChange
 use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder};
 use flowy_sync::client_grid::{GridBlockRevisionChangeset, GridBlockRevisionPad};
 use flowy_sync::entities::revision::Revision;
-use flowy_sync::util::make_text_delta_from_revisions;
+use flowy_sync::util::make_delta_from_revisions;
 use lib_infra::future::FutureResult;
 
 use std::borrow::Cow;
@@ -204,7 +204,7 @@ impl RevisionObjectBuilder for GridBlockRevisionPadBuilder {
 pub struct GridBlockRevisionCompactor();
 impl RevisionCompactor for GridBlockRevisionCompactor {
     fn bytes_from_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
-        let delta = make_text_delta_from_revisions(revisions)?;
+        let delta = make_delta_from_revisions(revisions)?;
         Ok(delta.json_bytes())
     }
 }

+ 2 - 2
frontend/rust-lib/flowy-grid/src/services/grid_editor.rs

@@ -17,7 +17,7 @@ use flowy_revision::{RevisionCloudService, RevisionCompactor, RevisionManager, R
 use flowy_sync::client_grid::{GridRevisionChangeset, GridRevisionPad, JsonDeserializer};
 use flowy_sync::entities::revision::Revision;
 use flowy_sync::errors::CollaborateResult;
-use flowy_sync::util::make_text_delta_from_revisions;
+use flowy_sync::util::make_delta_from_revisions;
 use lib_infra::future::{wrap_future, FutureResult};
 
 use std::collections::HashMap;
@@ -834,7 +834,7 @@ impl RevisionCloudService for GridRevisionCloudService {
 pub struct GridRevisionCompactor();
 impl RevisionCompactor for GridRevisionCompactor {
     fn bytes_from_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
-        let delta = make_text_delta_from_revisions(revisions)?;
+        let delta = make_delta_from_revisions(revisions)?;
         Ok(delta.json_bytes())
     }
 }

+ 2 - 2
frontend/rust-lib/flowy-grid/src/services/grid_view_manager.rs

@@ -12,7 +12,7 @@ use flowy_grid_data_model::revision::{FieldRevision, RowChangeset, RowRevision};
 use flowy_revision::disk::SQLiteGridViewRevisionPersistence;
 use flowy_revision::{RevisionCompactor, RevisionManager, RevisionPersistence, SQLiteRevisionSnapshotPersistence};
 use flowy_sync::entities::revision::Revision;
-use flowy_sync::util::make_text_delta_from_revisions;
+use flowy_sync::util::make_delta_from_revisions;
 use lib_infra::future::AFFuture;
 use std::sync::Arc;
 
@@ -246,7 +246,7 @@ pub async fn make_grid_view_rev_manager(user: &Arc<dyn GridUser>, view_id: &str)
 pub struct GridViewRevisionCompactor();
 impl RevisionCompactor for GridViewRevisionCompactor {
     fn bytes_from_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
-        let delta = make_text_delta_from_revisions(revisions)?;
+        let delta = make_delta_from_revisions(revisions)?;
         Ok(delta.json_bytes())
     }
 }

+ 1 - 1
frontend/rust-lib/flowy-revision/src/cache/disk/document_impl.rs

@@ -109,7 +109,7 @@ impl TextRevisionSql {
                     dsl::doc_id.eq(record.revision.object_id),
                     dsl::base_rev_id.eq(record.revision.base_rev_id),
                     dsl::rev_id.eq(record.revision.rev_id),
-                    dsl::data.eq(record.revision.delta_data),
+                    dsl::data.eq(record.revision.bytes),
                     dsl::state.eq(rev_state),
                     dsl::ty.eq(RevTableType::Local),
                 )

+ 1 - 1
frontend/rust-lib/flowy-revision/src/cache/disk/grid_block_impl.rs

@@ -108,7 +108,7 @@ impl GridMetaRevisionSql {
                     dsl::object_id.eq(record.revision.object_id),
                     dsl::base_rev_id.eq(record.revision.base_rev_id),
                     dsl::rev_id.eq(record.revision.rev_id),
-                    dsl::data.eq(record.revision.delta_data),
+                    dsl::data.eq(record.revision.bytes),
                     dsl::state.eq(rev_state),
                 )
             })

+ 1 - 1
frontend/rust-lib/flowy-revision/src/cache/disk/grid_impl.rs

@@ -107,7 +107,7 @@ impl GridRevisionSql {
                     dsl::object_id.eq(record.revision.object_id),
                     dsl::base_rev_id.eq(record.revision.base_rev_id),
                     dsl::rev_id.eq(record.revision.rev_id),
-                    dsl::data.eq(record.revision.delta_data),
+                    dsl::data.eq(record.revision.bytes),
                     dsl::state.eq(rev_state),
                 )
             })

+ 1 - 1
frontend/rust-lib/flowy-revision/src/cache/disk/grid_view_impl.rs

@@ -106,7 +106,7 @@ impl GridViewRevisionSql {
                     dsl::object_id.eq(record.revision.object_id),
                     dsl::base_rev_id.eq(record.revision.base_rev_id),
                     dsl::rev_id.eq(record.revision.rev_id),
-                    dsl::data.eq(record.revision.delta_data),
+                    dsl::data.eq(record.revision.bytes),
                     dsl::state.eq(rev_state),
                 )
             })

+ 13 - 13
frontend/rust-lib/flowy-revision/src/conflict_resolve.rs

@@ -6,23 +6,23 @@ use flowy_sync::{
         revision::{RepeatedRevision, Revision, RevisionRange},
         ws_data::ServerRevisionWSDataType,
     },
-    util::make_delta_from_revisions,
+    util::make_operations_from_revisions,
 };
 use lib_infra::future::BoxResultFuture;
-use lib_ot::core::{Attributes, EmptyAttributes, OperationAttributes, Operations};
+use lib_ot::core::{AttributeHashMap, DeltaOperations, EmptyAttributes, OperationAttributes};
 
 use serde::de::DeserializeOwned;
 use std::{convert::TryFrom, sync::Arc};
 
-pub type DeltaMD5 = String;
+pub type OperationsMD5 = String;
 
 pub trait ConflictResolver<T>
 where
     T: OperationAttributes + Send + Sync,
 {
-    fn compose_delta(&self, delta: Operations<T>) -> BoxResultFuture<DeltaMD5, FlowyError>;
-    fn transform_delta(&self, delta: Operations<T>) -> BoxResultFuture<TransformDeltas<T>, FlowyError>;
-    fn reset_delta(&self, delta: Operations<T>) -> BoxResultFuture<DeltaMD5, FlowyError>;
+    fn compose_delta(&self, delta: DeltaOperations<T>) -> BoxResultFuture<OperationsMD5, FlowyError>;
+    fn transform_delta(&self, delta: DeltaOperations<T>) -> BoxResultFuture<TransformDeltas<T>, FlowyError>;
+    fn reset_delta(&self, delta: DeltaOperations<T>) -> BoxResultFuture<OperationsMD5, FlowyError>;
 }
 
 pub trait ConflictRevisionSink: Send + Sync + 'static {
@@ -30,7 +30,7 @@ pub trait ConflictRevisionSink: Send + Sync + 'static {
     fn ack(&self, rev_id: String, ty: ServerRevisionWSDataType) -> BoxResultFuture<(), FlowyError>;
 }
 
-pub type RichTextConflictController = ConflictController<Attributes>;
+pub type RichTextConflictController = ConflictController<AttributeHashMap>;
 pub type PlainTextConflictController = ConflictController<EmptyAttributes>;
 
 pub struct ConflictController<T>
@@ -103,7 +103,7 @@ where
             }
         }
 
-        let new_delta = make_delta_from_revisions(revisions.clone())?;
+        let new_delta = make_operations_from_revisions(revisions.clone())?;
 
         let TransformDeltas {
             client_prime,
@@ -142,8 +142,8 @@ where
 fn make_client_and_server_revision<T>(
     user_id: &str,
     rev_manager: &Arc<RevisionManager>,
-    client_delta: Operations<T>,
-    server_delta: Option<Operations<T>>,
+    client_delta: DeltaOperations<T>,
+    server_delta: Option<DeltaOperations<T>>,
     md5: String,
 ) -> (Revision, Option<Revision>)
 where
@@ -175,12 +175,12 @@ where
     }
 }
 
-pub type RichTextTransformDeltas = TransformDeltas<Attributes>;
+pub type RichTextTransformDeltas = TransformDeltas<AttributeHashMap>;
 
 pub struct TransformDeltas<T>
 where
     T: OperationAttributes,
 {
-    pub client_prime: Operations<T>,
-    pub server_prime: Option<Operations<T>>,
+    pub client_prime: DeltaOperations<T>,
+    pub server_prime: Option<DeltaOperations<T>>,
 }

+ 6 - 4
frontend/rust-lib/flowy-revision/src/rev_manager.rs

@@ -9,6 +9,8 @@ use flowy_sync::{
 use lib_infra::future::FutureResult;
 use std::sync::Arc;
 
+pub type SyncObject = lib_ot::text_delta::TextOperations;
+
 pub trait RevisionCloudService: Send + Sync {
     fn fetch_object(&self, user_id: &str, object_id: &str) -> FutureResult<Vec<Revision>, FlowyError>;
 }
@@ -33,8 +35,8 @@ pub trait RevisionCompactor: Send + Sync {
 
         let (base_rev_id, rev_id) = first_revision.pair_rev_id();
         let md5 = last_revision.md5.clone();
-        let delta_data = self.bytes_from_revisions(revisions)?;
-        Ok(Revision::new(object_id, base_rev_id, rev_id, delta_data, user_id, md5))
+        let bytes = self.bytes_from_revisions(revisions)?;
+        Ok(Revision::new(object_id, base_rev_id, rev_id, bytes, user_id, md5))
     }
 
     fn bytes_from_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes>;
@@ -113,7 +115,7 @@ impl RevisionManager {
 
     #[tracing::instrument(level = "debug", skip(self, revision), err)]
     pub async fn add_remote_revision(&self, revision: &Revision) -> Result<(), FlowyError> {
-        if revision.delta_data.is_empty() {
+        if revision.bytes.is_empty() {
             return Err(FlowyError::internal().context("Delta data should be empty"));
         }
 
@@ -125,7 +127,7 @@ impl RevisionManager {
 
     #[tracing::instrument(level = "debug", skip_all, err)]
     pub async fn add_local_revision(&self, revision: &Revision) -> Result<(), FlowyError> {
-        if revision.delta_data.is_empty() {
+        if revision.bytes.is_empty() {
             return Err(FlowyError::internal().context("Delta data should be empty"));
         }
         let rev_id = self

+ 10 - 10
frontend/rust-lib/flowy-text-block/src/editor.rs

@@ -11,12 +11,12 @@ use flowy_sync::entities::ws_data::ServerRevisionWSData;
 use flowy_sync::{
     entities::{revision::Revision, text_block::DocumentPB},
     errors::CollaborateResult,
-    util::make_delta_from_revisions,
+    util::make_operations_from_revisions,
 };
 use lib_ot::core::AttributeEntry;
 use lib_ot::{
-    core::{Interval, Operation},
-    text_delta::TextDelta,
+    core::{DeltaOperation, Interval},
+    text_delta::TextOperations,
 };
 use lib_ws::WSConnectState;
 use std::sync::Arc;
@@ -150,7 +150,7 @@ impl TextBlockEditor {
 
     #[tracing::instrument(level = "trace", skip(self, data), err)]
     pub(crate) async fn compose_local_delta(&self, data: Bytes) -> Result<(), FlowyError> {
-        let delta = TextDelta::from_bytes(&data)?;
+        let delta = TextOperations::from_bytes(&data)?;
         let (ret, rx) = oneshot::channel::<CollaborateResult<()>>();
         let msg = EditorCommand::ComposeLocalDelta {
             delta: delta.clone(),
@@ -196,7 +196,7 @@ impl std::ops::Drop for TextBlockEditor {
 fn spawn_edit_queue(
     user: Arc<dyn TextEditorUser>,
     rev_manager: Arc<RevisionManager>,
-    delta: TextDelta,
+    delta: TextOperations,
 ) -> EditorCommandSender {
     let (sender, receiver) = mpsc::channel(1000);
     let edit_queue = EditBlockQueue::new(user, rev_manager, delta, receiver);
@@ -215,8 +215,8 @@ fn spawn_edit_queue(
 
 #[cfg(feature = "flowy_unit_test")]
 impl TextBlockEditor {
-    pub async fn text_block_delta(&self) -> FlowyResult<TextDelta> {
-        let (ret, rx) = oneshot::channel::<CollaborateResult<TextDelta>>();
+    pub async fn text_block_delta(&self) -> FlowyResult<TextOperations> {
+        let (ret, rx) = oneshot::channel::<CollaborateResult<TextOperations>>();
         let msg = EditorCommand::ReadDelta { ret };
         let _ = self.edit_cmd_tx.send(msg).await;
         let delta = rx.await.map_err(internal_error)??;
@@ -234,7 +234,7 @@ impl RevisionObjectBuilder for TextBlockInfoBuilder {
 
     fn build_object(object_id: &str, revisions: Vec<Revision>) -> FlowyResult<Self::Output> {
         let (base_rev_id, rev_id) = revisions.last().unwrap().pair_rev_id();
-        let mut delta = make_delta_from_revisions(revisions)?;
+        let mut delta = make_operations_from_revisions(revisions)?;
         correct_delta(&mut delta);
 
         Result::<DocumentPB, FlowyError>::Ok(DocumentPB {
@@ -248,12 +248,12 @@ impl RevisionObjectBuilder for TextBlockInfoBuilder {
 
 // quill-editor requires the delta should end with '\n' and only contains the
 // insert operation. The function, correct_delta maybe be removed in the future.
-fn correct_delta(delta: &mut TextDelta) {
+fn correct_delta(delta: &mut TextOperations) {
     if let Some(op) = delta.ops.last() {
         let op_data = op.get_data();
         if !op_data.ends_with('\n') {
             tracing::warn!("The document must end with newline. Correcting it by inserting newline op");
-            delta.ops.push(Operation::Insert("\n".into()));
+            delta.ops.push(DeltaOperation::Insert("\n".into()));
         }
     }
 

+ 16 - 16
frontend/rust-lib/flowy-text-block/src/queue.rs

@@ -3,18 +3,18 @@ use crate::TextEditorUser;
 use async_stream::stream;
 use bytes::Bytes;
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_revision::{DeltaMD5, RevisionCompactor, RevisionManager, RichTextTransformDeltas, TransformDeltas};
-use flowy_sync::util::make_delta_from_revisions;
+use flowy_revision::{OperationsMD5, RevisionCompactor, RevisionManager, RichTextTransformDeltas, TransformDeltas};
+use flowy_sync::util::make_operations_from_revisions;
 use flowy_sync::{
     client_document::{history::UndoResult, ClientDocument},
     entities::revision::{RevId, Revision},
     errors::CollaborateError,
 };
 use futures::stream::StreamExt;
-use lib_ot::core::{AttributeEntry, Attributes};
+use lib_ot::core::{AttributeEntry, AttributeHashMap};
 use lib_ot::{
     core::{Interval, OperationTransform},
-    text_delta::TextDelta,
+    text_delta::TextOperations,
 };
 use std::sync::Arc;
 use tokio::sync::{oneshot, RwLock};
@@ -32,7 +32,7 @@ impl EditBlockQueue {
     pub(crate) fn new(
         user: Arc<dyn TextEditorUser>,
         rev_manager: Arc<RevisionManager>,
-        delta: TextDelta,
+        delta: TextOperations,
         receiver: EditorCommandReceiver,
     ) -> Self {
         let document = Arc::new(RwLock::new(ClientDocument::from_delta(delta)));
@@ -92,8 +92,8 @@ impl EditBlockQueue {
             EditorCommand::TransformDelta { delta, ret } => {
                 let f = || async {
                     let read_guard = self.document.read().await;
-                    let mut server_prime: Option<TextDelta> = None;
-                    let client_prime: TextDelta;
+                    let mut server_prime: Option<TextOperations> = None;
+                    let client_prime: TextOperations;
 
                     if read_guard.is_empty() {
                         // Do nothing
@@ -175,7 +175,7 @@ impl EditBlockQueue {
         Ok(())
     }
 
-    async fn save_local_delta(&self, delta: TextDelta, md5: String) -> Result<RevId, FlowyError> {
+    async fn save_local_delta(&self, delta: TextOperations, md5: String) -> Result<RevId, FlowyError> {
         let delta_data = delta.json_bytes();
         let (base_rev_id, rev_id) = self.rev_manager.next_rev_id_pair();
         let user_id = self.user.user_id()?;
@@ -195,7 +195,7 @@ impl EditBlockQueue {
 pub(crate) struct TextBlockRevisionCompactor();
 impl RevisionCompactor for TextBlockRevisionCompactor {
     fn bytes_from_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<Bytes> {
-        let delta = make_delta_from_revisions::<Attributes>(revisions)?;
+        let delta = make_operations_from_revisions::<AttributeHashMap>(revisions)?;
         Ok(delta.json_bytes())
     }
 }
@@ -204,19 +204,19 @@ pub(crate) type Ret<T> = oneshot::Sender<Result<T, CollaborateError>>;
 
 pub(crate) enum EditorCommand {
     ComposeLocalDelta {
-        delta: TextDelta,
+        delta: TextOperations,
         ret: Ret<()>,
     },
     ComposeRemoteDelta {
-        client_delta: TextDelta,
-        ret: Ret<DeltaMD5>,
+        client_delta: TextOperations,
+        ret: Ret<OperationsMD5>,
     },
     ResetDelta {
-        delta: TextDelta,
-        ret: Ret<DeltaMD5>,
+        delta: TextOperations,
+        ret: Ret<OperationsMD5>,
     },
     TransformDelta {
-        delta: TextDelta,
+        delta: TextOperations,
         ret: Ret<RichTextTransformDeltas>,
     },
     Insert {
@@ -255,7 +255,7 @@ pub(crate) enum EditorCommand {
     },
     #[allow(dead_code)]
     ReadDelta {
-        ret: Ret<TextDelta>,
+        ret: Ret<TextOperations>,
     },
 }
 

+ 6 - 6
frontend/rust-lib/flowy-text-block/src/web_socket.rs

@@ -10,9 +10,9 @@ use flowy_sync::{
     errors::CollaborateResult,
 };
 use lib_infra::future::{BoxResultFuture, FutureResult};
-use lib_ot::core::Attributes;
+use lib_ot::core::AttributeHashMap;
 
-use lib_ot::text_delta::TextDelta;
+use lib_ot::text_delta::TextOperations;
 use lib_ws::WSConnectState;
 use std::{sync::Arc, time::Duration};
 use tokio::sync::{
@@ -112,8 +112,8 @@ struct TextBlockConflictResolver {
     edit_cmd_tx: EditorCommandSender,
 }
 
-impl ConflictResolver<Attributes> for TextBlockConflictResolver {
-    fn compose_delta(&self, delta: TextDelta) -> BoxResultFuture<DeltaMD5, FlowyError> {
+impl ConflictResolver<AttributeHashMap> for TextBlockConflictResolver {
+    fn compose_delta(&self, delta: TextOperations) -> BoxResultFuture<OperationsMD5, FlowyError> {
         let tx = self.edit_cmd_tx.clone();
         Box::pin(async move {
             let (ret, rx) = oneshot::channel();
@@ -132,7 +132,7 @@ impl ConflictResolver<Attributes> for TextBlockConflictResolver {
 
     fn transform_delta(
         &self,
-        delta: TextDelta,
+        delta: TextOperations,
     ) -> BoxResultFuture<flowy_revision::RichTextTransformDeltas, FlowyError> {
         let tx = self.edit_cmd_tx.clone();
         Box::pin(async move {
@@ -147,7 +147,7 @@ impl ConflictResolver<Attributes> for TextBlockConflictResolver {
         })
     }
 
-    fn reset_delta(&self, delta: TextDelta) -> BoxResultFuture<DeltaMD5, FlowyError> {
+    fn reset_delta(&self, delta: TextOperations) -> BoxResultFuture<OperationsMD5, FlowyError> {
         let tx = self.edit_cmd_tx.clone();
         Box::pin(async move {
             let (ret, rx) = oneshot::channel();

+ 2 - 2
frontend/rust-lib/flowy-text-block/tests/document/script.rs

@@ -2,7 +2,7 @@ use flowy_revision::disk::RevisionState;
 use flowy_test::{helper::ViewTest, FlowySDKTest};
 use flowy_text_block::editor::TextBlockEditor;
 use flowy_text_block::TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS;
-use lib_ot::{core::Interval, text_delta::TextDelta};
+use lib_ot::{core::Interval, text_delta::TextOperations};
 use std::sync::Arc;
 use tokio::time::{sleep, Duration};
 
@@ -71,7 +71,7 @@ impl TextBlockEditorTest {
                 assert_eq!(next_revision.rev_id, rev_id.unwrap());
             }
             EditorScript::AssertJson(expected) => {
-                let expected_delta: TextDelta = serde_json::from_str(expected).unwrap();
+                let expected_delta: TextOperations = serde_json::from_str(expected).unwrap();
                 let delta = self.editor.text_block_delta().await.unwrap();
                 if expected_delta != delta {
                     eprintln!("✅ expect: {}", expected,);

+ 6 - 6
frontend/rust-lib/flowy-text-block/tests/editor/attribute_test.rs

@@ -3,7 +3,7 @@ use crate::editor::{TestBuilder, TestOp::*};
 use flowy_sync::client_document::{NewlineDoc, EmptyDoc};
 use lib_ot::core::{Interval, OperationTransform, NEW_LINE, WHITESPACE, OTString};
 use unicode_segmentation::UnicodeSegmentation;
-use lib_ot::text_delta::TextDelta;
+use lib_ot::text_delta::TextOperations;
 
 #[test]
 fn attributes_bold_added() {
@@ -762,12 +762,12 @@ fn attributes_preserve_list_format_on_merge() {
 
 #[test]
 fn delta_compose() {
-    let mut delta = TextDelta::from_json(r#"[{"insert":"\n"}]"#).unwrap();
+    let mut delta = TextOperations::from_json(r#"[{"insert":"\n"}]"#).unwrap();
     let deltas = vec![
-        TextDelta::from_json(r#"[{"retain":1,"attributes":{"list":"unchecked"}}]"#).unwrap(),
-        TextDelta::from_json(r#"[{"insert":"a"}]"#).unwrap(),
-        TextDelta::from_json(r#"[{"retain":1},{"insert":"\n","attributes":{"list":"unchecked"}}]"#).unwrap(),
-        TextDelta::from_json(r#"[{"retain":2},{"retain":1,"attributes":{"list":""}}]"#).unwrap(),
+        TextOperations::from_json(r#"[{"retain":1,"attributes":{"list":"unchecked"}}]"#).unwrap(),
+        TextOperations::from_json(r#"[{"insert":"a"}]"#).unwrap(),
+        TextOperations::from_json(r#"[{"retain":1},{"insert":"\n","attributes":{"list":"unchecked"}}]"#).unwrap(),
+        TextOperations::from_json(r#"[{"retain":2},{"retain":1,"attributes":{"list":""}}]"#).unwrap(),
     ];
 
     for d in deltas {

+ 12 - 12
frontend/rust-lib/flowy-text-block/tests/editor/mod.rs

@@ -8,7 +8,7 @@ use derive_more::Display;
 use flowy_sync::client_document::{ClientDocument, InitialDocumentText};
 use lib_ot::{
     core::*,
-    text_delta::{BuildInTextAttribute, TextDelta},
+    text_delta::{BuildInTextAttribute, TextOperations},
 };
 use rand::{prelude::*, Rng as WrappedRng};
 use std::{sync::Once, time::Duration};
@@ -81,8 +81,8 @@ pub enum TestOp {
 
 pub struct TestBuilder {
     documents: Vec<ClientDocument>,
-    deltas: Vec<Option<TextDelta>>,
-    primes: Vec<Option<TextDelta>>,
+    deltas: Vec<Option<TextOperations>>,
+    primes: Vec<Option<TextOperations>>,
 }
 
 impl TestBuilder {
@@ -226,8 +226,8 @@ impl TestBuilder {
 
             TestOp::AssertDocJson(delta_i, expected) => {
                 let delta_json = self.documents[*delta_i].delta_str();
-                let expected_delta: TextDelta = serde_json::from_str(expected).unwrap();
-                let target_delta: TextDelta = serde_json::from_str(&delta_json).unwrap();
+                let expected_delta: TextOperations = serde_json::from_str(expected).unwrap();
+                let target_delta: TextOperations = serde_json::from_str(&delta_json).unwrap();
 
                 if expected_delta != target_delta {
                     log::error!("✅ expect: {}", expected,);
@@ -238,8 +238,8 @@ impl TestBuilder {
 
             TestOp::AssertPrimeJson(doc_i, expected) => {
                 let prime_json = self.primes[*doc_i].as_ref().unwrap().json_str();
-                let expected_prime: TextDelta = serde_json::from_str(expected).unwrap();
-                let target_prime: TextDelta = serde_json::from_str(&prime_json).unwrap();
+                let expected_prime: TextOperations = serde_json::from_str(expected).unwrap();
+                let target_prime: TextOperations = serde_json::from_str(&prime_json).unwrap();
 
                 if expected_prime != target_prime {
                     log::error!("✅ expect prime: {}", expected,);
@@ -297,8 +297,8 @@ impl Rng {
             .collect()
     }
 
-    pub fn gen_delta(&mut self, s: &str) -> TextDelta {
-        let mut delta = TextDelta::default();
+    pub fn gen_delta(&mut self, s: &str) -> TextOperations {
+        let mut delta = TextOperations::default();
         let s = OTString::from(s);
         loop {
             let left = s.utf16_len() - delta.utf16_base_len;
@@ -312,18 +312,18 @@ impl Rng {
             };
             match self.0.gen_range(0.0..1.0) {
                 f if f < 0.2 => {
-                    delta.insert(&self.gen_string(i), Attributes::default());
+                    delta.insert(&self.gen_string(i), AttributeHashMap::default());
                 }
                 f if f < 0.4 => {
                     delta.delete(i);
                 }
                 _ => {
-                    delta.retain(i, Attributes::default());
+                    delta.retain(i, AttributeHashMap::default());
                 }
             }
         }
         if self.0.gen_range(0.0..1.0) < 0.3 {
-            delta.insert(&("1".to_owned() + &self.gen_string(10)), Attributes::default());
+            delta.insert(&("1".to_owned() + &self.gen_string(10)), AttributeHashMap::default());
         }
         delta
     }

+ 118 - 118
frontend/rust-lib/flowy-text-block/tests/editor/op_test.rs

@@ -1,8 +1,8 @@
 #![allow(clippy::all)]
 use crate::editor::{Rng, TestBuilder, TestOp::*};
 use flowy_sync::client_document::{EmptyDoc, NewlineDoc};
-use lib_ot::text_delta::TextDeltaBuilder;
-use lib_ot::{core::Interval, core::*, text_delta::TextDelta};
+use lib_ot::text_delta::TextOperationBuilder;
+use lib_ot::{core::Interval, core::*, text_delta::TextOperations};
 
 #[test]
 fn attributes_insert_text() {
@@ -37,7 +37,7 @@ fn attributes_insert_text_at_middle() {
 #[test]
 fn delta_get_ops_in_interval_1() {
     let operations = OperationsBuilder::new().insert("123").insert("4").build();
-    let delta = TextDeltaBuilder::from_operations(operations);
+    let delta = TextOperationBuilder::from_operations(operations);
 
     let mut iterator = OperationIterator::from_interval(&delta, Interval::new(0, 4));
     assert_eq!(iterator.ops(), delta.ops);
@@ -45,11 +45,11 @@ fn delta_get_ops_in_interval_1() {
 
 #[test]
 fn delta_get_ops_in_interval_2() {
-    let mut delta = TextDelta::default();
-    let insert_a = Operation::insert("123");
-    let insert_b = Operation::insert("4");
-    let insert_c = Operation::insert("5");
-    let retain_a = Operation::retain(3);
+    let mut delta = TextOperations::default();
+    let insert_a = DeltaOperation::insert("123");
+    let insert_b = DeltaOperation::insert("4");
+    let insert_c = DeltaOperation::insert("5");
+    let retain_a = DeltaOperation::retain(3);
 
     delta.add(insert_a.clone());
     delta.add(retain_a.clone());
@@ -58,12 +58,12 @@ fn delta_get_ops_in_interval_2() {
 
     assert_eq!(
         OperationIterator::from_interval(&delta, Interval::new(0, 2)).ops(),
-        vec![Operation::insert("12")]
+        vec![DeltaOperation::insert("12")]
     );
 
     assert_eq!(
         OperationIterator::from_interval(&delta, Interval::new(1, 3)).ops(),
-        vec![Operation::insert("23")]
+        vec![DeltaOperation::insert("23")]
     );
 
     assert_eq!(
@@ -73,7 +73,7 @@ fn delta_get_ops_in_interval_2() {
 
     assert_eq!(
         OperationIterator::from_interval(&delta, Interval::new(0, 4)).ops(),
-        vec![insert_a.clone(), Operation::retain(1)]
+        vec![insert_a.clone(), DeltaOperation::retain(1)]
     );
 
     assert_eq!(
@@ -89,21 +89,21 @@ fn delta_get_ops_in_interval_2() {
 
 #[test]
 fn delta_get_ops_in_interval_3() {
-    let mut delta = TextDelta::default();
-    let insert_a = Operation::insert("123456");
+    let mut delta = TextOperations::default();
+    let insert_a = DeltaOperation::insert("123456");
     delta.add(insert_a.clone());
     assert_eq!(
         OperationIterator::from_interval(&delta, Interval::new(3, 5)).ops(),
-        vec![Operation::insert("45")]
+        vec![DeltaOperation::insert("45")]
     );
 }
 
 #[test]
 fn delta_get_ops_in_interval_4() {
-    let mut delta = TextDelta::default();
-    let insert_a = Operation::insert("12");
-    let insert_b = Operation::insert("34");
-    let insert_c = Operation::insert("56");
+    let mut delta = TextOperations::default();
+    let insert_a = DeltaOperation::insert("12");
+    let insert_b = DeltaOperation::insert("34");
+    let insert_c = DeltaOperation::insert("56");
 
     delta.ops.push(insert_a.clone());
     delta.ops.push(insert_b.clone());
@@ -124,20 +124,20 @@ fn delta_get_ops_in_interval_4() {
 
     assert_eq!(
         OperationIterator::from_interval(&delta, Interval::new(2, 5)).ops(),
-        vec![Operation::insert("34"), Operation::insert("5")]
+        vec![DeltaOperation::insert("34"), DeltaOperation::insert("5")]
     );
 }
 
 #[test]
 fn delta_get_ops_in_interval_5() {
-    let mut delta = TextDelta::default();
-    let insert_a = Operation::insert("123456");
-    let insert_b = Operation::insert("789");
+    let mut delta = TextOperations::default();
+    let insert_a = DeltaOperation::insert("123456");
+    let insert_b = DeltaOperation::insert("789");
     delta.ops.push(insert_a.clone());
     delta.ops.push(insert_b.clone());
     assert_eq!(
         OperationIterator::from_interval(&delta, Interval::new(4, 8)).ops(),
-        vec![Operation::insert("56"), Operation::insert("78")]
+        vec![DeltaOperation::insert("56"), DeltaOperation::insert("78")]
     );
 
     // assert_eq!(
@@ -148,40 +148,40 @@ fn delta_get_ops_in_interval_5() {
 
 #[test]
 fn delta_get_ops_in_interval_6() {
-    let mut delta = TextDelta::default();
-    let insert_a = Operation::insert("12345678");
+    let mut delta = TextOperations::default();
+    let insert_a = DeltaOperation::insert("12345678");
     delta.add(insert_a.clone());
     assert_eq!(
         OperationIterator::from_interval(&delta, Interval::new(4, 6)).ops(),
-        vec![Operation::insert("56")]
+        vec![DeltaOperation::insert("56")]
     );
 }
 
 #[test]
 fn delta_get_ops_in_interval_7() {
-    let mut delta = TextDelta::default();
-    let insert_a = Operation::insert("12345");
-    let retain_a = Operation::retain(3);
+    let mut delta = TextOperations::default();
+    let insert_a = DeltaOperation::insert("12345");
+    let retain_a = DeltaOperation::retain(3);
 
     delta.add(insert_a.clone());
     delta.add(retain_a.clone());
 
     let mut iter_1 = OperationIterator::from_offset(&delta, 2);
-    assert_eq!(iter_1.next_op().unwrap(), Operation::insert("345"));
-    assert_eq!(iter_1.next_op().unwrap(), Operation::retain(3));
+    assert_eq!(iter_1.next_op().unwrap(), DeltaOperation::insert("345"));
+    assert_eq!(iter_1.next_op().unwrap(), DeltaOperation::retain(3));
 
     let mut iter_2 = OperationIterator::new(&delta);
-    assert_eq!(iter_2.next_op_with_len(2).unwrap(), Operation::insert("12"));
-    assert_eq!(iter_2.next_op().unwrap(), Operation::insert("345"));
+    assert_eq!(iter_2.next_op_with_len(2).unwrap(), DeltaOperation::insert("12"));
+    assert_eq!(iter_2.next_op().unwrap(), DeltaOperation::insert("345"));
 
-    assert_eq!(iter_2.next_op().unwrap(), Operation::retain(3));
+    assert_eq!(iter_2.next_op().unwrap(), DeltaOperation::retain(3));
 }
 
 #[test]
 fn delta_op_seek() {
-    let mut delta = TextDelta::default();
-    let insert_a = Operation::insert("12345");
-    let retain_a = Operation::retain(3);
+    let mut delta = TextOperations::default();
+    let insert_a = DeltaOperation::insert("12345");
+    let retain_a = DeltaOperation::retain(3);
     delta.add(insert_a.clone());
     delta.add(retain_a.clone());
     let mut iter = OperationIterator::new(&delta);
@@ -191,92 +191,92 @@ fn delta_op_seek() {
 
 #[test]
 fn delta_utf16_code_unit_seek() {
-    let mut delta = TextDelta::default();
-    delta.add(Operation::insert("12345"));
+    let mut delta = TextOperations::default();
+    delta.add(DeltaOperation::insert("12345"));
 
     let mut iter = OperationIterator::new(&delta);
     iter.seek::<Utf16CodeUnitMetric>(3);
-    assert_eq!(iter.next_op_with_len(2).unwrap(), Operation::insert("45"));
+    assert_eq!(iter.next_op_with_len(2).unwrap(), DeltaOperation::insert("45"));
 }
 
 #[test]
 fn delta_utf16_code_unit_seek_with_attributes() {
-    let mut delta = TextDelta::default();
+    let mut delta = TextOperations::default();
     let attributes = AttributeBuilder::new()
         .insert("bold", true)
         .insert("italic", true)
         .build();
 
-    delta.add(Operation::insert_with_attributes("1234", attributes.clone()));
-    delta.add(Operation::insert("\n"));
+    delta.add(DeltaOperation::insert_with_attributes("1234", attributes.clone()));
+    delta.add(DeltaOperation::insert("\n"));
 
     let mut iter = OperationIterator::new(&delta);
     iter.seek::<Utf16CodeUnitMetric>(0);
 
     assert_eq!(
         iter.next_op_with_len(4).unwrap(),
-        Operation::insert_with_attributes("1234", attributes),
+        DeltaOperation::insert_with_attributes("1234", attributes),
     );
 }
 
 #[test]
 fn delta_next_op_len() {
-    let mut delta = TextDelta::default();
-    delta.add(Operation::insert("12345"));
+    let mut delta = TextOperations::default();
+    delta.add(DeltaOperation::insert("12345"));
     let mut iter = OperationIterator::new(&delta);
-    assert_eq!(iter.next_op_with_len(2).unwrap(), Operation::insert("12"));
-    assert_eq!(iter.next_op_with_len(2).unwrap(), Operation::insert("34"));
-    assert_eq!(iter.next_op_with_len(2).unwrap(), Operation::insert("5"));
+    assert_eq!(iter.next_op_with_len(2).unwrap(), DeltaOperation::insert("12"));
+    assert_eq!(iter.next_op_with_len(2).unwrap(), DeltaOperation::insert("34"));
+    assert_eq!(iter.next_op_with_len(2).unwrap(), DeltaOperation::insert("5"));
     assert_eq!(iter.next_op_with_len(1), None);
 }
 
 #[test]
 fn delta_next_op_len_with_chinese() {
-    let mut delta = TextDelta::default();
-    delta.add(Operation::insert("你好"));
+    let mut delta = TextOperations::default();
+    delta.add(DeltaOperation::insert("你好"));
 
     let mut iter = OperationIterator::new(&delta);
     assert_eq!(iter.next_op_len().unwrap(), 2);
-    assert_eq!(iter.next_op_with_len(2).unwrap(), Operation::insert("你好"));
+    assert_eq!(iter.next_op_with_len(2).unwrap(), DeltaOperation::insert("你好"));
 }
 
 #[test]
 fn delta_next_op_len_with_english() {
-    let mut delta = TextDelta::default();
-    delta.add(Operation::insert("ab"));
+    let mut delta = TextOperations::default();
+    delta.add(DeltaOperation::insert("ab"));
     let mut iter = OperationIterator::new(&delta);
     assert_eq!(iter.next_op_len().unwrap(), 2);
-    assert_eq!(iter.next_op_with_len(2).unwrap(), Operation::insert("ab"));
+    assert_eq!(iter.next_op_with_len(2).unwrap(), DeltaOperation::insert("ab"));
 }
 
 #[test]
 fn delta_next_op_len_after_seek() {
-    let mut delta = TextDelta::default();
-    delta.add(Operation::insert("12345"));
+    let mut delta = TextOperations::default();
+    delta.add(DeltaOperation::insert("12345"));
     let mut iter = OperationIterator::new(&delta);
     assert_eq!(iter.next_op_len().unwrap(), 5);
     iter.seek::<Utf16CodeUnitMetric>(3);
     assert_eq!(iter.next_op_len().unwrap(), 2);
-    assert_eq!(iter.next_op_with_len(1).unwrap(), Operation::insert("4"));
+    assert_eq!(iter.next_op_with_len(1).unwrap(), DeltaOperation::insert("4"));
     assert_eq!(iter.next_op_len().unwrap(), 1);
-    assert_eq!(iter.next_op().unwrap(), Operation::insert("5"));
+    assert_eq!(iter.next_op().unwrap(), DeltaOperation::insert("5"));
 }
 
 #[test]
 fn delta_next_op_len_none() {
-    let mut delta = TextDelta::default();
-    delta.add(Operation::insert("12345"));
+    let mut delta = TextOperations::default();
+    delta.add(DeltaOperation::insert("12345"));
     let mut iter = OperationIterator::new(&delta);
 
     assert_eq!(iter.next_op_len().unwrap(), 5);
-    assert_eq!(iter.next_op_with_len(5).unwrap(), Operation::insert("12345"));
+    assert_eq!(iter.next_op_with_len(5).unwrap(), DeltaOperation::insert("12345"));
     assert_eq!(iter.next_op_len(), None);
 }
 
 #[test]
 fn delta_next_op_with_len_zero() {
-    let mut delta = TextDelta::default();
-    delta.add(Operation::insert("12345"));
+    let mut delta = TextOperations::default();
+    delta.add(DeltaOperation::insert("12345"));
     let mut iter = OperationIterator::new(&delta);
     assert_eq!(iter.next_op_with_len(0), None,);
     assert_eq!(iter.next_op_len().unwrap(), 5);
@@ -284,29 +284,29 @@ fn delta_next_op_with_len_zero() {
 
 #[test]
 fn delta_next_op_with_len_cross_op_return_last() {
-    let mut delta = TextDelta::default();
-    delta.add(Operation::insert("12345"));
-    delta.add(Operation::retain(1));
-    delta.add(Operation::insert("678"));
+    let mut delta = TextOperations::default();
+    delta.add(DeltaOperation::insert("12345"));
+    delta.add(DeltaOperation::retain(1));
+    delta.add(DeltaOperation::insert("678"));
 
     let mut iter = OperationIterator::new(&delta);
     iter.seek::<Utf16CodeUnitMetric>(4);
     assert_eq!(iter.next_op_len().unwrap(), 1);
-    assert_eq!(iter.next_op_with_len(2).unwrap(), Operation::retain(1));
+    assert_eq!(iter.next_op_with_len(2).unwrap(), DeltaOperation::retain(1));
 }
 
 #[test]
 fn lengths() {
-    let mut delta = TextDelta::default();
+    let mut delta = TextOperations::default();
     assert_eq!(delta.utf16_base_len, 0);
     assert_eq!(delta.utf16_target_len, 0);
-    delta.retain(5, Attributes::default());
+    delta.retain(5, AttributeHashMap::default());
     assert_eq!(delta.utf16_base_len, 5);
     assert_eq!(delta.utf16_target_len, 5);
-    delta.insert("abc", Attributes::default());
+    delta.insert("abc", AttributeHashMap::default());
     assert_eq!(delta.utf16_base_len, 5);
     assert_eq!(delta.utf16_target_len, 8);
-    delta.retain(2, Attributes::default());
+    delta.retain(2, AttributeHashMap::default());
     assert_eq!(delta.utf16_base_len, 7);
     assert_eq!(delta.utf16_target_len, 10);
     delta.delete(2);
@@ -315,11 +315,11 @@ fn lengths() {
 }
 #[test]
 fn sequence() {
-    let mut delta = TextDelta::default();
-    delta.retain(5, Attributes::default());
-    delta.retain(0, Attributes::default());
-    delta.insert("appflowy", Attributes::default());
-    delta.insert("", Attributes::default());
+    let mut delta = TextOperations::default();
+    delta.retain(5, AttributeHashMap::default());
+    delta.retain(0, AttributeHashMap::default());
+    delta.insert("appflowy", AttributeHashMap::default());
+    delta.insert("", AttributeHashMap::default());
     delta.delete(3);
     delta.delete(0);
     assert_eq!(delta.ops.len(), 3);
@@ -348,16 +348,16 @@ fn apply_test() {
 
 #[test]
 fn base_len_test() {
-    let mut delta_a = TextDelta::default();
-    delta_a.insert("a", Attributes::default());
-    delta_a.insert("b", Attributes::default());
-    delta_a.insert("c", Attributes::default());
+    let mut delta_a = TextOperations::default();
+    delta_a.insert("a", AttributeHashMap::default());
+    delta_a.insert("b", AttributeHashMap::default());
+    delta_a.insert("c", AttributeHashMap::default());
 
     let s = "hello world,".to_owned();
     delta_a.delete(s.len());
     let after_a = delta_a.apply(&s).unwrap();
 
-    delta_a.insert("d", Attributes::default());
+    delta_a.insert("d", AttributeHashMap::default());
     assert_eq!("abc", &after_a);
 }
 
@@ -387,62 +387,62 @@ fn invert_test() {
 
 #[test]
 fn empty_ops() {
-    let mut delta = TextDelta::default();
-    delta.retain(0, Attributes::default());
-    delta.insert("", Attributes::default());
+    let mut delta = TextOperations::default();
+    delta.retain(0, AttributeHashMap::default());
+    delta.insert("", AttributeHashMap::default());
     delta.delete(0);
     assert_eq!(delta.ops.len(), 0);
 }
 #[test]
 fn eq() {
-    let mut delta_a = TextDelta::default();
+    let mut delta_a = TextOperations::default();
     delta_a.delete(1);
-    delta_a.insert("lo", Attributes::default());
-    delta_a.retain(2, Attributes::default());
-    delta_a.retain(3, Attributes::default());
-    let mut delta_b = TextDelta::default();
+    delta_a.insert("lo", AttributeHashMap::default());
+    delta_a.retain(2, AttributeHashMap::default());
+    delta_a.retain(3, AttributeHashMap::default());
+    let mut delta_b = TextOperations::default();
     delta_b.delete(1);
-    delta_b.insert("l", Attributes::default());
-    delta_b.insert("o", Attributes::default());
-    delta_b.retain(5, Attributes::default());
+    delta_b.insert("l", AttributeHashMap::default());
+    delta_b.insert("o", AttributeHashMap::default());
+    delta_b.retain(5, AttributeHashMap::default());
     assert_eq!(delta_a, delta_b);
     delta_a.delete(1);
-    delta_b.retain(1, Attributes::default());
+    delta_b.retain(1, AttributeHashMap::default());
     assert_ne!(delta_a, delta_b);
 }
 #[test]
 fn ops_merging() {
-    let mut delta = TextDelta::default();
+    let mut delta = TextOperations::default();
     assert_eq!(delta.ops.len(), 0);
-    delta.retain(2, Attributes::default());
+    delta.retain(2, AttributeHashMap::default());
     assert_eq!(delta.ops.len(), 1);
-    assert_eq!(delta.ops.last(), Some(&Operation::retain(2)));
-    delta.retain(3, Attributes::default());
+    assert_eq!(delta.ops.last(), Some(&DeltaOperation::retain(2)));
+    delta.retain(3, AttributeHashMap::default());
     assert_eq!(delta.ops.len(), 1);
-    assert_eq!(delta.ops.last(), Some(&Operation::retain(5)));
-    delta.insert("abc", Attributes::default());
+    assert_eq!(delta.ops.last(), Some(&DeltaOperation::retain(5)));
+    delta.insert("abc", AttributeHashMap::default());
     assert_eq!(delta.ops.len(), 2);
-    assert_eq!(delta.ops.last(), Some(&Operation::insert("abc")));
-    delta.insert("xyz", Attributes::default());
+    assert_eq!(delta.ops.last(), Some(&DeltaOperation::insert("abc")));
+    delta.insert("xyz", AttributeHashMap::default());
     assert_eq!(delta.ops.len(), 2);
-    assert_eq!(delta.ops.last(), Some(&Operation::insert("abcxyz")));
+    assert_eq!(delta.ops.last(), Some(&DeltaOperation::insert("abcxyz")));
     delta.delete(1);
     assert_eq!(delta.ops.len(), 3);
-    assert_eq!(delta.ops.last(), Some(&Operation::delete(1)));
+    assert_eq!(delta.ops.last(), Some(&DeltaOperation::delete(1)));
     delta.delete(1);
     assert_eq!(delta.ops.len(), 3);
-    assert_eq!(delta.ops.last(), Some(&Operation::delete(2)));
+    assert_eq!(delta.ops.last(), Some(&DeltaOperation::delete(2)));
 }
 
 #[test]
 fn is_noop() {
-    let mut delta = TextDelta::default();
+    let mut delta = TextOperations::default();
     assert!(delta.is_noop());
-    delta.retain(5, Attributes::default());
+    delta.retain(5, AttributeHashMap::default());
     assert!(delta.is_noop());
-    delta.retain(3, Attributes::default());
+    delta.retain(3, AttributeHashMap::default());
     assert!(delta.is_noop());
-    delta.insert("lorem", Attributes::default());
+    delta.insert("lorem", AttributeHashMap::default());
     assert!(!delta.is_noop());
 }
 #[test]
@@ -484,15 +484,15 @@ fn transform_random_delta() {
 
 #[test]
 fn transform_with_two_delta() {
-    let mut a = TextDelta::default();
+    let mut a = TextOperations::default();
     let mut a_s = String::new();
     a.insert("123", AttributeBuilder::new().insert("bold", true).build());
     a_s = a.apply(&a_s).unwrap();
     assert_eq!(&a_s, "123");
 
-    let mut b = TextDelta::default();
+    let mut b = TextOperations::default();
     let mut b_s = String::new();
-    b.insert("456", Attributes::default());
+    b.insert("456", AttributeHashMap::default());
     b_s = b.apply(&b_s).unwrap();
     assert_eq!(&b_s, "456");
 
@@ -580,12 +580,12 @@ fn transform_two_conflict_non_seq_delta() {
 
 #[test]
 fn delta_invert_no_attribute_delta() {
-    let mut delta = TextDelta::default();
-    delta.add(Operation::insert("123"));
+    let mut delta = TextOperations::default();
+    delta.add(DeltaOperation::insert("123"));
 
-    let mut change = TextDelta::default();
-    change.add(Operation::retain(3));
-    change.add(Operation::insert("456"));
+    let mut change = TextOperations::default();
+    change.add(DeltaOperation::retain(3));
+    change.add(DeltaOperation::insert("456"));
     let undo = change.invert(&delta);
 
     let new_delta = delta.compose(&change).unwrap();

+ 11 - 11
frontend/rust-lib/flowy-text-block/tests/editor/serde_test.rs

@@ -2,7 +2,7 @@ use flowy_sync::client_document::{ClientDocument, EmptyDoc};
 use lib_ot::text_delta::TextOperation;
 use lib_ot::{
     core::*,
-    text_delta::{BuildInTextAttribute, TextDelta},
+    text_delta::{BuildInTextAttribute, TextOperations},
 };
 
 #[test]
@@ -11,7 +11,7 @@ fn operation_insert_serialize_test() {
         .insert("bold", true)
         .insert("italic", true)
         .build();
-    let operation = Operation::insert_with_attributes("123", attributes);
+    let operation = DeltaOperation::insert_with_attributes("123", attributes);
     let json = serde_json::to_string(&operation).unwrap();
     eprintln!("{}", json);
 
@@ -21,7 +21,7 @@ fn operation_insert_serialize_test() {
 
 #[test]
 fn operation_retain_serialize_test() {
-    let operation = Operation::Retain(12.into());
+    let operation = DeltaOperation::Retain(12.into());
     let json = serde_json::to_string(&operation).unwrap();
     eprintln!("{}", json);
     let insert_op: TextOperation = serde_json::from_str(&json).unwrap();
@@ -42,7 +42,7 @@ fn attributes_serialize_test() {
         .insert_entry(BuildInTextAttribute::Bold(true))
         .insert_entry(BuildInTextAttribute::Italic(true))
         .build();
-    let retain = Operation::insert_with_attributes("123", attributes);
+    let retain = DeltaOperation::insert_with_attributes("123", attributes);
 
     let json = serde_json::to_string(&retain).unwrap();
     eprintln!("{}", json);
@@ -50,22 +50,22 @@ fn attributes_serialize_test() {
 
 #[test]
 fn delta_serialize_multi_attribute_test() {
-    let mut delta = Operations::default();
+    let mut delta = DeltaOperations::default();
 
     let attributes = AttributeBuilder::new()
         .insert_entry(BuildInTextAttribute::Bold(true))
         .insert_entry(BuildInTextAttribute::Italic(true))
         .build();
-    let retain = Operation::insert_with_attributes("123", attributes);
+    let retain = DeltaOperation::insert_with_attributes("123", attributes);
 
     delta.add(retain);
-    delta.add(Operation::Retain(5.into()));
-    delta.add(Operation::Delete(3));
+    delta.add(DeltaOperation::Retain(5.into()));
+    delta.add(DeltaOperation::Delete(3));
 
     let json = serde_json::to_string(&delta).unwrap();
     eprintln!("{}", json);
 
-    let delta_from_json = Operations::from_json(&json).unwrap();
+    let delta_from_json = DeltaOperations::from_json(&json).unwrap();
     assert_eq!(delta_from_json, delta);
 }
 
@@ -77,7 +77,7 @@ fn delta_deserialize_test() {
         {"retain":2,"attributes":{"italic":true,"bold":true}},
         {"retain":2,"attributes":{"italic":true,"bold":true}}
      ]"#;
-    let delta = TextDelta::from_json(json).unwrap();
+    let delta = TextOperations::from_json(json).unwrap();
     eprintln!("{}", delta);
 }
 
@@ -86,7 +86,7 @@ fn delta_deserialize_null_test() {
     let json = r#"[
         {"retain":7,"attributes":{"bold":null}}
      ]"#;
-    let delta1 = TextDelta::from_json(json).unwrap();
+    let delta1 = TextOperations::from_json(json).unwrap();
 
     let mut attribute = BuildInTextAttribute::Bold(true);
     attribute.remove_value();

+ 4 - 4
shared-lib/flowy-sync/src/client_document/default/mod.rs

@@ -1,7 +1,7 @@
-use lib_ot::{core::OperationBuilder, text_delta::TextDelta};
+use lib_ot::{core::OperationBuilder, text_delta::TextOperations};
 
 #[inline]
-pub fn initial_quill_delta() -> TextDelta {
+pub fn initial_quill_delta() -> TextOperations {
     OperationBuilder::new().insert("\n").build()
 }
 
@@ -11,9 +11,9 @@ pub fn initial_quill_delta_string() -> String {
 }
 
 #[inline]
-pub fn initial_read_me() -> TextDelta {
+pub fn initial_read_me() -> TextOperations {
     let json = include_str!("READ_ME.json");
-    TextDelta::from_json(json).unwrap()
+    TextOperations::from_json(json).unwrap()
 }
 
 #[cfg(test)]

+ 22 - 18
shared-lib/flowy-sync/src/client_document/document_pad.rs

@@ -7,29 +7,29 @@ use crate::{
     errors::CollaborateError,
 };
 use bytes::Bytes;
-use lib_ot::{core::*, text_delta::TextDelta};
+use lib_ot::{core::*, text_delta::TextOperations};
 use tokio::sync::mpsc;
 
 pub trait InitialDocumentText {
-    fn initial_delta() -> TextDelta;
+    fn initial_delta() -> TextOperations;
 }
 
 pub struct EmptyDoc();
 impl InitialDocumentText for EmptyDoc {
-    fn initial_delta() -> TextDelta {
-        TextDelta::new()
+    fn initial_delta() -> TextOperations {
+        TextOperations::new()
     }
 }
 
 pub struct NewlineDoc();
 impl InitialDocumentText for NewlineDoc {
-    fn initial_delta() -> TextDelta {
+    fn initial_delta() -> TextOperations {
         initial_quill_delta()
     }
 }
 
 pub struct ClientDocument {
-    delta: TextDelta,
+    delta: TextOperations,
     history: History,
     view: ViewExtensions,
     last_edit_time: usize,
@@ -41,7 +41,7 @@ impl ClientDocument {
         Self::from_delta(C::initial_delta())
     }
 
-    pub fn from_delta(delta: TextDelta) -> Self {
+    pub fn from_delta(delta: TextOperations) -> Self {
         ClientDocument {
             delta,
             history: History::new(),
@@ -52,7 +52,7 @@ impl ClientDocument {
     }
 
     pub fn from_json(json: &str) -> Result<Self, CollaborateError> {
-        let delta = TextDelta::from_json(json)?;
+        let delta = TextOperations::from_json(json)?;
         Ok(Self::from_delta(delta))
     }
 
@@ -68,7 +68,7 @@ impl ClientDocument {
         self.delta.apply("").unwrap()
     }
 
-    pub fn delta(&self) -> &TextDelta {
+    pub fn delta(&self) -> &TextOperations {
         &self.delta
     }
 
@@ -81,7 +81,7 @@ impl ClientDocument {
         self.notify = Some(notify);
     }
 
-    pub fn set_delta(&mut self, data: TextDelta) {
+    pub fn set_delta(&mut self, data: TextOperations) {
         tracing::trace!("document: {}", data.json_str());
         self.delta = data;
 
@@ -93,7 +93,7 @@ impl ClientDocument {
         }
     }
 
-    pub fn compose_delta(&mut self, delta: TextDelta) -> Result<(), CollaborateError> {
+    pub fn compose_delta(&mut self, delta: TextOperations) -> Result<(), CollaborateError> {
         tracing::trace!("{} compose {}", &self.delta.json_str(), delta.json_str());
         let composed_delta = self.delta.compose(&delta)?;
         let mut undo_delta = delta.invert(&self.delta);
@@ -119,7 +119,7 @@ impl ClientDocument {
         Ok(())
     }
 
-    pub fn insert<T: ToString>(&mut self, index: usize, data: T) -> Result<TextDelta, CollaborateError> {
+    pub fn insert<T: ToString>(&mut self, index: usize, data: T) -> Result<TextOperations, CollaborateError> {
         let text = data.to_string();
         let interval = Interval::new(index, index);
         let _ = validate_interval(&self.delta, &interval)?;
@@ -128,7 +128,7 @@ impl ClientDocument {
         Ok(delta)
     }
 
-    pub fn delete(&mut self, interval: Interval) -> Result<TextDelta, CollaborateError> {
+    pub fn delete(&mut self, interval: Interval) -> Result<TextOperations, CollaborateError> {
         let _ = validate_interval(&self.delta, &interval)?;
         debug_assert!(!interval.is_empty());
         let delete = self.view.delete(&self.delta, interval)?;
@@ -138,7 +138,11 @@ impl ClientDocument {
         Ok(delete)
     }
 
-    pub fn format(&mut self, interval: Interval, attribute: AttributeEntry) -> Result<TextDelta, CollaborateError> {
+    pub fn format(
+        &mut self,
+        interval: Interval,
+        attribute: AttributeEntry,
+    ) -> Result<TextOperations, CollaborateError> {
         let _ = validate_interval(&self.delta, &interval)?;
         tracing::trace!("format {} with {:?}", interval, attribute);
         let format_delta = self.view.format(&self.delta, attribute, interval).unwrap();
@@ -146,9 +150,9 @@ impl ClientDocument {
         Ok(format_delta)
     }
 
-    pub fn replace<T: ToString>(&mut self, interval: Interval, data: T) -> Result<TextDelta, CollaborateError> {
+    pub fn replace<T: ToString>(&mut self, interval: Interval, data: T) -> Result<TextOperations, CollaborateError> {
         let _ = validate_interval(&self.delta, &interval)?;
-        let mut delta = TextDelta::default();
+        let mut delta = TextOperations::default();
         let text = data.to_string();
         if !text.is_empty() {
             delta = self.view.insert(&self.delta, &text, interval)?;
@@ -202,7 +206,7 @@ impl ClientDocument {
 }
 
 impl ClientDocument {
-    fn invert(&self, delta: &TextDelta) -> Result<(TextDelta, TextDelta), CollaborateError> {
+    fn invert(&self, delta: &TextOperations) -> Result<(TextOperations, TextOperations), CollaborateError> {
         // c = a.compose(b)
         // d = b.invert(a)
         // a = c.compose(d)
@@ -212,7 +216,7 @@ impl ClientDocument {
     }
 }
 
-fn validate_interval(delta: &TextDelta, interval: &Interval) -> Result<(), CollaborateError> {
+fn validate_interval(delta: &TextOperations, interval: &Interval) -> Result<(), CollaborateError> {
     if delta.utf16_target_len < interval.end {
         log::error!("{:?} out of bounds. should 0..{}", interval, delta.utf16_target_len);
         return Err(CollaborateError::out_of_bound());

+ 2 - 2
shared-lib/flowy-sync/src/client_document/extensions/delete/default_delete.rs

@@ -1,7 +1,7 @@
 use crate::client_document::DeleteExt;
 use lib_ot::{
     core::{Interval, OperationBuilder},
-    text_delta::TextDelta,
+    text_delta::TextOperations,
 };
 
 pub struct DefaultDelete {}
@@ -10,7 +10,7 @@ impl DeleteExt for DefaultDelete {
         "DefaultDelete"
     }
 
-    fn apply(&self, _delta: &TextDelta, interval: Interval) -> Option<TextDelta> {
+    fn apply(&self, _delta: &TextOperations, interval: Interval) -> Option<TextOperations> {
         Some(
             OperationBuilder::new()
                 .retain(interval.start)

+ 3 - 3
shared-lib/flowy-sync/src/client_document/extensions/delete/preserve_line_format_merge.rs

@@ -1,7 +1,7 @@
 use crate::{client_document::DeleteExt, util::is_newline};
 use lib_ot::{
     core::{Interval, OperationAttributes, OperationBuilder, OperationIterator, Utf16CodeUnitMetric, NEW_LINE},
-    text_delta::{empty_attributes, TextDelta},
+    text_delta::{empty_attributes, TextOperations},
 };
 
 pub struct PreserveLineFormatOnMerge {}
@@ -10,7 +10,7 @@ impl DeleteExt for PreserveLineFormatOnMerge {
         "PreserveLineFormatOnMerge"
     }
 
-    fn apply(&self, delta: &TextDelta, interval: Interval) -> Option<TextDelta> {
+    fn apply(&self, delta: &TextOperations, interval: Interval) -> Option<TextOperations> {
         if interval.is_empty() {
             return None;
         }
@@ -45,7 +45,7 @@ impl DeleteExt for PreserveLineFormatOnMerge {
                             attributes.remove_all_value();
 
                             if newline_op.has_attribute() {
-                                attributes.extend_other(newline_op.get_attributes());
+                                attributes.extend(newline_op.get_attributes());
                             }
 
                             new_delta.retain(line_break, empty_attributes());

+ 2 - 2
shared-lib/flowy-sync/src/client_document/extensions/format/resolve_block_format.rs

@@ -2,7 +2,7 @@ use lib_ot::core::AttributeEntry;
 use lib_ot::text_delta::is_block;
 use lib_ot::{
     core::{Interval, OperationBuilder, OperationIterator},
-    text_delta::{empty_attributes, AttributeScope, TextDelta},
+    text_delta::{empty_attributes, AttributeScope, TextOperations},
 };
 
 use crate::{
@@ -16,7 +16,7 @@ impl FormatExt for ResolveBlockFormat {
         "ResolveBlockFormat"
     }
 
-    fn apply(&self, delta: &TextDelta, interval: Interval, attribute: &AttributeEntry) -> Option<TextDelta> {
+    fn apply(&self, delta: &TextOperations, interval: Interval, attribute: &AttributeEntry) -> Option<TextOperations> {
         if !is_block(&attribute.key) {
             return None;
         }

+ 2 - 2
shared-lib/flowy-sync/src/client_document/extensions/format/resolve_inline_format.rs

@@ -2,7 +2,7 @@ use lib_ot::core::AttributeEntry;
 use lib_ot::text_delta::is_inline;
 use lib_ot::{
     core::{Interval, OperationBuilder, OperationIterator},
-    text_delta::{AttributeScope, TextDelta},
+    text_delta::{AttributeScope, TextOperations},
 };
 
 use crate::{
@@ -16,7 +16,7 @@ impl FormatExt for ResolveInlineFormat {
         "ResolveInlineFormat"
     }
 
-    fn apply(&self, delta: &TextDelta, interval: Interval, attribute: &AttributeEntry) -> Option<TextDelta> {
+    fn apply(&self, delta: &TextOperations, interval: Interval, attribute: &AttributeEntry) -> Option<TextOperations> {
         if !is_inline(&attribute.key) {
             return None;
         }

+ 3 - 3
shared-lib/flowy-sync/src/client_document/extensions/helper.rs

@@ -1,9 +1,9 @@
 use crate::util::find_newline;
 use lib_ot::core::AttributeEntry;
-use lib_ot::text_delta::{empty_attributes, AttributeScope, TextDelta, TextOperation};
+use lib_ot::text_delta::{empty_attributes, AttributeScope, TextOperation, TextOperations};
 
-pub(crate) fn line_break(op: &TextOperation, attribute: &AttributeEntry, scope: AttributeScope) -> TextDelta {
-    let mut new_delta = TextDelta::new();
+pub(crate) fn line_break(op: &TextOperation, attribute: &AttributeEntry, scope: AttributeScope) -> TextOperations {
+    let mut new_delta = TextOperations::new();
     let mut start = 0;
     let end = op.len();
     let mut s = op.get_data();

+ 2 - 2
shared-lib/flowy-sync/src/client_document/extensions/insert/auto_exit_block.rs

@@ -1,6 +1,6 @@
 use crate::{client_document::InsertExt, util::is_newline};
 use lib_ot::core::{is_empty_line_at_index, OperationBuilder, OperationIterator};
-use lib_ot::text_delta::{attributes_except_header, BuildInTextAttributeKey, TextDelta};
+use lib_ot::text_delta::{attributes_except_header, BuildInTextAttributeKey, TextOperations};
 
 pub struct AutoExitBlock {}
 
@@ -9,7 +9,7 @@ impl InsertExt for AutoExitBlock {
         "AutoExitBlock"
     }
 
-    fn apply(&self, delta: &TextDelta, replace_len: usize, text: &str, index: usize) -> Option<TextDelta> {
+    fn apply(&self, delta: &TextOperations, replace_len: usize, text: &str, index: usize) -> Option<TextOperations> {
         // Auto exit block will be triggered by enter two new lines
         if !is_newline(text) {
             return None;

+ 4 - 4
shared-lib/flowy-sync/src/client_document/extensions/insert/auto_format.rs

@@ -1,8 +1,8 @@
 use crate::{client_document::InsertExt, util::is_whitespace};
-use lib_ot::core::Attributes;
+use lib_ot::core::AttributeHashMap;
 use lib_ot::{
     core::{count_utf16_code_units, OperationBuilder, OperationIterator},
-    text_delta::{empty_attributes, BuildInTextAttribute, TextDelta},
+    text_delta::{empty_attributes, BuildInTextAttribute, TextOperations},
 };
 use std::cmp::min;
 use url::Url;
@@ -13,7 +13,7 @@ impl InsertExt for AutoFormatExt {
         "AutoFormatExt"
     }
 
-    fn apply(&self, delta: &TextDelta, replace_len: usize, text: &str, index: usize) -> Option<TextDelta> {
+    fn apply(&self, delta: &TextOperations, replace_len: usize, text: &str, index: usize) -> Option<TextOperations> {
         // enter whitespace to trigger auto format
         if !is_whitespace(text) {
             return None;
@@ -61,7 +61,7 @@ pub enum AutoFormatter {
 }
 
 impl AutoFormatter {
-    pub fn to_attributes(&self) -> Attributes {
+    pub fn to_attributes(&self) -> AttributeHashMap {
         match self {
             AutoFormatter::Url(url) => BuildInTextAttribute::Link(url.as_str()).into(),
         }

+ 5 - 5
shared-lib/flowy-sync/src/client_document/extensions/insert/default_insert.rs

@@ -1,8 +1,8 @@
 use crate::client_document::InsertExt;
-use lib_ot::core::Attributes;
+use lib_ot::core::AttributeHashMap;
 use lib_ot::{
     core::{OperationAttributes, OperationBuilder, OperationIterator, NEW_LINE},
-    text_delta::{BuildInTextAttributeKey, TextDelta},
+    text_delta::{BuildInTextAttributeKey, TextOperations},
 };
 
 pub struct DefaultInsertAttribute {}
@@ -11,9 +11,9 @@ impl InsertExt for DefaultInsertAttribute {
         "DefaultInsertAttribute"
     }
 
-    fn apply(&self, delta: &TextDelta, replace_len: usize, text: &str, index: usize) -> Option<TextDelta> {
+    fn apply(&self, delta: &TextOperations, replace_len: usize, text: &str, index: usize) -> Option<TextOperations> {
         let iter = OperationIterator::new(delta);
-        let mut attributes = Attributes::new();
+        let mut attributes = AttributeHashMap::new();
 
         // Enable each line split by "\n" remains the block attributes. for example:
         // insert "\n" to "123456" at index 3
@@ -28,7 +28,7 @@ impl InsertExt for DefaultInsertAttribute {
                         .get_attributes()
                         .contains_key(BuildInTextAttributeKey::Header.as_ref())
                     {
-                        attributes.extend_other(op.get_attributes());
+                        attributes.extend(op.get_attributes());
                     }
                 }
             }

+ 15 - 3
shared-lib/flowy-sync/src/client_document/extensions/insert/mod.rs

@@ -2,7 +2,7 @@ use crate::client_document::InsertExt;
 pub use auto_exit_block::*;
 pub use auto_format::*;
 pub use default_insert::*;
-use lib_ot::text_delta::TextDelta;
+use lib_ot::text_delta::TextOperations;
 pub use preserve_block_format::*;
 pub use preserve_inline_format::*;
 pub use reset_format_on_new_line::*;
@@ -20,7 +20,13 @@ impl InsertExt for InsertEmbedsExt {
         "InsertEmbedsExt"
     }
 
-    fn apply(&self, _delta: &TextDelta, _replace_len: usize, _text: &str, _index: usize) -> Option<TextDelta> {
+    fn apply(
+        &self,
+        _delta: &TextOperations,
+        _replace_len: usize,
+        _text: &str,
+        _index: usize,
+    ) -> Option<TextOperations> {
         None
     }
 }
@@ -31,7 +37,13 @@ impl InsertExt for ForceNewlineForInsertsAroundEmbedExt {
         "ForceNewlineForInsertsAroundEmbedExt"
     }
 
-    fn apply(&self, _delta: &TextDelta, _replace_len: usize, _text: &str, _index: usize) -> Option<TextDelta> {
+    fn apply(
+        &self,
+        _delta: &TextOperations,
+        _replace_len: usize,
+        _text: &str,
+        _index: usize,
+    ) -> Option<TextOperations> {
         None
     }
 }

+ 4 - 4
shared-lib/flowy-sync/src/client_document/extensions/insert/preserve_block_format.rs

@@ -1,8 +1,8 @@
 use crate::{client_document::InsertExt, util::is_newline};
-use lib_ot::core::Attributes;
+use lib_ot::core::AttributeHashMap;
 use lib_ot::{
     core::{OperationBuilder, OperationIterator, NEW_LINE},
-    text_delta::{attributes_except_header, empty_attributes, BuildInTextAttributeKey, TextDelta},
+    text_delta::{attributes_except_header, empty_attributes, BuildInTextAttributeKey, TextOperations},
 };
 
 pub struct PreserveBlockFormatOnInsert {}
@@ -11,7 +11,7 @@ impl InsertExt for PreserveBlockFormatOnInsert {
         "PreserveBlockFormatOnInsert"
     }
 
-    fn apply(&self, delta: &TextDelta, replace_len: usize, text: &str, index: usize) -> Option<TextDelta> {
+    fn apply(&self, delta: &TextOperations, replace_len: usize, text: &str, index: usize) -> Option<TextOperations> {
         if !is_newline(text) {
             return None;
         }
@@ -26,7 +26,7 @@ impl InsertExt for PreserveBlockFormatOnInsert {
                     return None;
                 }
 
-                let mut reset_attribute = Attributes::new();
+                let mut reset_attribute = AttributeHashMap::new();
                 if newline_attributes.contains_key(BuildInTextAttributeKey::Header.as_ref()) {
                     reset_attribute.insert(BuildInTextAttributeKey::Header, 1);
                 }

+ 4 - 4
shared-lib/flowy-sync/src/client_document/extensions/insert/preserve_inline_format.rs

@@ -4,7 +4,7 @@ use crate::{
 };
 use lib_ot::{
     core::{OpNewline, OperationBuilder, OperationIterator, NEW_LINE},
-    text_delta::{empty_attributes, BuildInTextAttributeKey, TextDelta},
+    text_delta::{empty_attributes, BuildInTextAttributeKey, TextOperations},
 };
 
 pub struct PreserveInlineFormat {}
@@ -13,7 +13,7 @@ impl InsertExt for PreserveInlineFormat {
         "PreserveInlineFormat"
     }
 
-    fn apply(&self, delta: &TextDelta, replace_len: usize, text: &str, index: usize) -> Option<TextDelta> {
+    fn apply(&self, delta: &TextOperations, replace_len: usize, text: &str, index: usize) -> Option<TextOperations> {
         if contain_newline(text) {
             return None;
         }
@@ -59,7 +59,7 @@ impl InsertExt for PreserveLineFormatOnSplit {
         "PreserveLineFormatOnSplit"
     }
 
-    fn apply(&self, delta: &TextDelta, replace_len: usize, text: &str, index: usize) -> Option<TextDelta> {
+    fn apply(&self, delta: &TextOperations, replace_len: usize, text: &str, index: usize) -> Option<TextOperations> {
         if !is_newline(text) {
             return None;
         }
@@ -76,7 +76,7 @@ impl InsertExt for PreserveLineFormatOnSplit {
             return None;
         }
 
-        let mut new_delta = TextDelta::new();
+        let mut new_delta = TextOperations::new();
         new_delta.retain(index + replace_len, empty_attributes());
 
         if newline_status.is_contain() {

+ 4 - 4
shared-lib/flowy-sync/src/client_document/extensions/insert/reset_format_on_new_line.rs

@@ -1,8 +1,8 @@
 use crate::{client_document::InsertExt, util::is_newline};
-use lib_ot::core::Attributes;
+use lib_ot::core::AttributeHashMap;
 use lib_ot::{
     core::{OperationBuilder, OperationIterator, Utf16CodeUnitMetric, NEW_LINE},
-    text_delta::{BuildInTextAttributeKey, TextDelta},
+    text_delta::{BuildInTextAttributeKey, TextOperations},
 };
 
 pub struct ResetLineFormatOnNewLine {}
@@ -11,7 +11,7 @@ impl InsertExt for ResetLineFormatOnNewLine {
         "ResetLineFormatOnNewLine"
     }
 
-    fn apply(&self, delta: &TextDelta, replace_len: usize, text: &str, index: usize) -> Option<TextDelta> {
+    fn apply(&self, delta: &TextOperations, replace_len: usize, text: &str, index: usize) -> Option<TextOperations> {
         if !is_newline(text) {
             return None;
         }
@@ -23,7 +23,7 @@ impl InsertExt for ResetLineFormatOnNewLine {
             return None;
         }
 
-        let mut reset_attribute = Attributes::new();
+        let mut reset_attribute = AttributeHashMap::new();
         if next_op
             .get_attributes()
             .contains_key(BuildInTextAttributeKey::Header.as_ref())

+ 4 - 4
shared-lib/flowy-sync/src/client_document/extensions/mod.rs

@@ -2,7 +2,7 @@ pub use delete::*;
 pub use format::*;
 pub use insert::*;
 use lib_ot::core::AttributeEntry;
-use lib_ot::{core::Interval, text_delta::TextDelta};
+use lib_ot::{core::Interval, text_delta::TextOperations};
 
 mod delete;
 mod format;
@@ -15,15 +15,15 @@ pub type DeleteExtension = Box<dyn DeleteExt + Send + Sync>;
 
 pub trait InsertExt {
     fn ext_name(&self) -> &str;
-    fn apply(&self, delta: &TextDelta, replace_len: usize, text: &str, index: usize) -> Option<TextDelta>;
+    fn apply(&self, delta: &TextOperations, replace_len: usize, text: &str, index: usize) -> Option<TextOperations>;
 }
 
 pub trait FormatExt {
     fn ext_name(&self) -> &str;
-    fn apply(&self, delta: &TextDelta, interval: Interval, attribute: &AttributeEntry) -> Option<TextDelta>;
+    fn apply(&self, delta: &TextOperations, interval: Interval, attribute: &AttributeEntry) -> Option<TextOperations>;
 }
 
 pub trait DeleteExt {
     fn ext_name(&self) -> &str;
-    fn apply(&self, delta: &TextDelta, interval: Interval) -> Option<TextDelta>;
+    fn apply(&self, delta: &TextOperations, interval: Interval) -> Option<TextOperations>;
 }

+ 9 - 9
shared-lib/flowy-sync/src/client_document/history.rs

@@ -1,18 +1,18 @@
-use lib_ot::text_delta::TextDelta;
+use lib_ot::text_delta::TextOperations;
 
 const MAX_UNDOES: usize = 20;
 
 #[derive(Debug, Clone)]
 pub struct UndoResult {
-    pub delta: TextDelta,
+    pub delta: TextOperations,
 }
 
 #[derive(Debug, Clone)]
 pub struct History {
     #[allow(dead_code)]
     cur_undo: usize,
-    undoes: Vec<TextDelta>,
-    redoes: Vec<TextDelta>,
+    undoes: Vec<TextOperations>,
+    redoes: Vec<TextOperations>,
     capacity: usize,
 }
 
@@ -40,15 +40,15 @@ impl History {
         !self.redoes.is_empty()
     }
 
-    pub fn add_undo(&mut self, delta: TextDelta) {
+    pub fn add_undo(&mut self, delta: TextOperations) {
         self.undoes.push(delta);
     }
 
-    pub fn add_redo(&mut self, delta: TextDelta) {
+    pub fn add_redo(&mut self, delta: TextOperations) {
         self.redoes.push(delta);
     }
 
-    pub fn record(&mut self, delta: TextDelta) {
+    pub fn record(&mut self, delta: TextOperations) {
         if delta.ops.is_empty() {
             return;
         }
@@ -61,7 +61,7 @@ impl History {
         }
     }
 
-    pub fn undo(&mut self) -> Option<TextDelta> {
+    pub fn undo(&mut self) -> Option<TextOperations> {
         if !self.can_undo() {
             return None;
         }
@@ -69,7 +69,7 @@ impl History {
         Some(delta)
     }
 
-    pub fn redo(&mut self) -> Option<TextDelta> {
+    pub fn redo(&mut self) -> Option<TextOperations> {
         if !self.can_redo() {
             return None;
         }

+ 10 - 5
shared-lib/flowy-sync/src/client_document/view.rs

@@ -3,7 +3,7 @@ use lib_ot::core::AttributeEntry;
 use lib_ot::{
     core::{trim, Interval},
     errors::{ErrorBuilder, OTError, OTErrorCode},
-    text_delta::TextDelta,
+    text_delta::TextOperations,
 };
 
 pub const RECORD_THRESHOLD: usize = 400; // in milliseconds
@@ -23,7 +23,12 @@ impl ViewExtensions {
         }
     }
 
-    pub(crate) fn insert(&self, delta: &TextDelta, text: &str, interval: Interval) -> Result<TextDelta, OTError> {
+    pub(crate) fn insert(
+        &self,
+        delta: &TextOperations,
+        text: &str,
+        interval: Interval,
+    ) -> Result<TextOperations, OTError> {
         let mut new_delta = None;
         for ext in &self.insert_exts {
             if let Some(mut delta) = ext.apply(delta, interval.size(), text, interval.start) {
@@ -40,7 +45,7 @@ impl ViewExtensions {
         }
     }
 
-    pub(crate) fn delete(&self, delta: &TextDelta, interval: Interval) -> Result<TextDelta, OTError> {
+    pub(crate) fn delete(&self, delta: &TextOperations, interval: Interval) -> Result<TextOperations, OTError> {
         let mut new_delta = None;
         for ext in &self.delete_exts {
             if let Some(mut delta) = ext.apply(delta, interval) {
@@ -59,10 +64,10 @@ impl ViewExtensions {
 
     pub(crate) fn format(
         &self,
-        delta: &TextDelta,
+        delta: &TextOperations,
         attribute: AttributeEntry,
         interval: Interval,
-    ) -> Result<TextDelta, OTError> {
+    ) -> Result<TextOperations, OTError> {
         let mut new_delta = None;
         for ext in &self.format_exts {
             if let Some(mut delta) = ext.apply(delta, interval, &attribute) {

+ 2 - 2
shared-lib/flowy-sync/src/client_folder/builder.rs

@@ -1,5 +1,5 @@
 use crate::entities::folder::FolderDelta;
-use crate::util::make_text_delta_from_revisions;
+use crate::util::make_delta_from_revisions;
 use crate::{
     client_folder::{default_folder_delta, FolderPad},
     entities::revision::Revision,
@@ -37,7 +37,7 @@ impl FolderPadBuilder {
     }
 
     pub(crate) fn build_with_revisions(self, revisions: Vec<Revision>) -> CollaborateResult<FolderPad> {
-        let mut folder_delta: FolderDelta = make_text_delta_from_revisions(revisions)?;
+        let mut folder_delta: FolderDelta = make_delta_from_revisions(revisions)?;
         if folder_delta.is_empty() {
             folder_delta = default_folder_delta();
         }

+ 2 - 2
shared-lib/flowy-sync/src/client_grid/block_revision_pad.rs

@@ -1,6 +1,6 @@
 use crate::entities::revision::{md5, RepeatedRevision, Revision};
 use crate::errors::{CollaborateError, CollaborateResult};
-use crate::util::{cal_diff, make_text_delta_from_revisions};
+use crate::util::{cal_diff, make_delta_from_revisions};
 use flowy_grid_data_model::revision::{
     gen_block_id, gen_row_id, CellRevision, GridBlockRevision, RowChangeset, RowRevision,
 };
@@ -53,7 +53,7 @@ impl GridBlockRevisionPad {
     }
 
     pub fn from_revisions(_grid_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
-        let block_delta: Delta = make_text_delta_from_revisions(revisions)?;
+        let block_delta: Delta = make_delta_from_revisions(revisions)?;
         Self::from_delta(block_delta)
     }
 

+ 2 - 2
shared-lib/flowy-sync/src/client_grid/grid_revision_pad.rs

@@ -1,6 +1,6 @@
 use crate::entities::revision::{md5, RepeatedRevision, Revision};
 use crate::errors::{internal_error, CollaborateError, CollaborateResult};
-use crate::util::{cal_diff, make_text_delta_from_revisions};
+use crate::util::{cal_diff, make_delta_from_revisions};
 use bytes::Bytes;
 use flowy_grid_data_model::revision::{
     gen_block_id, gen_grid_id, FieldRevision, FieldTypeRevision, GridBlockMetaRevision, GridBlockMetaRevisionChangeset,
@@ -64,7 +64,7 @@ impl GridRevisionPad {
     }
 
     pub fn from_revisions(revisions: Vec<Revision>) -> CollaborateResult<Self> {
-        let grid_delta: GridRevisionDelta = make_text_delta_from_revisions(revisions)?;
+        let grid_delta: GridRevisionDelta = make_delta_from_revisions(revisions)?;
         Self::from_delta(grid_delta)
     }
 

+ 2 - 2
shared-lib/flowy-sync/src/client_grid/view_revision_pad.rs

@@ -1,6 +1,6 @@
 use crate::entities::revision::{md5, Revision};
 use crate::errors::{internal_error, CollaborateError, CollaborateResult};
-use crate::util::{cal_diff, make_text_delta_from_revisions};
+use crate::util::{cal_diff, make_delta_from_revisions};
 use flowy_grid_data_model::revision::{
     FieldRevision, FieldTypeRevision, FilterConfigurationRevision, FilterConfigurationsByFieldId, GridViewRevision,
     GroupConfigurationRevision, GroupConfigurationsByFieldId,
@@ -49,7 +49,7 @@ impl GridViewRevisionPad {
     }
 
     pub fn from_revisions(view_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
-        let delta: Delta = make_text_delta_from_revisions(revisions)?;
+        let delta: Delta = make_delta_from_revisions(revisions)?;
         Self::from_delta(view_id, delta)
     }
 

+ 13 - 19
shared-lib/flowy-sync/src/entities/revision.rs

@@ -1,8 +1,9 @@
 use bytes::Bytes;
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
-use lib_ot::text_delta::TextDelta;
 use std::{convert::TryFrom, fmt::Formatter, ops::RangeInclusive};
 
+pub type RevisionObject = lib_ot::text_delta::TextOperations;
+
 #[derive(PartialEq, Eq, Clone, Default, ProtoBuf)]
 pub struct Revision {
     #[pb(index = 1)]
@@ -12,7 +13,7 @@ pub struct Revision {
     pub rev_id: i64,
 
     #[pb(index = 3)]
-    pub delta_data: Vec<u8>,
+    pub bytes: Vec<u8>,
 
     #[pb(index = 4)]
     pub md5: String,
@@ -47,22 +48,15 @@ impl Revision {
         self.rev_id == 0
     }
 
-    pub fn initial_revision(user_id: &str, object_id: &str, delta_data: Bytes) -> Self {
-        let md5 = md5(&delta_data);
-        Self::new(object_id, 0, 0, delta_data, user_id, md5)
+    pub fn initial_revision(user_id: &str, object_id: &str, bytes: Bytes) -> Self {
+        let md5 = md5(&bytes);
+        Self::new(object_id, 0, 0, bytes, user_id, md5)
     }
 
-    pub fn new(
-        object_id: &str,
-        base_rev_id: i64,
-        rev_id: i64,
-        delta_data: Bytes,
-        user_id: &str,
-        md5: String,
-    ) -> Revision {
+    pub fn new(object_id: &str, base_rev_id: i64, rev_id: i64, bytes: Bytes, user_id: &str, md5: String) -> Revision {
         let user_id = user_id.to_owned();
         let object_id = object_id.to_owned();
-        let delta_data = delta_data.to_vec();
+        let bytes = bytes.to_vec();
         let base_rev_id = base_rev_id;
         let rev_id = rev_id;
 
@@ -73,7 +67,7 @@ impl Revision {
         Self {
             base_rev_id,
             rev_id,
-            delta_data,
+            bytes,
             md5,
             object_id,
             ty: RevType::DeprecatedLocal,
@@ -87,12 +81,12 @@ impl std::fmt::Debug for Revision {
         let _ = f.write_fmt(format_args!("object_id {}, ", self.object_id))?;
         let _ = f.write_fmt(format_args!("base_rev_id {}, ", self.base_rev_id))?;
         let _ = f.write_fmt(format_args!("rev_id {}, ", self.rev_id))?;
-        match TextDelta::from_bytes(&self.delta_data) {
-            Ok(delta) => {
-                let _ = f.write_fmt(format_args!("delta {:?}", delta.json_str()))?;
+        match RevisionObject::from_bytes(&self.bytes) {
+            Ok(object) => {
+                let _ = f.write_fmt(format_args!("object {:?}", object.json_str()))?;
             }
             Err(e) => {
-                let _ = f.write_fmt(format_args!("delta {:?}", e))?;
+                let _ = f.write_fmt(format_args!("object {:?}", e))?;
             }
         }
         Ok(())

+ 4 - 4
shared-lib/flowy-sync/src/entities/text_block.rs

@@ -3,7 +3,7 @@ use crate::{
     errors::CollaborateError,
 };
 use flowy_derive::ProtoBuf;
-use lib_ot::{errors::OTError, text_delta::TextDelta};
+use lib_ot::{errors::OTError, text_delta::TextOperations};
 
 #[derive(ProtoBuf, Default, Debug, Clone)]
 pub struct CreateTextBlockParams {
@@ -30,8 +30,8 @@ pub struct DocumentPB {
 }
 
 impl DocumentPB {
-    pub fn delta(&self) -> Result<TextDelta, OTError> {
-        let delta = TextDelta::from_bytes(&self.text)?;
+    pub fn delta(&self) -> Result<TextOperations, OTError> {
+        let delta = TextOperations::from_bytes(&self.text)?;
         Ok(delta)
     }
 }
@@ -45,7 +45,7 @@ impl std::convert::TryFrom<Revision> for DocumentPB {
                 .context("Revision's rev_id should be 0 when creating the document"));
         }
 
-        let delta = TextDelta::from_bytes(&revision.delta_data)?;
+        let delta = TextOperations::from_bytes(&revision.bytes)?;
         let doc_json = delta.json_str();
 
         Ok(DocumentPB {

+ 1 - 1
shared-lib/flowy-sync/src/lib.rs

@@ -9,4 +9,4 @@ pub mod server_folder;
 pub mod synchronizer;
 pub mod util;
 
-pub use lib_ot::text_delta::TextDelta;
+pub use lib_ot::text_delta::TextOperations;

+ 4 - 4
shared-lib/flowy-sync/src/server_document/document_manager.rs

@@ -11,8 +11,8 @@ use async_stream::stream;
 use dashmap::DashMap;
 use futures::stream::StreamExt;
 use lib_infra::future::BoxResultFuture;
-use lib_ot::core::Attributes;
-use lib_ot::text_delta::TextDelta;
+use lib_ot::core::AttributeHashMap;
+use lib_ot::text_delta::TextOperations;
 use std::{collections::HashMap, fmt::Debug, sync::Arc};
 use tokio::{
     sync::{mpsc, oneshot, RwLock},
@@ -199,7 +199,7 @@ impl std::ops::Drop for ServerDocumentManager {
     }
 }
 
-type DocumentRevisionSynchronizer = RevisionSynchronizer<Attributes>;
+type DocumentRevisionSynchronizer = RevisionSynchronizer<AttributeHashMap>;
 
 struct OpenDocumentHandler {
     doc_id: String,
@@ -213,7 +213,7 @@ impl OpenDocumentHandler {
         let (sender, receiver) = mpsc::channel(1000);
         let users = DashMap::new();
 
-        let delta = TextDelta::from_bytes(&doc.text)?;
+        let delta = TextOperations::from_bytes(&doc.text)?;
         let sync_object = ServerDocument::from_delta(&doc_id, delta);
         let synchronizer = Arc::new(DocumentRevisionSynchronizer::new(doc.rev_id, sync_object, persistence));
 

+ 14 - 13
shared-lib/flowy-sync/src/server_document/document_pad.rs

@@ -1,9 +1,10 @@
+use crate::synchronizer::RevisionOperations;
 use crate::{client_document::InitialDocumentText, errors::CollaborateError, synchronizer::RevisionSyncObject};
-use lib_ot::{core::*, text_delta::TextDelta};
+use lib_ot::{core::*, text_delta::TextOperations};
 
 pub struct ServerDocument {
     doc_id: String,
-    delta: TextDelta,
+    operations: TextOperations,
 }
 
 impl ServerDocument {
@@ -12,34 +13,34 @@ impl ServerDocument {
         Self::from_delta(doc_id, C::initial_delta())
     }
 
-    pub fn from_delta(doc_id: &str, delta: TextDelta) -> Self {
+    pub fn from_delta(doc_id: &str, operations: TextOperations) -> Self {
         let doc_id = doc_id.to_owned();
-        ServerDocument { doc_id, delta }
+        ServerDocument { doc_id, operations }
     }
 }
 
-impl RevisionSyncObject<Attributes> for ServerDocument {
+impl RevisionSyncObject<AttributeHashMap> for ServerDocument {
     fn id(&self) -> &str {
         &self.doc_id
     }
 
-    fn compose(&mut self, other: &TextDelta) -> Result<(), CollaborateError> {
+    fn compose(&mut self, other: &TextOperations) -> Result<(), CollaborateError> {
         // tracing::trace!("{} compose {}", &self.delta.to_json(), other.to_json());
-        let new_delta = self.delta.compose(other)?;
-        self.delta = new_delta;
+        let operations = self.operations.compose(other)?;
+        self.operations = operations;
         Ok(())
     }
 
-    fn transform(&self, other: &TextDelta) -> Result<(TextDelta, TextDelta), CollaborateError> {
-        let value = self.delta.transform(other)?;
+    fn transform(&self, other: &TextOperations) -> Result<(TextOperations, TextOperations), CollaborateError> {
+        let value = self.operations.transform(other)?;
         Ok(value)
     }
 
     fn to_json(&self) -> String {
-        self.delta.json_str()
+        self.operations.json_str()
     }
 
-    fn set_delta(&mut self, new_delta: Operations<Attributes>) {
-        self.delta = new_delta;
+    fn set_operations(&mut self, operations: RevisionOperations<AttributeHashMap>) {
+        self.operations = operations;
     }
 }

+ 11 - 10
shared-lib/flowy-sync/src/server_folder/folder_pad.rs

@@ -1,16 +1,17 @@
-use crate::{entities::folder::FolderDelta, errors::CollaborateError, synchronizer::RevisionSyncObject};
+use crate::synchronizer::RevisionOperations;
+use crate::{errors::CollaborateError, synchronizer::RevisionSyncObject};
 use lib_ot::core::{Delta, EmptyAttributes, OperationTransform};
 
 pub struct ServerFolder {
     folder_id: String,
-    delta: FolderDelta,
+    operations: Delta,
 }
 
 impl ServerFolder {
-    pub fn from_delta(folder_id: &str, delta: FolderDelta) -> Self {
+    pub fn from_delta(folder_id: &str, operations: Delta) -> Self {
         Self {
             folder_id: folder_id.to_owned(),
-            delta,
+            operations,
         }
     }
 }
@@ -21,21 +22,21 @@ impl RevisionSyncObject<EmptyAttributes> for ServerFolder {
     }
 
     fn compose(&mut self, other: &Delta) -> Result<(), CollaborateError> {
-        let new_delta = self.delta.compose(other)?;
-        self.delta = new_delta;
+        let new_delta = self.operations.compose(other)?;
+        self.operations = new_delta;
         Ok(())
     }
 
     fn transform(&self, other: &Delta) -> Result<(Delta, Delta), CollaborateError> {
-        let value = self.delta.transform(other)?;
+        let value = self.operations.transform(other)?;
         Ok(value)
     }
 
     fn to_json(&self) -> String {
-        self.delta.json_str()
+        self.operations.json_str()
     }
 
-    fn set_delta(&mut self, new_delta: Delta) {
-        self.delta = new_delta;
+    fn set_operations(&mut self, operations: RevisionOperations<EmptyAttributes>) {
+        self.operations = operations;
     }
 }

+ 37 - 29
shared-lib/flowy-sync/src/synchronizer.rs

@@ -9,7 +9,7 @@ use crate::{
     util::*,
 };
 use lib_infra::future::BoxResultFuture;
-use lib_ot::core::{OperationAttributes, Operations};
+use lib_ot::core::{DeltaOperations, OperationAttributes};
 use parking_lot::RwLock;
 use serde::de::DeserializeOwned;
 use std::{
@@ -22,6 +22,8 @@ use std::{
     time::Duration,
 };
 
+pub type RevisionOperations<Attribute> = DeltaOperations<Attribute>;
+
 pub trait RevisionUser: Send + Sync + Debug {
     fn user_id(&self) -> String;
     fn receive(&self, resp: RevisionSyncResponse);
@@ -43,12 +45,15 @@ pub trait RevisionSyncPersistence: Send + Sync + 'static {
     ) -> BoxResultFuture<(), CollaborateError>;
 }
 
-pub trait RevisionSyncObject<T: OperationAttributes>: Send + Sync + 'static {
+pub trait RevisionSyncObject<Attribute: OperationAttributes>: Send + Sync + 'static {
     fn id(&self) -> &str;
-    fn compose(&mut self, other: &Operations<T>) -> Result<(), CollaborateError>;
-    fn transform(&self, other: &Operations<T>) -> Result<(Operations<T>, Operations<T>), CollaborateError>;
+    fn compose(&mut self, other: &RevisionOperations<Attribute>) -> Result<(), CollaborateError>;
+    fn transform(
+        &self,
+        other: &RevisionOperations<Attribute>,
+    ) -> Result<(RevisionOperations<Attribute>, RevisionOperations<Attribute>), CollaborateError>;
     fn to_json(&self) -> String;
-    fn set_delta(&mut self, new_delta: Operations<T>);
+    fn set_operations(&mut self, operations: RevisionOperations<Attribute>);
 }
 
 pub enum RevisionSyncResponse {
@@ -57,20 +62,20 @@ pub enum RevisionSyncResponse {
     Ack(ServerRevisionWSData),
 }
 
-pub struct RevisionSynchronizer<T: OperationAttributes> {
+pub struct RevisionSynchronizer<Attribute: OperationAttributes> {
     object_id: String,
     rev_id: AtomicI64,
-    object: Arc<RwLock<dyn RevisionSyncObject<T>>>,
+    object: Arc<RwLock<dyn RevisionSyncObject<Attribute>>>,
     persistence: Arc<dyn RevisionSyncPersistence>,
 }
 
-impl<T> RevisionSynchronizer<T>
+impl<Attribute> RevisionSynchronizer<Attribute>
 where
-    T: OperationAttributes + DeserializeOwned + serde::Serialize + 'static,
+    Attribute: OperationAttributes + DeserializeOwned + serde::Serialize + 'static,
 {
-    pub fn new<S, P>(rev_id: i64, sync_object: S, persistence: P) -> RevisionSynchronizer<T>
+    pub fn new<S, P>(rev_id: i64, sync_object: S, persistence: P) -> RevisionSynchronizer<Attribute>
     where
-        S: RevisionSyncObject<T>,
+        S: RevisionSyncObject<Attribute>,
         P: RevisionSyncPersistence,
     {
         let object = Arc::new(RwLock::new(sync_object));
@@ -117,7 +122,7 @@ where
                     }
                     let _ = self.persistence.save_revisions(repeated_revision).await?;
                 } else {
-                    // The server delta is outdated, pull the missing revision from the client.
+                    // The server ops is outdated, pull the missing revision from the client.
                     let range = RevisionRange {
                         start: server_rev_id,
                         end: first_revision.rev_id,
@@ -131,9 +136,9 @@ where
                 tracing::trace!("Applied {} revision rev_id is the same as cur_rev_id", self.object_id);
             }
             Ordering::Greater => {
-                // The client delta is outdated. Transform the client revision delta and then
-                // send the prime delta to the client. Client should compose the this prime
-                // delta.
+                // The client ops is outdated. Transform the client revision ops and then
+                // send the prime ops to the client. Client should compose the this prime
+                // ops.
                 let from_rev_id = first_revision.rev_id;
                 let to_rev_id = server_base_rev_id;
                 let _ = self.push_revisions_to_user(user, from_rev_id, to_rev_id).await;
@@ -153,9 +158,9 @@ where
             }
             Ordering::Equal => tracing::trace!("{} is up to date.", object_id),
             Ordering::Greater => {
-                // The client delta is outdated. Transform the client revision delta and then
-                // send the prime delta to the client. Client should compose the this prime
-                // delta.
+                // The client ops is outdated. Transform the client revision ops and then
+                // send the prime ops to the client. Client should compose the this prime
+                // ops.
                 let from_rev_id = client_rev_id;
                 let to_rev_id = server_rev_id;
                 tracing::trace!("Push revisions to user");
@@ -171,9 +176,9 @@ where
         tracing::Span::current().record("object_id", &object_id.as_str());
         let revisions: Vec<Revision> = repeated_revision.clone().into_inner();
         let (_, rev_id) = pair_rev_id_from_revision_pbs(&revisions);
-        let delta = make_delta_from_revision_pb(revisions)?;
+        let operations = make_operations_from_revisions(revisions)?;
         let _ = self.persistence.reset_object(&object_id, repeated_revision).await?;
-        self.object.write().set_delta(delta);
+        self.object.write().set_operations(operations);
         let _ = self.rev_id.fetch_update(SeqCst, SeqCst, |_e| Some(rev_id));
         Ok(())
     }
@@ -183,28 +188,31 @@ where
     }
 
     fn compose_revision(&self, revision: &Revision) -> Result<(), CollaborateError> {
-        let delta = Operations::<T>::from_bytes(&revision.delta_data)?;
-        let _ = self.compose_delta(delta)?;
+        let operations = RevisionOperations::<Attribute>::from_bytes(&revision.bytes)?;
+        let _ = self.compose_operations(operations)?;
         let _ = self.rev_id.fetch_update(SeqCst, SeqCst, |_e| Some(revision.rev_id));
         Ok(())
     }
 
     #[tracing::instrument(level = "debug", skip(self, revision))]
-    fn transform_revision(&self, revision: &RevisionPB) -> Result<(Operations<T>, Operations<T>), CollaborateError> {
-        let cli_delta = Operations::<T>::from_bytes(&revision.delta_data)?;
-        let result = self.object.read().transform(&cli_delta)?;
+    fn transform_revision(
+        &self,
+        revision: &RevisionPB,
+    ) -> Result<(RevisionOperations<Attribute>, RevisionOperations<Attribute>), CollaborateError> {
+        let client_operations = RevisionOperations::<Attribute>::from_bytes(&revision.bytes)?;
+        let result = self.object.read().transform(&client_operations)?;
         Ok(result)
     }
 
-    fn compose_delta(&self, delta: Operations<T>) -> Result<(), CollaborateError> {
-        if delta.is_empty() {
-            log::warn!("Composed delta is empty");
+    fn compose_operations(&self, operations: RevisionOperations<Attribute>) -> Result<(), CollaborateError> {
+        if operations.is_empty() {
+            log::warn!("Composed operations is empty");
         }
 
         match self.object.try_write_for(Duration::from_millis(300)) {
             None => log::error!("Failed to acquire write lock of object"),
             Some(mut write_guard) => {
-                let _ = write_guard.compose(&delta)?;
+                let _ = write_guard.compose(&operations)?;
             }
         }
         Ok(())

+ 17 - 31
shared-lib/flowy-sync/src/util.rs

@@ -9,8 +9,8 @@ use crate::{
 use dissimilar::Chunk;
 use lib_ot::core::{Delta, EmptyAttributes, OTString, OperationAttributes, OperationBuilder};
 use lib_ot::{
-    core::{OperationTransform, Operations, NEW_LINE, WHITESPACE},
-    text_delta::TextDelta,
+    core::{DeltaOperations, OperationTransform, NEW_LINE, WHITESPACE},
+    text_delta::TextOperations,
 };
 use serde::de::DeserializeOwned;
 use std::sync::atomic::{AtomicI64, Ordering::SeqCst};
@@ -62,42 +62,28 @@ impl RevIdCounter {
 }
 
 #[tracing::instrument(level = "trace", skip(revisions), err)]
-pub fn make_delta_from_revisions<T>(revisions: Vec<Revision>) -> CollaborateResult<Operations<T>>
+pub fn make_operations_from_revisions<T>(revisions: Vec<Revision>) -> CollaborateResult<DeltaOperations<T>>
 where
     T: OperationAttributes + DeserializeOwned,
 {
-    let mut delta = Operations::<T>::new();
+    let mut new_operations = DeltaOperations::<T>::new();
     for revision in revisions {
-        if revision.delta_data.is_empty() {
+        if revision.bytes.is_empty() {
             tracing::warn!("revision delta_data is empty");
+            continue;
         }
 
-        let revision_delta = Operations::<T>::from_bytes(revision.delta_data).map_err(|e| {
+        let operations = DeltaOperations::<T>::from_bytes(revision.bytes).map_err(|e| {
             let err_msg = format!("Deserialize remote revision failed: {:?}", e);
             CollaborateError::internal().context(err_msg)
         })?;
-        delta = delta.compose(&revision_delta)?;
+        new_operations = new_operations.compose(&operations)?;
     }
-    Ok(delta)
+    Ok(new_operations)
 }
 
-pub fn make_text_delta_from_revisions(revisions: Vec<Revision>) -> CollaborateResult<Delta> {
-    make_delta_from_revisions::<EmptyAttributes>(revisions)
-}
-
-pub fn make_delta_from_revision_pb<T>(revisions: Vec<Revision>) -> CollaborateResult<Operations<T>>
-where
-    T: OperationAttributes + DeserializeOwned,
-{
-    let mut new_delta = Operations::<T>::new();
-    for revision in revisions {
-        let delta = Operations::<T>::from_bytes(revision.delta_data).map_err(|e| {
-            let err_msg = format!("Deserialize remote revision failed: {:?}", e);
-            CollaborateError::internal().context(err_msg)
-        })?;
-        new_delta = new_delta.compose(&delta)?;
-    }
-    Ok(new_delta)
+pub fn make_delta_from_revisions(revisions: Vec<Revision>) -> CollaborateResult<Delta> {
+    make_operations_from_revisions::<EmptyAttributes>(revisions)
 }
 
 pub fn pair_rev_id_from_revision_pbs(revisions: &[Revision]) -> (i64, i64) {
@@ -146,10 +132,10 @@ pub fn make_folder_from_revisions_pb(
     for revision in revisions {
         base_rev_id = revision.base_rev_id;
         rev_id = revision.rev_id;
-        if revision.delta_data.is_empty() {
+        if revision.bytes.is_empty() {
             tracing::warn!("revision delta_data is empty");
         }
-        let delta = FolderDelta::from_bytes(revision.delta_data)?;
+        let delta = FolderDelta::from_bytes(revision.bytes)?;
         folder_delta = folder_delta.compose(&delta)?;
     }
 
@@ -172,18 +158,18 @@ pub fn make_document_from_revision_pbs(
         return Ok(None);
     }
 
-    let mut delta = TextDelta::new();
+    let mut delta = TextOperations::new();
     let mut base_rev_id = 0;
     let mut rev_id = 0;
     for revision in revisions {
         base_rev_id = revision.base_rev_id;
         rev_id = revision.rev_id;
 
-        if revision.delta_data.is_empty() {
+        if revision.bytes.is_empty() {
             tracing::warn!("revision delta_data is empty");
         }
 
-        let new_delta = TextDelta::from_bytes(revision.delta_data)?;
+        let new_delta = TextOperations::from_bytes(revision.bytes)?;
         delta = delta.compose(&new_delta)?;
     }
 
@@ -206,7 +192,7 @@ pub fn rev_id_from_str(s: &str) -> Result<i64, CollaborateError> {
     Ok(rev_id)
 }
 
-pub fn cal_diff<T: OperationAttributes>(old: String, new: String) -> Option<Operations<T>> {
+pub fn cal_diff<T: OperationAttributes>(old: String, new: String) -> Option<DeltaOperations<T>> {
     let chunks = dissimilar::diff(&old, &new);
     let mut delta_builder = OperationBuilder::<T>::new();
     for chunk in &chunks {

+ 28 - 28
shared-lib/lib-ot/src/core/attributes/attribute.rs

@@ -5,8 +5,6 @@ use std::collections::HashMap;
 use std::fmt;
 use std::fmt::Display;
 
-pub type AttributeMap = HashMap<AttributeKey, AttributeValue>;
-
 #[derive(Debug, Clone)]
 pub struct AttributeEntry {
     pub key: AttributeKey,
@@ -20,37 +18,37 @@ impl AttributeEntry {
     }
 }
 
-impl std::convert::From<AttributeEntry> for Attributes {
+impl std::convert::From<AttributeEntry> for AttributeHashMap {
     fn from(entry: AttributeEntry) -> Self {
-        let mut attributes = Attributes::new();
+        let mut attributes = AttributeHashMap::new();
         attributes.insert_entry(entry);
         attributes
     }
 }
 
 #[derive(Default, Clone, Serialize, Deserialize, Eq, PartialEq, Debug)]
-pub struct Attributes(AttributeMap);
+pub struct AttributeHashMap(HashMap<AttributeKey, AttributeValue>);
 
-impl std::ops::Deref for Attributes {
-    type Target = AttributeMap;
+impl std::ops::Deref for AttributeHashMap {
+    type Target = HashMap<AttributeKey, AttributeValue>;
 
     fn deref(&self) -> &Self::Target {
         &self.0
     }
 }
 
-impl std::ops::DerefMut for Attributes {
+impl std::ops::DerefMut for AttributeHashMap {
     fn deref_mut(&mut self) -> &mut Self::Target {
         &mut self.0
     }
 }
 
-impl Attributes {
-    pub fn new() -> Attributes {
-        Attributes(HashMap::new())
+impl AttributeHashMap {
+    pub fn new() -> AttributeHashMap {
+        AttributeHashMap(HashMap::new())
     }
 
-    pub fn from_value(attribute_map: AttributeMap) -> Self {
+    pub fn from_value(attribute_map: HashMap<AttributeKey, AttributeValue>) -> Self {
         Self(attribute_map)
     }
 
@@ -91,7 +89,7 @@ impl Attributes {
 
     /// Create a new key/value map by constructing new attributes from the other
     /// if it's not None and replace the key/value with self key/value.
-    pub fn merge(&mut self, other: Option<Attributes>) {
+    pub fn merge(&mut self, other: Option<AttributeHashMap>) {
         if other.is_none() {
             return;
         }
@@ -108,7 +106,7 @@ impl Attributes {
     }
 }
 
-impl Display for Attributes {
+impl Display for AttributeHashMap {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         for (key, value) in self.0.iter() {
             let _ = f.write_str(&format!("{:?}:{:?}", key, value))?;
@@ -117,21 +115,21 @@ impl Display for Attributes {
     }
 }
 
-impl OperationAttributes for Attributes {
+impl OperationAttributes for AttributeHashMap {
     fn is_empty(&self) -> bool {
         self.is_empty()
     }
 
-    fn remove_empty(&mut self) {
+    fn remove(&mut self) {
         self.retain(|_, v| v.value.is_some());
     }
 
-    fn extend_other(&mut self, other: Self) {
+    fn extend(&mut self, other: Self) {
         self.0.extend(other.0);
     }
 }
 
-impl OperationTransform for Attributes {
+impl OperationTransform for AttributeHashMap {
     fn compose(&self, other: &Self) -> Result<Self, OTError>
     where
         Self: Sized,
@@ -145,25 +143,27 @@ impl OperationTransform for Attributes {
     where
         Self: Sized,
     {
-        let a = self.iter().fold(Attributes::new(), |mut new_attributes, (k, v)| {
+        let a = self.iter().fold(AttributeHashMap::new(), |mut new_attributes, (k, v)| {
             if !other.contains_key(k) {
                 new_attributes.insert(k.clone(), v.clone());
             }
             new_attributes
         });
 
-        let b = other.iter().fold(Attributes::new(), |mut new_attributes, (k, v)| {
-            if !self.contains_key(k) {
-                new_attributes.insert(k.clone(), v.clone());
-            }
-            new_attributes
-        });
+        let b = other
+            .iter()
+            .fold(AttributeHashMap::new(), |mut new_attributes, (k, v)| {
+                if !self.contains_key(k) {
+                    new_attributes.insert(k.clone(), v.clone());
+                }
+                new_attributes
+            });
 
         Ok((a, b))
     }
 
     fn invert(&self, other: &Self) -> Self {
-        let base_inverted = other.iter().fold(Attributes::new(), |mut attributes, (k, v)| {
+        let base_inverted = other.iter().fold(AttributeHashMap::new(), |mut attributes, (k, v)| {
             if other.get(k) != self.get(k) && self.contains_key(k) {
                 attributes.insert(k.clone(), v.clone());
             }
@@ -275,7 +275,7 @@ impl std::convert::From<String> for AttributeValue {
 
 #[derive(Default)]
 pub struct AttributeBuilder {
-    attributes: Attributes,
+    attributes: AttributeHashMap,
 }
 
 impl AttributeBuilder {
@@ -298,7 +298,7 @@ impl AttributeBuilder {
         self
     }
 
-    pub fn build(self) -> Attributes {
+    pub fn build(self) -> AttributeHashMap {
         self.attributes
     }
 }

+ 10 - 10
shared-lib/lib-ot/src/core/delta/builder.rs

@@ -1,6 +1,6 @@
 use crate::core::delta::operation::OperationAttributes;
-use crate::core::delta::{trim, Operations};
-use crate::core::Operation;
+use crate::core::delta::{trim, DeltaOperations};
+use crate::core::DeltaOperation;
 
 /// A builder for creating new [Operations] objects.
 ///
@@ -17,7 +17,7 @@ use crate::core::Operation;
 /// assert_eq!(delta.content().unwrap(), "AppFlowy");
 /// ```
 pub struct OperationBuilder<T: OperationAttributes> {
-    delta: Operations<T>,
+    delta: DeltaOperations<T>,
 }
 
 impl<T> std::default::Default for OperationBuilder<T>
@@ -26,7 +26,7 @@ where
 {
     fn default() -> Self {
         Self {
-            delta: Operations::new(),
+            delta: DeltaOperations::new(),
         }
     }
 }
@@ -39,7 +39,7 @@ where
         OperationBuilder::default()
     }
 
-    pub fn from_operations(operations: Vec<Operation<T>>) -> Operations<T> {
+    pub fn from_operations(operations: Vec<DeltaOperation<T>>) -> DeltaOperations<T> {
         let mut delta = OperationBuilder::default().build();
         operations.into_iter().for_each(|operation| {
             delta.add(operation);
@@ -52,10 +52,10 @@ where
     /// # Examples
     ///
     /// ```
-    /// use lib_ot::text_delta::{BuildInTextAttribute, TextDelta, TextDeltaBuilder};
+    /// use lib_ot::text_delta::{BuildInTextAttribute, TextOperations, TextOperationBuilder};
     ///
     /// let mut attribute = BuildInTextAttribute::Bold(true);
-    /// let delta = TextDeltaBuilder::new().retain_with_attributes(7, attribute.into()).build();
+    /// let delta = TextOperationBuilder::new().retain_with_attributes(7, attribute.into()).build();
     ///
     /// assert_eq!(delta.json_str(), r#"[{"retain":7,"attributes":{"bold":true}}]"#);
     /// ```
@@ -111,14 +111,14 @@ where
     ///
     /// ```
     /// use lib_ot::core::{OperationTransform, DeltaBuilder};
-    /// use lib_ot::text_delta::{BuildInTextAttribute, TextDeltaBuilder};
+    /// use lib_ot::text_delta::{BuildInTextAttribute, TextOperationBuilder};
     /// let delta = DeltaBuilder::new()
     ///         .retain(3)
     ///         .trim()
     ///         .build();
     /// assert_eq!(delta.ops.len(), 0);
     ///
-    /// let delta = TextDeltaBuilder::new()
+    /// let delta = TextOperationBuilder::new()
     ///         .retain_with_attributes(3, BuildInTextAttribute::Bold(true).into())
     ///         .trim()
     ///         .build();
@@ -130,7 +130,7 @@ where
     }
 
     /// Builds the `Delta`
-    pub fn build(self) -> Operations<T> {
+    pub fn build(self) -> DeltaOperations<T> {
         self.delta
     }
 }

+ 17 - 17
shared-lib/lib-ot/src/core/delta/cursor.rs

@@ -1,6 +1,6 @@
 #![allow(clippy::while_let_on_iterator)]
-use crate::core::delta::operation::{Operation, OperationAttributes};
-use crate::core::delta::Operations;
+use crate::core::delta::operation::{DeltaOperation, OperationAttributes};
+use crate::core::delta::DeltaOperations;
 use crate::core::interval::Interval;
 use crate::errors::{ErrorBuilder, OTError, OTErrorCode};
 use std::{cmp::min, iter::Enumerate, slice::Iter};
@@ -8,13 +8,13 @@ use std::{cmp::min, iter::Enumerate, slice::Iter};
 /// A [OperationsCursor] is used to iterate the delta and return the corresponding delta.
 #[derive(Debug)]
 pub struct OperationsCursor<'a, T: OperationAttributes> {
-    pub(crate) delta: &'a Operations<T>,
+    pub(crate) delta: &'a DeltaOperations<T>,
     pub(crate) origin_iv: Interval,
     pub(crate) consume_iv: Interval,
     pub(crate) consume_count: usize,
     pub(crate) op_offset: usize,
-    iter: Enumerate<Iter<'a, Operation<T>>>,
-    next_op: Option<Operation<T>>,
+    iter: Enumerate<Iter<'a, DeltaOperation<T>>>,
+    next_op: Option<DeltaOperation<T>>,
 }
 
 impl<'a, T> OperationsCursor<'a, T>
@@ -29,19 +29,19 @@ where
     /// # Examples
     ///
     /// ```
-    /// use lib_ot::core::{OperationsCursor, OperationIterator, Interval, Operation};
-    /// use lib_ot::text_delta::TextDelta;
-    /// let mut delta = TextDelta::default();   
-    /// delta.add(Operation::insert("123"));    
-    /// delta.add(Operation::insert("4"));
+    /// use lib_ot::core::{OperationsCursor, OperationIterator, Interval, DeltaOperation};
+    /// use lib_ot::text_delta::TextOperations;
+    /// let mut delta = TextOperations::default();   
+    /// delta.add(DeltaOperation::insert("123"));    
+    /// delta.add(DeltaOperation::insert("4"));
     ///
     /// let mut cursor = OperationsCursor::new(&delta, Interval::new(0, 3));
     /// assert_eq!(cursor.next_iv(), Interval::new(0,3));
-    /// assert_eq!(cursor.next_with_len(Some(2)).unwrap(), Operation::insert("12"));
-    /// assert_eq!(cursor.get_next_op().unwrap(), Operation::insert("3"));
+    /// assert_eq!(cursor.next_with_len(Some(2)).unwrap(), DeltaOperation::insert("12"));
+    /// assert_eq!(cursor.get_next_op().unwrap(), DeltaOperation::insert("3"));
     /// assert_eq!(cursor.get_next_op(), None);
     /// ```
-    pub fn new(delta: &'a Operations<T>, interval: Interval) -> OperationsCursor<'a, T> {
+    pub fn new(delta: &'a DeltaOperations<T>, interval: Interval) -> OperationsCursor<'a, T> {
         // debug_assert!(interval.start <= delta.target_len);
         let mut cursor = Self {
             delta,
@@ -62,12 +62,12 @@ where
     }
 
     /// Returns the next operation
-    pub fn get_next_op(&mut self) -> Option<Operation<T>> {
+    pub fn get_next_op(&mut self) -> Option<DeltaOperation<T>> {
         self.next_with_len(None)
     }
 
     /// Returns the reference of the next operation
-    pub fn next_op(&self) -> Option<&Operation<T>> {
+    pub fn next_op(&self) -> Option<&DeltaOperation<T>> {
         let mut next_op = self.next_op.as_ref();
         if next_op.is_none() {
             let mut offset = 0;
@@ -87,7 +87,7 @@ where
     /// * `expected_len`: Return the next operation with the specified length.
     ///
     ///
-    pub fn next_with_len(&mut self, expected_len: Option<usize>) -> Option<Operation<T>> {
+    pub fn next_with_len(&mut self, expected_len: Option<usize>) -> Option<DeltaOperation<T>> {
         let mut find_op = None;
         let holder = self.next_op.clone();
         let mut next_op = holder.as_ref();
@@ -182,7 +182,7 @@ where
     }
 }
 
-fn find_next<'a, T>(cursor: &mut OperationsCursor<'a, T>) -> Option<&'a Operation<T>>
+fn find_next<'a, T>(cursor: &mut OperationsCursor<'a, T>) -> Option<&'a DeltaOperation<T>>
 where
     T: OperationAttributes,
 {

+ 27 - 27
shared-lib/lib-ot/src/core/delta/iterator.rs

@@ -1,8 +1,8 @@
 use super::cursor::*;
-use crate::core::delta::operation::{Operation, OperationAttributes};
-use crate::core::delta::{Operations, NEW_LINE};
+use crate::core::delta::operation::{DeltaOperation, OperationAttributes};
+use crate::core::delta::{DeltaOperations, NEW_LINE};
 use crate::core::interval::Interval;
-use crate::core::Attributes;
+use crate::core::AttributeHashMap;
 
 use std::ops::{Deref, DerefMut};
 
@@ -14,19 +14,19 @@ pub(crate) const MAX_IV_LEN: usize = i32::MAX as usize;
 /// You could check [this](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/backend/delta) out for more information.
 ///
 /// ```
-///  use lib_ot::core::{OperationIterator, Interval, Operation};
-///  use lib_ot::text_delta::TextDelta;
-///  let mut delta = TextDelta::default();
-///  delta.add(Operation::insert("123"));
-///  delta.add(Operation::insert("4"));
+///  use lib_ot::core::{OperationIterator, Interval, DeltaOperation};
+///  use lib_ot::text_delta::TextOperations;
+///  let mut delta = TextOperations::default();
+///  delta.add(DeltaOperation::insert("123"));
+///  delta.add(DeltaOperation::insert("4"));
 ///  assert_eq!(
 ///     OperationIterator::from_interval(&delta, Interval::new(0, 2)).ops(),
-///     vec![Operation::insert("12")]
+///     vec![DeltaOperation::insert("12")]
 ///  );
 ///
 ///  assert_eq!(
 ///     OperationIterator::from_interval(&delta, Interval::new(1, 3)).ops(),
-///     vec![Operation::insert("23")]
+///     vec![DeltaOperation::insert("23")]
 ///  );
 /// ```
 pub struct OperationIterator<'a, T: OperationAttributes> {
@@ -37,24 +37,24 @@ impl<'a, T> OperationIterator<'a, T>
 where
     T: OperationAttributes,
 {
-    pub fn new(delta: &'a Operations<T>) -> Self {
+    pub fn new(delta: &'a DeltaOperations<T>) -> Self {
         let interval = Interval::new(0, MAX_IV_LEN);
         Self::from_interval(delta, interval)
     }
 
-    pub fn from_offset(delta: &'a Operations<T>, offset: usize) -> Self {
+    pub fn from_offset(delta: &'a DeltaOperations<T>, offset: usize) -> Self {
         let interval = Interval::new(0, MAX_IV_LEN);
         let mut iter = Self::from_interval(delta, interval);
         iter.seek::<Utf16CodeUnitMetric>(offset);
         iter
     }
 
-    pub fn from_interval(delta: &'a Operations<T>, interval: Interval) -> Self {
+    pub fn from_interval(delta: &'a DeltaOperations<T>, interval: Interval) -> Self {
         let cursor = OperationsCursor::new(delta, interval);
         Self { cursor }
     }
 
-    pub fn ops(&mut self) -> Vec<Operation<T>> {
+    pub fn ops(&mut self) -> Vec<DeltaOperation<T>> {
         self.collect::<Vec<_>>()
     }
 
@@ -67,16 +67,16 @@ where
         }
     }
 
-    pub fn next_op(&mut self) -> Option<Operation<T>> {
+    pub fn next_op(&mut self) -> Option<DeltaOperation<T>> {
         self.cursor.get_next_op()
     }
 
-    pub fn next_op_with_len(&mut self, len: usize) -> Option<Operation<T>> {
+    pub fn next_op_with_len(&mut self, len: usize) -> Option<DeltaOperation<T>> {
         self.cursor.next_with_len(Some(len))
     }
 
     // find next op contains NEW_LINE
-    pub fn next_op_with_newline(&mut self) -> Option<(Operation<T>, usize)> {
+    pub fn next_op_with_newline(&mut self) -> Option<(DeltaOperation<T>, usize)> {
         let mut offset = 0;
         while self.has_next() {
             if let Some(op) = self.next_op() {
@@ -127,13 +127,13 @@ impl<'a, T> Iterator for OperationIterator<'a, T>
 where
     T: OperationAttributes,
 {
-    type Item = Operation<T>;
+    type Item = DeltaOperation<T>;
     fn next(&mut self) -> Option<Self::Item> {
         self.next_op()
     }
 }
 
-pub fn is_empty_line_at_index(delta: &Operations<Attributes>, index: usize) -> bool {
+pub fn is_empty_line_at_index(delta: &DeltaOperations<AttributeHashMap>, index: usize) -> bool {
     let mut iter = OperationIterator::new(delta);
     let (prev, next) = (iter.next_op_with_len(index), iter.next_op());
     if prev.is_none() {
@@ -157,12 +157,12 @@ impl<'a, T> AttributesIter<'a, T>
 where
     T: OperationAttributes,
 {
-    pub fn new(delta: &'a Operations<T>) -> Self {
+    pub fn new(delta: &'a DeltaOperations<T>) -> Self {
         let interval = Interval::new(0, usize::MAX);
         Self::from_interval(delta, interval)
     }
 
-    pub fn from_interval(delta: &'a Operations<T>, interval: Interval) -> Self {
+    pub fn from_interval(delta: &'a DeltaOperations<T>, interval: Interval) -> Self {
         let delta_iter = OperationIterator::from_interval(delta, interval);
         Self { delta_iter }
     }
@@ -207,16 +207,16 @@ where
         let mut attributes = T::default();
 
         match next_op.unwrap() {
-            Operation::<T>::Delete(_n) => {}
-            Operation::<T>::Retain(retain) => {
+            DeltaOperation::<T>::Delete(_n) => {}
+            DeltaOperation::<T>::Retain(retain) => {
                 tracing::trace!("extend retain attributes with {} ", &retain.attributes);
-                attributes.extend_other(retain.attributes.clone());
+                attributes.extend(retain.attributes.clone());
 
                 length = retain.n;
             }
-            Operation::<T>::Insert(insert) => {
+            DeltaOperation::<T>::Insert(insert) => {
                 tracing::trace!("extend insert attributes with {} ", &insert.attributes);
-                attributes.extend_other(insert.attributes.clone());
+                attributes.extend(insert.attributes.clone());
                 length = insert.utf16_size();
             }
         }
@@ -235,7 +235,7 @@ pub enum OpNewline {
 }
 
 impl OpNewline {
-    pub fn parse<T: OperationAttributes>(op: &Operation<T>) -> OpNewline {
+    pub fn parse<T: OperationAttributes>(op: &DeltaOperation<T>) -> OpNewline {
         let s = op.get_data();
 
         if s == NEW_LINE {

+ 8 - 8
shared-lib/lib-ot/src/core/delta/operation/builder.rs

@@ -1,11 +1,11 @@
-use crate::core::delta::operation::{EmptyAttributes, Operation, OperationAttributes};
+use crate::core::delta::operation::{DeltaOperation, EmptyAttributes, OperationAttributes};
 
 // pub type RichTextOpBuilder = OperationsBuilder<TextAttributes>;
 pub type PlainTextOpBuilder = OperationsBuilder<EmptyAttributes>;
 
 #[derive(Default)]
 pub struct OperationsBuilder<T: OperationAttributes> {
-    operations: Vec<Operation<T>>,
+    operations: Vec<DeltaOperation<T>>,
 }
 
 impl<T> OperationsBuilder<T>
@@ -17,35 +17,35 @@ where
     }
 
     pub fn retain_with_attributes(mut self, n: usize, attributes: T) -> OperationsBuilder<T> {
-        let retain = Operation::retain_with_attributes(n, attributes);
+        let retain = DeltaOperation::retain_with_attributes(n, attributes);
         self.operations.push(retain);
         self
     }
 
     pub fn retain(mut self, n: usize) -> OperationsBuilder<T> {
-        let retain = Operation::retain(n);
+        let retain = DeltaOperation::retain(n);
         self.operations.push(retain);
         self
     }
 
     pub fn delete(mut self, n: usize) -> OperationsBuilder<T> {
-        self.operations.push(Operation::Delete(n));
+        self.operations.push(DeltaOperation::Delete(n));
         self
     }
 
     pub fn insert_with_attributes(mut self, s: &str, attributes: T) -> OperationsBuilder<T> {
-        let insert = Operation::insert_with_attributes(s, attributes);
+        let insert = DeltaOperation::insert_with_attributes(s, attributes);
         self.operations.push(insert);
         self
     }
 
     pub fn insert(mut self, s: &str) -> OperationsBuilder<T> {
-        let insert = Operation::insert(s);
+        let insert = DeltaOperation::insert(s);
         self.operations.push(insert);
         self
     }
 
-    pub fn build(self) -> Vec<Operation<T>> {
+    pub fn build(self) -> Vec<DeltaOperation<T>> {
         self.operations
     }
 }

+ 53 - 57
shared-lib/lib-ot/src/core/delta/operation/operation.rs

@@ -75,17 +75,13 @@ pub trait OperationAttributes: Default + Display + Eq + PartialEq + Clone + Debu
         true
     }
 
-    /// Remove the empty attribute which value is None.
-    fn remove_empty(&mut self) {
-        // Do nothing
-    }
+    /// Remove the attribute which value is None.
+    fn remove(&mut self) {}
 
-    fn extend_other(&mut self, _other: Self) {
-        // Do nothing
-    }
+    fn extend(&mut self, _other: Self) {}
 }
 
-/// [Operation] consists of three types.
+/// [DeltaOperation] consists of three types.
 /// * Delete
 /// * Retain
 /// * Insert
@@ -96,13 +92,13 @@ pub trait OperationAttributes: Default + Display + Eq + PartialEq + Clone + Debu
 /// to json string. You could check out the operation_serde.rs for more information.
 ///
 #[derive(Debug, Clone, Eq, PartialEq)]
-pub enum Operation<T: OperationAttributes> {
+pub enum DeltaOperation<T: OperationAttributes> {
     Delete(usize),
     Retain(Retain<T>),
     Insert(Insert<T>),
 }
 
-impl<T> Operation<T>
+impl<T> DeltaOperation<T>
 where
     T: OperationAttributes,
 {
@@ -142,25 +138,25 @@ where
     /// Return the String if the operation is [Insert] operation, otherwise return the empty string.
     pub fn get_data(&self) -> &str {
         match self {
-            Operation::Delete(_) => "",
-            Operation::Retain(_) => "",
-            Operation::Insert(insert) => &insert.s,
+            DeltaOperation::Delete(_) => "",
+            DeltaOperation::Retain(_) => "",
+            DeltaOperation::Insert(insert) => &insert.s,
         }
     }
 
     pub fn get_attributes(&self) -> T {
         match self {
-            Operation::Delete(_) => T::default(),
-            Operation::Retain(retain) => retain.attributes.clone(),
-            Operation::Insert(insert) => insert.attributes.clone(),
+            DeltaOperation::Delete(_) => T::default(),
+            DeltaOperation::Retain(retain) => retain.attributes.clone(),
+            DeltaOperation::Insert(insert) => insert.attributes.clone(),
         }
     }
 
     pub fn set_attributes(&mut self, attributes: T) {
         match self {
-            Operation::Delete(_) => log::error!("Delete should not contains attributes"),
-            Operation::Retain(retain) => retain.attributes = attributes,
-            Operation::Insert(insert) => insert.attributes = attributes,
+            DeltaOperation::Delete(_) => log::error!("Delete should not contains attributes"),
+            DeltaOperation::Retain(retain) => retain.attributes = attributes,
+            DeltaOperation::Insert(insert) => insert.attributes = attributes,
         }
     }
 
@@ -170,9 +166,9 @@ where
 
     pub fn len(&self) -> usize {
         match self {
-            Operation::Delete(n) => *n,
-            Operation::Retain(r) => r.n,
-            Operation::Insert(i) => i.utf16_size(),
+            DeltaOperation::Delete(n) => *n,
+            DeltaOperation::Retain(r) => r.n,
+            DeltaOperation::Insert(i) => i.utf16_size(),
         }
     }
 
@@ -181,26 +177,26 @@ where
     }
 
     #[allow(dead_code)]
-    pub fn split(&self, index: usize) -> (Option<Operation<T>>, Option<Operation<T>>) {
+    pub fn split(&self, index: usize) -> (Option<DeltaOperation<T>>, Option<DeltaOperation<T>>) {
         debug_assert!(index < self.len());
         let left;
         let right;
         match self {
-            Operation::Delete(n) => {
-                left = Some(Operation::<T>::delete(index));
-                right = Some(Operation::<T>::delete(*n - index));
+            DeltaOperation::Delete(n) => {
+                left = Some(DeltaOperation::<T>::delete(index));
+                right = Some(DeltaOperation::<T>::delete(*n - index));
             }
-            Operation::Retain(retain) => {
-                left = Some(Operation::<T>::delete(index));
-                right = Some(Operation::<T>::delete(retain.n - index));
+            DeltaOperation::Retain(retain) => {
+                left = Some(DeltaOperation::<T>::delete(index));
+                right = Some(DeltaOperation::<T>::delete(retain.n - index));
             }
-            Operation::Insert(insert) => {
+            DeltaOperation::Insert(insert) => {
                 let attributes = self.get_attributes();
-                left = Some(Operation::<T>::insert_with_attributes(
+                left = Some(DeltaOperation::<T>::insert_with_attributes(
                     &insert.s[0..index],
                     attributes.clone(),
                 ));
-                right = Some(Operation::<T>::insert_with_attributes(
+                right = Some(DeltaOperation::<T>::insert_with_attributes(
                     &insert.s[index..insert.utf16_size()],
                     attributes,
                 ));
@@ -218,27 +214,27 @@ where
     /// # Examples
     ///
     /// ```
-    /// use lib_ot::core::{Interval, Operation, EmptyAttributes};
-    /// let operation = Operation::<EmptyAttributes>::insert("1234");
+    /// use lib_ot::core::{Interval, DeltaOperation, EmptyAttributes};
+    /// let operation = DeltaOperation::<EmptyAttributes>::insert("1234");
     ///
     /// let op1 = operation.shrink(Interval::new(0,3)).unwrap();
-    /// assert_eq!(op1 , Operation::insert("123"));
+    /// assert_eq!(op1 , DeltaOperation::insert("123"));
     ///
     /// let op2= operation.shrink(Interval::new(3,4)).unwrap();
-    /// assert_eq!(op2, Operation::insert("4"));
+    /// assert_eq!(op2, DeltaOperation::insert("4"));
     /// ```
-    pub fn shrink(&self, interval: Interval) -> Option<Operation<T>> {
+    pub fn shrink(&self, interval: Interval) -> Option<DeltaOperation<T>> {
         let op = match self {
-            Operation::Delete(n) => Operation::delete(min(*n, interval.size())),
-            Operation::Retain(retain) => {
-                Operation::retain_with_attributes(min(retain.n, interval.size()), retain.attributes.clone())
+            DeltaOperation::Delete(n) => DeltaOperation::delete(min(*n, interval.size())),
+            DeltaOperation::Retain(retain) => {
+                DeltaOperation::retain_with_attributes(min(retain.n, interval.size()), retain.attributes.clone())
             }
-            Operation::Insert(insert) => {
+            DeltaOperation::Insert(insert) => {
                 if interval.start > insert.utf16_size() {
-                    Operation::insert("")
+                    DeltaOperation::insert("")
                 } else {
                     let s = insert.s.sub_str(interval).unwrap_or_else(|| "".to_owned());
-                    Operation::insert_with_attributes(&s, insert.attributes.clone())
+                    DeltaOperation::insert_with_attributes(&s, insert.attributes.clone())
                 }
             }
         };
@@ -250,21 +246,21 @@ where
     }
 
     pub fn is_delete(&self) -> bool {
-        if let Operation::Delete(_) = self {
+        if let DeltaOperation::Delete(_) = self {
             return true;
         }
         false
     }
 
     pub fn is_insert(&self) -> bool {
-        if let Operation::Insert(_) = self {
+        if let DeltaOperation::Insert(_) = self {
             return true;
         }
         false
     }
 
     pub fn is_retain(&self) -> bool {
-        if let Operation::Retain(_) = self {
+        if let DeltaOperation::Retain(_) = self {
             return true;
         }
         false
@@ -272,27 +268,27 @@ where
 
     pub fn is_plain(&self) -> bool {
         match self {
-            Operation::Delete(_) => true,
-            Operation::Retain(retain) => retain.is_plain(),
-            Operation::Insert(insert) => insert.is_plain(),
+            DeltaOperation::Delete(_) => true,
+            DeltaOperation::Retain(retain) => retain.is_plain(),
+            DeltaOperation::Insert(insert) => insert.is_plain(),
         }
     }
 }
 
-impl<T> fmt::Display for Operation<T>
+impl<T> fmt::Display for DeltaOperation<T>
 where
     T: OperationAttributes,
 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.write_str("{")?;
         match self {
-            Operation::Delete(n) => {
+            DeltaOperation::Delete(n) => {
                 f.write_fmt(format_args!("delete: {}", n))?;
             }
-            Operation::Retain(r) => {
+            DeltaOperation::Retain(r) => {
                 f.write_fmt(format_args!("{}", r))?;
             }
-            Operation::Insert(i) => {
+            DeltaOperation::Insert(i) => {
                 f.write_fmt(format_args!("{}", i))?;
             }
         }
@@ -324,7 +320,7 @@ impl<T> Retain<T>
 where
     T: OperationAttributes,
 {
-    pub fn merge_or_new(&mut self, n: usize, attributes: T) -> Option<Operation<T>> {
+    pub fn merge_or_new(&mut self, n: usize, attributes: T) -> Option<DeltaOperation<T>> {
         // tracing::trace!(
         //     "merge_retain_or_new_op: len: {:?}, l: {} - r: {}",
         //     n,
@@ -335,7 +331,7 @@ where
             self.n += n;
             None
         } else {
-            Some(Operation::retain_with_attributes(n, attributes))
+            Some(DeltaOperation::retain_with_attributes(n, attributes))
         }
     }
 
@@ -411,12 +407,12 @@ where
         self.s.utf16_len()
     }
 
-    pub fn merge_or_new_op(&mut self, s: &str, attributes: T) -> Option<Operation<T>> {
+    pub fn merge_or_new_op(&mut self, s: &str, attributes: T) -> Option<DeltaOperation<T>> {
         if self.attributes == attributes {
             self.s += s;
             None
         } else {
-            Some(Operation::<T>::insert_with_attributes(s, attributes))
+            Some(DeltaOperation::<T>::insert_with_attributes(s, attributes))
         }
     }
 

+ 11 - 11
shared-lib/lib-ot/src/core/delta/operation/operation_serde.rs

@@ -1,4 +1,4 @@
-use crate::core::delta::operation::{Insert, Operation, OperationAttributes, Retain};
+use crate::core::delta::operation::{DeltaOperation, Insert, OperationAttributes, Retain};
 use crate::core::ot_str::OTString;
 use serde::{
     de,
@@ -8,7 +8,7 @@ use serde::{
 };
 use std::{fmt, marker::PhantomData};
 
-impl<T> Serialize for Operation<T>
+impl<T> Serialize for DeltaOperation<T>
 where
     T: OperationAttributes + Serialize,
 {
@@ -17,22 +17,22 @@ where
         S: Serializer,
     {
         match self {
-            Operation::Retain(retain) => retain.serialize(serializer),
-            Operation::Delete(i) => {
+            DeltaOperation::Retain(retain) => retain.serialize(serializer),
+            DeltaOperation::Delete(i) => {
                 let mut map = serializer.serialize_map(Some(1))?;
                 map.serialize_entry("delete", i)?;
                 map.end()
             }
-            Operation::Insert(insert) => insert.serialize(serializer),
+            DeltaOperation::Insert(insert) => insert.serialize(serializer),
         }
     }
 }
 
-impl<'de, T> Deserialize<'de> for Operation<T>
+impl<'de, T> Deserialize<'de> for DeltaOperation<T>
 where
     T: OperationAttributes + Deserialize<'de>,
 {
-    fn deserialize<D>(deserializer: D) -> Result<Operation<T>, D::Error>
+    fn deserialize<D>(deserializer: D) -> Result<DeltaOperation<T>, D::Error>
     where
         D: Deserializer<'de>,
     {
@@ -42,7 +42,7 @@ where
         where
             T: OperationAttributes + Deserialize<'de>,
         {
-            type Value = Operation<T>;
+            type Value = DeltaOperation<T>;
 
             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                 formatter.write_str("an integer between -2^64 and 2^63 or a string")
@@ -61,21 +61,21 @@ where
                             if operation.is_some() {
                                 return Err(de::Error::duplicate_field("operation"));
                             }
-                            operation = Some(Operation::<T>::Delete(map.next_value()?));
+                            operation = Some(DeltaOperation::<T>::Delete(map.next_value()?));
                         }
                         "retain" => {
                             if operation.is_some() {
                                 return Err(de::Error::duplicate_field("operation"));
                             }
                             let i: usize = map.next_value()?;
-                            operation = Some(Operation::<T>::Retain(i.into()));
+                            operation = Some(DeltaOperation::<T>::Retain(i.into()));
                         }
                         "insert" => {
                             if operation.is_some() {
                                 return Err(de::Error::duplicate_field("operation"));
                             }
                             let i: String = map.next_value()?;
-                            operation = Some(Operation::<T>::Insert(i.into()));
+                            operation = Some(DeltaOperation::<T>::Insert(i.into()));
                         }
                         "attributes" => {
                             if attributes.is_some() {

+ 83 - 82
shared-lib/lib-ot/src/core/delta/ops.rs

@@ -1,6 +1,6 @@
 use crate::errors::{ErrorBuilder, OTError, OTErrorCode};
 
-use crate::core::delta::operation::{EmptyAttributes, Operation, OperationAttributes, OperationTransform};
+use crate::core::delta::operation::{DeltaOperation, EmptyAttributes, OperationAttributes, OperationTransform};
 use crate::core::delta::{OperationIterator, MAX_IV_LEN};
 use crate::core::interval::Interval;
 use crate::core::ot_str::OTString;
@@ -15,7 +15,7 @@ use std::{
     str::FromStr,
 };
 
-pub type Delta = Operations<EmptyAttributes>;
+pub type Delta = DeltaOperations<EmptyAttributes>;
 pub type DeltaBuilder = OperationBuilder<EmptyAttributes>;
 
 /// A [Delta] contains list of operations that consists of 'Retain', 'Delete' and 'Insert' operation.
@@ -28,8 +28,8 @@ pub type DeltaBuilder = OperationBuilder<EmptyAttributes>;
 /// a JSON string.
 ///
 #[derive(Clone, Debug, PartialEq, Eq)]
-pub struct Operations<T: OperationAttributes> {
-    pub ops: Vec<Operation<T>>,
+pub struct DeltaOperations<Attribute: OperationAttributes> {
+    pub ops: Vec<DeltaOperation<Attribute>>,
 
     /// 'Delete' and 'Retain' operation will update the [utf16_base_len]
     /// Transforming the other delta, it requires the utf16_base_len must be equal.  
@@ -40,7 +40,7 @@ pub struct Operations<T: OperationAttributes> {
     pub utf16_target_len: usize,
 }
 
-impl<T> Default for Operations<T>
+impl<T> Default for DeltaOperations<T>
 where
     T: OperationAttributes,
 {
@@ -53,7 +53,7 @@ where
     }
 }
 
-impl<T> fmt::Display for Operations<T>
+impl<T> fmt::Display for DeltaOperations<T>
 where
     T: OperationAttributes,
 {
@@ -68,12 +68,12 @@ where
     }
 }
 
-impl<T> FromIterator<Operation<T>> for Operations<T>
+impl<T> FromIterator<DeltaOperation<T>> for DeltaOperations<T>
 where
     T: OperationAttributes,
 {
-    fn from_iter<I: IntoIterator<Item = Operation<T>>>(ops: I) -> Self {
-        let mut operations = Operations::default();
+    fn from_iter<I: IntoIterator<Item = DeltaOperation<T>>>(ops: I) -> Self {
+        let mut operations = DeltaOperations::default();
         for op in ops {
             operations.add(op);
         }
@@ -81,7 +81,7 @@ where
     }
 }
 
-impl<T> Operations<T>
+impl<T> DeltaOperations<T>
 where
     T: OperationAttributes,
 {
@@ -99,11 +99,11 @@ where
     }
 
     /// Adding an operation. It will be added in sequence.
-    pub fn add(&mut self, op: Operation<T>) {
+    pub fn add(&mut self, op: DeltaOperation<T>) {
         match op {
-            Operation::Delete(i) => self.delete(i),
-            Operation::Insert(i) => self.insert(&i.s, i.attributes),
-            Operation::Retain(r) => self.retain(r.n, r.attributes),
+            DeltaOperation::Delete(i) => self.delete(i),
+            DeltaOperation::Insert(i) => self.insert(&i.s, i.attributes),
+            DeltaOperation::Retain(r) => self.retain(r.n, r.attributes),
         }
     }
 
@@ -113,10 +113,10 @@ where
             return;
         }
         self.utf16_base_len += n as usize;
-        if let Some(Operation::Delete(n_last)) = self.ops.last_mut() {
+        if let Some(DeltaOperation::Delete(n_last)) = self.ops.last_mut() {
             *n_last += n;
         } else {
-            self.ops.push(Operation::delete(n));
+            self.ops.push(DeltaOperation::delete(n));
         }
     }
 
@@ -129,20 +129,20 @@ where
 
         self.utf16_target_len += s.utf16_len();
         let new_last = match self.ops.as_mut_slice() {
-            [.., Operation::<T>::Insert(insert)] => {
+            [.., DeltaOperation::<T>::Insert(insert)] => {
                 //
                 insert.merge_or_new_op(&s, attributes)
             }
-            [.., Operation::<T>::Insert(pre_insert), Operation::Delete(_)] => {
+            [.., DeltaOperation::<T>::Insert(pre_insert), DeltaOperation::Delete(_)] => {
                 //
                 pre_insert.merge_or_new_op(&s, attributes)
             }
-            [.., op_last @ Operation::<T>::Delete(_)] => {
+            [.., op_last @ DeltaOperation::<T>::Delete(_)] => {
                 let new_last = op_last.clone();
-                *op_last = Operation::<T>::insert_with_attributes(&s, attributes);
+                *op_last = DeltaOperation::<T>::insert_with_attributes(&s, attributes);
                 Some(new_last)
             }
-            _ => Some(Operation::<T>::insert_with_attributes(&s, attributes)),
+            _ => Some(DeltaOperation::<T>::insert_with_attributes(&s, attributes)),
         };
 
         match new_last {
@@ -159,12 +159,13 @@ where
         self.utf16_base_len += n as usize;
         self.utf16_target_len += n as usize;
 
-        if let Some(Operation::<T>::Retain(retain)) = self.ops.last_mut() {
+        if let Some(DeltaOperation::<T>::Retain(retain)) = self.ops.last_mut() {
             if let Some(new_op) = retain.merge_or_new(n, attributes) {
                 self.ops.push(new_op);
             }
         } else {
-            self.ops.push(Operation::<T>::retain_with_attributes(n, attributes));
+            self.ops
+                .push(DeltaOperation::<T>::retain_with_attributes(n, attributes));
         }
     }
 
@@ -207,17 +208,17 @@ where
         let code_point_iter = &mut applied_str.utf16_iter();
         for op in &self.ops {
             match &op {
-                Operation::Retain(retain) => {
+                DeltaOperation::Retain(retain) => {
                     for c in code_point_iter.take(retain.n as usize) {
                         new_s.push_str(str::from_utf8(c.0).unwrap_or(""));
                     }
                 }
-                Operation::Delete(delete) => {
+                DeltaOperation::Delete(delete) => {
                     for _ in 0..*delete {
                         code_point_iter.next();
                     }
                 }
-                Operation::Insert(insert) => {
+                DeltaOperation::Insert(insert) => {
                     new_s += &insert.s;
                 }
             }
@@ -249,22 +250,22 @@ where
     /// ```
     ///
     pub fn invert_str(&self, inverted_s: &str) -> Self {
-        let mut inverted = Operations::default();
+        let mut inverted = DeltaOperations::default();
         let inverted_s: OTString = inverted_s.into();
         let code_point_iter = &mut inverted_s.utf16_iter();
 
         for op in &self.ops {
             match &op {
-                Operation::Retain(retain) => {
+                DeltaOperation::Retain(retain) => {
                     inverted.retain(retain.n, T::default());
                     for _ in 0..retain.n {
                         code_point_iter.next();
                     }
                 }
-                Operation::Insert(insert) => {
+                DeltaOperation::Insert(insert) => {
                     inverted.delete(insert.utf16_size());
                 }
-                Operation::Delete(delete) => {
+                DeltaOperation::Delete(delete) => {
                     let bytes = code_point_iter
                         .take(*delete as usize)
                         .into_iter()
@@ -280,7 +281,7 @@ where
 
     /// Return true if the delta doesn't contain any [Insert] or [Delete] operations.
     pub fn is_noop(&self) -> bool {
-        matches!(self.ops.as_slice(), [] | [Operation::Retain(_)])
+        matches!(self.ops.as_slice(), [] | [DeltaOperation::Retain(_)])
     }
 
     pub fn is_empty(&self) -> bool {
@@ -292,7 +293,7 @@ where
     }
 }
 
-impl<T> OperationTransform for Operations<T>
+impl<T> OperationTransform for DeltaOperations<T>
 where
     T: OperationAttributes,
 {
@@ -300,7 +301,7 @@ where
     where
         Self: Sized,
     {
-        let mut new_delta = Operations::default();
+        let mut new_delta = DeltaOperations::default();
         let mut iter = OperationIterator::new(self);
         let mut other_iter = OperationIterator::new(other);
 
@@ -322,25 +323,25 @@ where
 
             let op = iter
                 .next_op_with_len(length)
-                .unwrap_or_else(|| Operation::retain(length));
+                .unwrap_or_else(|| DeltaOperation::retain(length));
             let other_op = other_iter
                 .next_op_with_len(length)
-                .unwrap_or_else(|| Operation::retain(length));
+                .unwrap_or_else(|| DeltaOperation::retain(length));
 
             // debug_assert_eq!(op.len(), other_op.len(), "Composing delta failed,");
 
             match (&op, &other_op) {
-                (Operation::Retain(retain), Operation::Retain(other_retain)) => {
+                (DeltaOperation::Retain(retain), DeltaOperation::Retain(other_retain)) => {
                     let composed_attrs = retain.attributes.compose(&other_retain.attributes)?;
 
-                    new_delta.add(Operation::retain_with_attributes(retain.n, composed_attrs))
+                    new_delta.add(DeltaOperation::retain_with_attributes(retain.n, composed_attrs))
                 }
-                (Operation::Insert(insert), Operation::Retain(other_retain)) => {
+                (DeltaOperation::Insert(insert), DeltaOperation::Retain(other_retain)) => {
                     let mut composed_attrs = insert.attributes.compose(&other_retain.attributes)?;
-                    composed_attrs.remove_empty();
-                    new_delta.add(Operation::insert_with_attributes(op.get_data(), composed_attrs))
+                    composed_attrs.remove();
+                    new_delta.add(DeltaOperation::insert_with_attributes(op.get_data(), composed_attrs))
                 }
-                (Operation::Retain(_), Operation::Delete(_)) => {
+                (DeltaOperation::Retain(_), DeltaOperation::Delete(_)) => {
                     new_delta.add(other_op);
                 }
                 (a, b) => {
@@ -366,8 +367,8 @@ where
                 .build());
         }
 
-        let mut a_prime = Operations::default();
-        let mut b_prime = Operations::default();
+        let mut a_prime = DeltaOperations::default();
+        let mut b_prime = DeltaOperations::default();
 
         let mut ops1 = self.ops.iter().cloned();
         let mut ops2 = other.ops.iter().cloned();
@@ -377,13 +378,13 @@ where
         loop {
             match (&next_op1, &next_op2) {
                 (None, None) => break,
-                (Some(Operation::Insert(insert)), _) => {
+                (Some(DeltaOperation::Insert(insert)), _) => {
                     // let composed_attrs = transform_attributes(&next_op1, &next_op2, true);
                     a_prime.insert(&insert.s, insert.attributes.clone());
                     b_prime.retain(insert.utf16_size(), insert.attributes.clone());
                     next_op1 = ops1.next();
                 }
-                (_, Some(Operation::Insert(o_insert))) => {
+                (_, Some(DeltaOperation::Insert(o_insert))) => {
                     let composed_attrs = transform_op_attribute(&next_op1, &next_op2)?;
                     a_prime.retain(o_insert.utf16_size(), composed_attrs.clone());
                     b_prime.insert(&o_insert.s, composed_attrs);
@@ -395,13 +396,13 @@ where
                 (_, None) => {
                     return Err(ErrorBuilder::new(OTErrorCode::IncompatibleLength).build());
                 }
-                (Some(Operation::Retain(retain)), Some(Operation::Retain(o_retain))) => {
+                (Some(DeltaOperation::Retain(retain)), Some(DeltaOperation::Retain(o_retain))) => {
                     let composed_attrs = transform_op_attribute(&next_op1, &next_op2)?;
                     match retain.cmp(o_retain) {
                         Ordering::Less => {
                             a_prime.retain(retain.n, composed_attrs.clone());
                             b_prime.retain(retain.n, composed_attrs.clone());
-                            next_op2 = Some(Operation::retain(o_retain.n - retain.n));
+                            next_op2 = Some(DeltaOperation::retain(o_retain.n - retain.n));
                             next_op1 = ops1.next();
                         }
                         Ordering::Equal => {
@@ -413,14 +414,14 @@ where
                         Ordering::Greater => {
                             a_prime.retain(o_retain.n, composed_attrs.clone());
                             b_prime.retain(o_retain.n, composed_attrs.clone());
-                            next_op1 = Some(Operation::retain(retain.n - o_retain.n));
+                            next_op1 = Some(DeltaOperation::retain(retain.n - o_retain.n));
                             next_op2 = ops2.next();
                         }
                     };
                 }
-                (Some(Operation::Delete(i)), Some(Operation::Delete(j))) => match i.cmp(j) {
+                (Some(DeltaOperation::Delete(i)), Some(DeltaOperation::Delete(j))) => match i.cmp(j) {
                     Ordering::Less => {
-                        next_op2 = Some(Operation::delete(*j - *i));
+                        next_op2 = Some(DeltaOperation::delete(*j - *i));
                         next_op1 = ops1.next();
                     }
                     Ordering::Equal => {
@@ -428,15 +429,15 @@ where
                         next_op2 = ops2.next();
                     }
                     Ordering::Greater => {
-                        next_op1 = Some(Operation::delete(*i - *j));
+                        next_op1 = Some(DeltaOperation::delete(*i - *j));
                         next_op2 = ops2.next();
                     }
                 },
-                (Some(Operation::Delete(i)), Some(Operation::Retain(o_retain))) => {
+                (Some(DeltaOperation::Delete(i)), Some(DeltaOperation::Retain(o_retain))) => {
                     match i.cmp(o_retain) {
                         Ordering::Less => {
                             a_prime.delete(*i);
-                            next_op2 = Some(Operation::retain(o_retain.n - *i));
+                            next_op2 = Some(DeltaOperation::retain(o_retain.n - *i));
                             next_op1 = ops1.next();
                         }
                         Ordering::Equal => {
@@ -446,16 +447,16 @@ where
                         }
                         Ordering::Greater => {
                             a_prime.delete(o_retain.n);
-                            next_op1 = Some(Operation::delete(*i - o_retain.n));
+                            next_op1 = Some(DeltaOperation::delete(*i - o_retain.n));
                             next_op2 = ops2.next();
                         }
                     };
                 }
-                (Some(Operation::Retain(retain)), Some(Operation::Delete(j))) => {
+                (Some(DeltaOperation::Retain(retain)), Some(DeltaOperation::Delete(j))) => {
                     match retain.cmp(j) {
                         Ordering::Less => {
                             b_prime.delete(retain.n);
-                            next_op2 = Some(Operation::delete(*j - retain.n));
+                            next_op2 = Some(DeltaOperation::delete(*j - retain.n));
                             next_op1 = ops1.next();
                         }
                         Ordering::Equal => {
@@ -465,7 +466,7 @@ where
                         }
                         Ordering::Greater => {
                             b_prime.delete(*j);
-                            next_op1 = Some(Operation::retain(retain.n - *j));
+                            next_op1 = Some(DeltaOperation::retain(retain.n - *j));
                             next_op2 = ops2.next();
                         }
                     };
@@ -476,16 +477,16 @@ where
     }
 
     fn invert(&self, other: &Self) -> Self {
-        let mut inverted = Operations::default();
+        let mut inverted = DeltaOperations::default();
         let mut index = 0;
         for op in &self.ops {
             let len: usize = op.len() as usize;
             match op {
-                Operation::Delete(n) => {
+                DeltaOperation::Delete(n) => {
                     invert_other(&mut inverted, other, op, index, index + *n);
                     index += len;
                 }
-                Operation::Retain(_) => {
+                DeltaOperation::Retain(_) => {
                     match op.has_attribute() {
                         true => invert_other(&mut inverted, other, op, index, index + len),
                         false => {
@@ -496,7 +497,7 @@ where
                     }
                     index += len;
                 }
-                Operation::Insert(_) => {
+                DeltaOperation::Insert(_) => {
                     // tracing::trace!("invert insert: {} by delete {}", op, len);
                     inverted.delete(len as usize);
                 }
@@ -507,7 +508,7 @@ where
 }
 
 /// Removes trailing retain operation with empty attributes, if present.
-pub fn trim<T>(delta: &mut Operations<T>)
+pub fn trim<T>(delta: &mut DeltaOperations<T>)
 where
     T: OperationAttributes,
 {
@@ -519,20 +520,20 @@ where
 }
 
 fn invert_other<T: OperationAttributes>(
-    base: &mut Operations<T>,
-    other: &Operations<T>,
-    operation: &Operation<T>,
+    base: &mut DeltaOperations<T>,
+    other: &DeltaOperations<T>,
+    operation: &DeltaOperation<T>,
     start: usize,
     end: usize,
 ) {
     tracing::trace!("invert op: {} [{}:{}]", operation, start, end);
     let other_ops = OperationIterator::from_interval(other, Interval::new(start, end)).ops();
     other_ops.into_iter().for_each(|other_op| match operation {
-        Operation::Delete(_n) => {
+        DeltaOperation::Delete(_n) => {
             // tracing::trace!("invert delete: {} by add {}", n, other_op);
             base.add(other_op);
         }
-        Operation::Retain(_retain) => {
+        DeltaOperation::Retain(_retain) => {
             tracing::trace!(
                 "invert attributes: {:?}, {:?}",
                 operation.get_attributes(),
@@ -541,15 +542,15 @@ fn invert_other<T: OperationAttributes>(
             let inverted_attrs = operation.get_attributes().invert(&other_op.get_attributes());
             base.retain(other_op.len(), inverted_attrs);
         }
-        Operation::Insert(_) => {
+        DeltaOperation::Insert(_) => {
             log::error!("Impossible to here. Insert operation should be treated as delete")
         }
     });
 }
 
 fn transform_op_attribute<T: OperationAttributes>(
-    left: &Option<Operation<T>>,
-    right: &Option<Operation<T>>,
+    left: &Option<DeltaOperation<T>>,
+    right: &Option<DeltaOperation<T>>,
 ) -> Result<T, OTError> {
     if left.is_none() {
         if right.is_none() {
@@ -563,7 +564,7 @@ fn transform_op_attribute<T: OperationAttributes>(
     Ok(left.transform(&right)?.0)
 }
 
-impl<T> Operations<T>
+impl<T> DeltaOperations<T>
 where
     T: OperationAttributes + DeserializeOwned,
 {
@@ -571,11 +572,11 @@ where
     ///
     /// ```
     /// use lib_ot::core::OperationBuilder;
-    /// use lib_ot::text_delta::{TextDelta};
+    /// use lib_ot::text_delta::{TextOperations};
     /// let json = r#"[
     ///     {"retain":7,"attributes":{"bold":null}}
     ///  ]"#;
-    /// let delta = TextDelta::from_json(json).unwrap();
+    /// let delta = TextOperations::from_json(json).unwrap();
     /// assert_eq!(delta.json_str(), r#"[{"retain":7,"attributes":{"bold":null}}]"#);
     /// ```
     pub fn from_json(json: &str) -> Result<Self, OTError> {
@@ -595,7 +596,7 @@ where
     }
 }
 
-impl<T> Operations<T>
+impl<T> DeltaOperations<T>
 where
     T: OperationAttributes + serde::Serialize,
 {
@@ -616,36 +617,36 @@ where
     }
 }
 
-impl<T> FromStr for Operations<T>
+impl<T> FromStr for DeltaOperations<T>
 where
     T: OperationAttributes,
 {
     type Err = ();
 
-    fn from_str(s: &str) -> Result<Operations<T>, Self::Err> {
-        let mut delta = Operations::with_capacity(1);
-        delta.add(Operation::Insert(s.into()));
+    fn from_str(s: &str) -> Result<DeltaOperations<T>, Self::Err> {
+        let mut delta = DeltaOperations::with_capacity(1);
+        delta.add(DeltaOperation::Insert(s.into()));
         Ok(delta)
     }
 }
 
-impl<T> std::convert::TryFrom<Vec<u8>> for Operations<T>
+impl<T> std::convert::TryFrom<Vec<u8>> for DeltaOperations<T>
 where
     T: OperationAttributes + DeserializeOwned,
 {
     type Error = OTError;
     fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
-        Operations::from_bytes(bytes)
+        DeltaOperations::from_bytes(bytes)
     }
 }
 
-impl<T> std::convert::TryFrom<Bytes> for Operations<T>
+impl<T> std::convert::TryFrom<Bytes> for DeltaOperations<T>
 where
     T: OperationAttributes + DeserializeOwned,
 {
     type Error = OTError;
 
     fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
-        Operations::from_bytes(&bytes)
+        DeltaOperations::from_bytes(&bytes)
     }
 }

+ 6 - 6
shared-lib/lib-ot/src/core/delta/ops_serde.rs

@@ -1,5 +1,5 @@
 use crate::core::delta::operation::OperationAttributes;
-use crate::core::delta::Operations;
+use crate::core::delta::DeltaOperations;
 use serde::{
     de::{SeqAccess, Visitor},
     ser::SerializeSeq,
@@ -7,7 +7,7 @@ use serde::{
 };
 use std::{fmt, marker::PhantomData};
 
-impl<T> Serialize for Operations<T>
+impl<T> Serialize for DeltaOperations<T>
 where
     T: OperationAttributes + Serialize,
 {
@@ -23,11 +23,11 @@ where
     }
 }
 
-impl<'de, T> Deserialize<'de> for Operations<T>
+impl<'de, T> Deserialize<'de> for DeltaOperations<T>
 where
     T: OperationAttributes + Deserialize<'de>,
 {
-    fn deserialize<D>(deserializer: D) -> Result<Operations<T>, D::Error>
+    fn deserialize<D>(deserializer: D) -> Result<DeltaOperations<T>, D::Error>
     where
         D: Deserializer<'de>,
     {
@@ -37,7 +37,7 @@ where
         where
             T: OperationAttributes + Deserialize<'de>,
         {
-            type Value = Operations<T>;
+            type Value = DeltaOperations<T>;
 
             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                 formatter.write_str("a sequence")
@@ -48,7 +48,7 @@ where
             where
                 A: SeqAccess<'de>,
             {
-                let mut o = Operations::default();
+                let mut o = DeltaOperations::default();
                 while let Some(op) = seq.next_element()? {
                     o.add(op);
                 }

+ 11 - 8
shared-lib/lib-ot/src/core/node_tree/node.rs

@@ -1,9 +1,9 @@
 use super::node_serde::*;
-use crate::core::attributes::{AttributeKey, AttributeValue, Attributes};
+use crate::core::attributes::{AttributeHashMap, AttributeKey, AttributeValue};
 use crate::core::NodeBody::Delta;
 use crate::core::OperationTransform;
 use crate::errors::OTError;
-use crate::text_delta::TextDelta;
+use crate::text_delta::TextOperations;
 use serde::{Deserialize, Serialize};
 
 #[derive(Default, Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
@@ -11,9 +11,9 @@ pub struct NodeData {
     #[serde(rename = "type")]
     pub node_type: String,
 
-    #[serde(skip_serializing_if = "Attributes::is_empty")]
+    #[serde(skip_serializing_if = "AttributeHashMap::is_empty")]
     #[serde(default)]
-    pub attributes: Attributes,
+    pub attributes: AttributeHashMap,
 
     #[serde(serialize_with = "serialize_body")]
     #[serde(deserialize_with = "deserialize_body")]
@@ -94,7 +94,7 @@ impl NodeDataBuilder {
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub enum NodeBody {
     Empty,
-    Delta(TextDelta),
+    Delta(TextOperations),
 }
 
 impl std::default::Default for NodeBody {
@@ -159,7 +159,10 @@ impl OperationTransform for NodeBody {
 #[derive(Debug, Clone, Serialize, Deserialize)]
 #[serde(rename_all = "snake_case")]
 pub enum NodeBodyChangeset {
-    Delta { delta: TextDelta, inverted: TextDelta },
+    Delta {
+        delta: TextOperations,
+        inverted: TextOperations,
+    },
 }
 
 impl NodeBodyChangeset {
@@ -179,14 +182,14 @@ impl NodeBodyChangeset {
 pub struct Node {
     pub node_type: String,
     pub body: NodeBody,
-    pub attributes: Attributes,
+    pub attributes: AttributeHashMap,
 }
 
 impl Node {
     pub fn new(node_type: &str) -> Node {
         Node {
             node_type: node_type.into(),
-            attributes: Attributes::new(),
+            attributes: AttributeHashMap::new(),
             body: NodeBody::Empty,
         }
     }

+ 3 - 3
shared-lib/lib-ot/src/core/node_tree/node_serde.rs

@@ -1,5 +1,5 @@
 use super::NodeBody;
-use crate::text_delta::TextDelta;
+use crate::text_delta::TextOperations;
 use serde::de::{self, MapAccess, Visitor};
 use serde::ser::SerializeMap;
 use serde::{Deserializer, Serializer};
@@ -37,7 +37,7 @@ where
         where
             A: de::SeqAccess<'de>,
         {
-            let mut delta = TextDelta::default();
+            let mut delta = TextOperations::default();
             while let Some(op) = seq.next_element()? {
                 delta.add(op);
             }
@@ -49,7 +49,7 @@ where
         where
             V: MapAccess<'de>,
         {
-            let mut delta: Option<TextDelta> = None;
+            let mut delta: Option<TextOperations> = None;
             while let Some(key) = map.next_key()? {
                 match key {
                     "delta" => {

+ 9 - 9
shared-lib/lib-ot/src/core/node_tree/operation.rs

@@ -1,4 +1,4 @@
-use crate::core::attributes::Attributes;
+use crate::core::attributes::AttributeHashMap;
 use crate::core::{NodeBodyChangeset, NodeData, Path};
 use crate::errors::OTError;
 use serde::{Deserialize, Serialize};
@@ -13,8 +13,8 @@ pub enum NodeOperation {
     #[serde(rename = "update-attribute")]
     UpdateAttributes {
         path: Path,
-        new: Attributes,
-        old: Attributes,
+        new: AttributeHashMap,
+        old: AttributeHashMap,
     },
 
     #[serde(rename = "update-body")]
@@ -121,11 +121,11 @@ impl NodeOperation {
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize, Default)]
-pub struct NodeOperationList {
+pub struct NodeOperations {
     operations: Vec<Rc<NodeOperation>>,
 }
 
-impl NodeOperationList {
+impl NodeOperations {
     pub fn into_inner(self) -> Vec<Rc<NodeOperation>> {
         self.operations
     }
@@ -135,7 +135,7 @@ impl NodeOperationList {
     }
 }
 
-impl std::ops::Deref for NodeOperationList {
+impl std::ops::Deref for NodeOperations {
     type Target = Vec<Rc<NodeOperation>>;
 
     fn deref(&self) -> &Self::Target {
@@ -143,19 +143,19 @@ impl std::ops::Deref for NodeOperationList {
     }
 }
 
-impl std::ops::DerefMut for NodeOperationList {
+impl std::ops::DerefMut for NodeOperations {
     fn deref_mut(&mut self) -> &mut Self::Target {
         &mut self.operations
     }
 }
 
-impl std::convert::From<Vec<NodeOperation>> for NodeOperationList {
+impl std::convert::From<Vec<NodeOperation>> for NodeOperations {
     fn from(operations: Vec<NodeOperation>) -> Self {
         Self::new(operations)
     }
 }
 
-impl NodeOperationList {
+impl NodeOperations {
     pub fn new(operations: Vec<NodeOperation>) -> Self {
         Self {
             operations: operations.into_iter().map(Rc::new).collect(),

+ 3 - 3
shared-lib/lib-ot/src/core/node_tree/operation_serde.rs

@@ -1,5 +1,5 @@
 use crate::core::{NodeBodyChangeset, Path};
-use crate::text_delta::TextDelta;
+use crate::text_delta::TextOperations;
 use serde::de::{self, MapAccess, Visitor};
 use serde::ser::SerializeMap;
 use serde::{Deserializer, Serializer};
@@ -88,8 +88,8 @@ where
 
 #[allow(dead_code)]
 struct DeltaBodyChangeset<E> {
-    delta: Option<TextDelta>,
-    inverted: Option<TextDelta>,
+    delta: Option<TextOperations>,
+    inverted: Option<TextOperations>,
     error: PhantomData<E>,
 }
 

+ 8 - 8
shared-lib/lib-ot/src/core/node_tree/transaction.rs

@@ -1,14 +1,14 @@
-use crate::core::attributes::Attributes;
+use crate::core::attributes::AttributeHashMap;
 use crate::core::{NodeData, NodeOperation, NodeTree, Path};
 use crate::errors::OTError;
 use indextree::NodeId;
 use std::rc::Rc;
 
-use super::{NodeBodyChangeset, NodeOperationList};
+use super::{NodeBodyChangeset, NodeOperations};
 
 #[derive(Debug, Clone, Default)]
 pub struct Transaction {
-    operations: NodeOperationList,
+    operations: NodeOperations,
 }
 
 impl Transaction {
@@ -16,7 +16,7 @@ impl Transaction {
         Self::default()
     }
 
-    pub fn from_operations<T: Into<NodeOperationList>>(operations: T) -> Self {
+    pub fn from_operations<T: Into<NodeOperations>>(operations: T) -> Self {
         Self {
             operations: operations.into(),
         }
@@ -66,14 +66,14 @@ impl std::ops::DerefMut for Transaction {
 
 pub struct TransactionBuilder<'a> {
     node_tree: &'a NodeTree,
-    operations: NodeOperationList,
+    operations: NodeOperations,
 }
 
 impl<'a> TransactionBuilder<'a> {
     pub fn new(node_tree: &'a NodeTree) -> TransactionBuilder {
         TransactionBuilder {
             node_tree,
-            operations: NodeOperationList::default(),
+            operations: NodeOperations::default(),
         }
     }
 
@@ -132,10 +132,10 @@ impl<'a> TransactionBuilder<'a> {
         self.insert_nodes_at_path(path, vec![node])
     }
 
-    pub fn update_attributes_at_path(mut self, path: &Path, attributes: Attributes) -> Self {
+    pub fn update_attributes_at_path(mut self, path: &Path, attributes: AttributeHashMap) -> Self {
         match self.node_tree.get_node_at_path(path) {
             Some(node) => {
-                let mut old_attributes = Attributes::new();
+                let mut old_attributes = AttributeHashMap::new();
                 for key in attributes.keys() {
                     let old_attrs = &node.attributes;
                     if let Some(value) = old_attrs.get(key.as_str()) {

+ 6 - 6
shared-lib/lib-ot/src/core/node_tree/tree.rs

@@ -1,10 +1,10 @@
-use crate::core::attributes::Attributes;
+use crate::core::attributes::AttributeHashMap;
 use crate::core::{Node, NodeBodyChangeset, NodeData, NodeOperation, OperationTransform, Path, Transaction};
 use crate::errors::{ErrorBuilder, OTError, OTErrorCode};
 use indextree::{Arena, Children, FollowingSiblings, NodeId};
 use std::rc::Rc;
 
-use super::NodeOperationList;
+use super::NodeOperations;
 
 ///
 pub struct NodeTree {
@@ -26,11 +26,11 @@ impl NodeTree {
     }
 
     pub fn from_bytes(root_name: &str, bytes: Vec<u8>) -> Result<Self, OTError> {
-        let operations = NodeOperationList::from_bytes(bytes)?;
+        let operations = NodeOperations::from_bytes(bytes)?;
         Self::from_operations(root_name, operations)
     }
 
-    pub fn from_operations(root_name: &str, operations: NodeOperationList) -> Result<Self, OTError> {
+    pub fn from_operations(root_name: &str, operations: NodeOperations) -> Result<Self, OTError> {
         let mut node_tree = NodeTree::new(root_name);
         for operation in operations.into_inner().into_iter() {
             let _ = node_tree.apply_op(operation)?;
@@ -252,9 +252,9 @@ impl NodeTree {
         }
     }
 
-    fn update_attributes(&mut self, path: &Path, attributes: Attributes) -> Result<(), OTError> {
+    fn update_attributes(&mut self, path: &Path, attributes: AttributeHashMap) -> Result<(), OTError> {
         self.mut_node_at_path(path, |node| {
-            let new_attributes = Attributes::compose(&node.attributes, &attributes)?;
+            let new_attributes = AttributeHashMap::compose(&node.attributes, &attributes)?;
             node.attributes = new_attributes;
             Ok(())
         })

+ 4 - 4
shared-lib/lib-ot/src/text_delta/attributes.rs

@@ -1,5 +1,5 @@
 #![allow(non_snake_case)]
-use crate::core::{AttributeEntry, AttributeKey, Attributes};
+use crate::core::{AttributeEntry, AttributeHashMap, AttributeKey};
 use crate::text_delta::TextOperation;
 use crate::{inline_attribute_entry, inline_list_attribute_entry};
 use lazy_static::lazy_static;
@@ -8,11 +8,11 @@ use std::{collections::HashSet, iter::FromIterator};
 use strum_macros::{AsRefStr, Display, EnumString};
 
 #[inline(always)]
-pub fn empty_attributes() -> Attributes {
-    Attributes::default()
+pub fn empty_attributes() -> AttributeHashMap {
+    AttributeHashMap::default()
 }
 
-pub fn attributes_except_header(op: &TextOperation) -> Attributes {
+pub fn attributes_except_header(op: &TextOperation) -> AttributeHashMap {
     let mut attributes = op.get_attributes();
     attributes.remove_key(BuildInTextAttributeKey::Header);
     attributes

+ 4 - 4
shared-lib/lib-ot/src/text_delta/delta.rs

@@ -1,5 +1,5 @@
-use crate::core::{Attributes, Operation, OperationBuilder, Operations};
+use crate::core::{AttributeHashMap, DeltaOperation, DeltaOperations, OperationBuilder};
 
-pub type TextDelta = Operations<Attributes>;
-pub type TextDeltaBuilder = OperationBuilder<Attributes>;
-pub type TextOperation = Operation<Attributes>;
+pub type TextOperations = DeltaOperations<AttributeHashMap>;
+pub type TextOperationBuilder = OperationBuilder<AttributeHashMap>;
+pub type TextOperation = DeltaOperation<AttributeHashMap>;

+ 2 - 2
shared-lib/lib-ot/tests/node/editor_test.rs

@@ -2,7 +2,7 @@ use super::script::{NodeScript::*, *};
 use lib_ot::core::AttributeBuilder;
 use lib_ot::{
     core::{NodeData, Path},
-    text_delta::TextDeltaBuilder,
+    text_delta::TextOperationBuilder,
 };
 
 #[test]
@@ -11,7 +11,7 @@ fn editor_deserialize_node_test() {
     let node: NodeData = serde_json::from_str(EXAMPLE_JSON).unwrap();
     let path: Path = 0.into();
 
-    let expected_delta = TextDeltaBuilder::new()
+    let expected_delta = TextOperationBuilder::new()
         .insert("👋 ")
         .insert_with_attributes(
             "Welcome to ",

+ 2 - 2
shared-lib/lib-ot/tests/node/operation_test.rs

@@ -3,7 +3,7 @@ use crate::node::script::NodeTest;
 use lib_ot::core::{AttributeBuilder, Node};
 use lib_ot::{
     core::{NodeBodyChangeset, NodeData, NodeDataBuilder, NodeOperation, Path},
-    text_delta::TextDeltaBuilder,
+    text_delta::TextOperationBuilder,
 };
 
 #[test]
@@ -48,7 +48,7 @@ fn operation_update_node_attributes_serde_test() {
 
 #[test]
 fn operation_update_node_body_serialize_test() {
-    let delta = TextDeltaBuilder::new().insert("AppFlowy...").build();
+    let delta = TextOperationBuilder::new().insert("AppFlowy...").build();
     let inverted = delta.invert_str("");
     let changeset = NodeBodyChangeset::Delta { delta, inverted };
     let insert = NodeOperation::UpdateBody {

+ 4 - 4
shared-lib/lib-ot/tests/node/script.rs

@@ -1,8 +1,8 @@
 use lib_ot::core::{Node, Transaction};
 use lib_ot::{
-    core::attributes::Attributes,
+    core::attributes::AttributeHashMap,
     core::{NodeBody, NodeBodyChangeset, NodeData, NodeTree, Path, TransactionBuilder},
-    text_delta::TextDelta,
+    text_delta::TextOperations,
 };
 use std::collections::HashMap;
 
@@ -14,7 +14,7 @@ pub enum NodeScript {
     },
     UpdateAttributes {
         path: Path,
-        attributes: Attributes,
+        attributes: AttributeHashMap,
     },
     UpdateBody {
         path: Path,
@@ -38,7 +38,7 @@ pub enum NodeScript {
     },
     AssertNodeDelta {
         path: Path,
-        expected: TextDelta,
+        expected: TextOperations,
     },
 }
 

+ 3 - 3
shared-lib/lib-ot/tests/node/tree_test.rs

@@ -4,7 +4,7 @@ use lib_ot::core::NodeBody;
 use lib_ot::core::NodeBodyChangeset;
 use lib_ot::core::OperationTransform;
 use lib_ot::core::{NodeData, NodeDataBuilder, Path};
-use lib_ot::text_delta::TextDeltaBuilder;
+use lib_ot::text_delta::TextOperationBuilder;
 
 #[test]
 fn node_insert_test() {
@@ -293,8 +293,8 @@ fn node_update_body_test() {
     let path: Path = 0.into();
 
     let s = "Hello".to_owned();
-    let init_delta = TextDeltaBuilder::new().insert(&s).build();
-    let delta = TextDeltaBuilder::new().retain(s.len()).insert(" AppFlowy").build();
+    let init_delta = TextOperationBuilder::new().insert(&s).build();
+    let delta = TextOperationBuilder::new().retain(s.len()).insert(" AppFlowy").build();
     let inverted = delta.invert(&init_delta);
     let expected = init_delta.compose(&delta).unwrap();