Forráskód Böngészése

chore: impl view data processor

appflowy 3 éve
szülő
commit
1b80934899
32 módosított fájl, 257 hozzáadás és 145 törlés
  1. 8 8
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pb.dart
  2. 2 2
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbjson.dart
  3. 2 0
      frontend/rust-lib/Cargo.lock
  4. 2 2
      frontend/rust-lib/dart-ffi/Cargo.toml
  5. 4 4
      frontend/rust-lib/flowy-block/src/block_editor.rs
  6. 1 1
      frontend/rust-lib/flowy-block/src/event_handler.rs
  7. 4 4
      frontend/rust-lib/flowy-block/src/manager.rs
  8. 4 4
      frontend/rust-lib/flowy-block/src/queue.rs
  9. 1 1
      frontend/rust-lib/flowy-block/tests/document/edit_script.rs
  10. 1 1
      frontend/rust-lib/flowy-block/tests/editor/attribute_test.rs
  11. 14 14
      frontend/rust-lib/flowy-block/tests/editor/mod.rs
  12. 3 3
      frontend/rust-lib/flowy-block/tests/editor/serde_test.rs
  13. 1 0
      frontend/rust-lib/flowy-folder/Cargo.toml
  14. 27 17
      frontend/rust-lib/flowy-folder/src/manager.rs
  15. 17 16
      frontend/rust-lib/flowy-folder/src/services/view/controller.rs
  16. 25 22
      frontend/rust-lib/flowy-grid/src/manager.rs
  17. 4 0
      frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
  18. 1 1
      frontend/rust-lib/flowy-sdk/Cargo.toml
  19. 88 2
      frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs
  20. 4 3
      frontend/rust-lib/flowy-sdk/src/lib.rs
  21. 2 2
      shared-lib/flowy-collaboration/src/client_document/default/mod.rs
  22. 4 4
      shared-lib/flowy-collaboration/src/client_document/document_pad.rs
  23. 4 0
      shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs
  24. 2 2
      shared-lib/flowy-collaboration/src/entities/document_info.rs
  25. 1 1
      shared-lib/flowy-collaboration/src/entities/revision.rs
  26. 23 23
      shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs
  27. 1 1
      shared-lib/flowy-collaboration/src/protobuf/proto/document_info.proto
  28. 1 1
      shared-lib/flowy-collaboration/src/server_document/document_pad.rs
  29. 1 1
      shared-lib/flowy-collaboration/src/server_folder/folder_pad.rs
  30. 2 2
      shared-lib/flowy-collaboration/src/util.rs
  31. 1 1
      shared-lib/flowy-folder-data-model/src/entities/view.rs
  32. 2 2
      shared-lib/lib-ot/src/core/delta/delta.rs

+ 8 - 8
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pb.dart

@@ -230,21 +230,21 @@ class ResetBlockParams extends $pb.GeneratedMessage {
 class BlockDelta extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlockDelta', createEmptyInstance: create)
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blockId')
-    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deltaJson')
+    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deltaStr')
     ..hasRequiredFields = false
   ;
 
   BlockDelta._() : super();
   factory BlockDelta({
     $core.String? blockId,
-    $core.String? deltaJson,
+    $core.String? deltaStr,
   }) {
     final _result = create();
     if (blockId != null) {
       _result.blockId = blockId;
     }
-    if (deltaJson != null) {
-      _result.deltaJson = deltaJson;
+    if (deltaStr != null) {
+      _result.deltaStr = deltaStr;
     }
     return _result;
   }
@@ -279,13 +279,13 @@ class BlockDelta extends $pb.GeneratedMessage {
   void clearBlockId() => clearField(1);
 
   @$pb.TagNumber(2)
-  $core.String get deltaJson => $_getSZ(1);
+  $core.String get deltaStr => $_getSZ(1);
   @$pb.TagNumber(2)
-  set deltaJson($core.String v) { $_setString(1, v); }
+  set deltaStr($core.String v) { $_setString(1, v); }
   @$pb.TagNumber(2)
-  $core.bool hasDeltaJson() => $_has(1);
+  $core.bool hasDeltaStr() => $_has(1);
   @$pb.TagNumber(2)
-  void clearDeltaJson() => clearField(2);
+  void clearDeltaStr() => clearField(2);
 }
 
 class NewDocUser extends $pb.GeneratedMessage {

+ 2 - 2
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/document_info.pbjson.dart

@@ -48,12 +48,12 @@ const BlockDelta$json = const {
   '1': 'BlockDelta',
   '2': const [
     const {'1': 'block_id', '3': 1, '4': 1, '5': 9, '10': 'blockId'},
-    const {'1': 'delta_json', '3': 2, '4': 1, '5': 9, '10': 'deltaJson'},
+    const {'1': 'delta_str', '3': 2, '4': 1, '5': 9, '10': 'deltaStr'},
   ],
 };
 
 /// Descriptor for `BlockDelta`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List blockDeltaDescriptor = $convert.base64Decode('CgpCbG9ja0RlbHRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEh0KCmRlbHRhX2pzb24YAiABKAlSCWRlbHRhSnNvbg==');
+final $typed_data.Uint8List blockDeltaDescriptor = $convert.base64Decode('CgpCbG9ja0RlbHRhEhkKCGJsb2NrX2lkGAEgASgJUgdibG9ja0lkEhsKCWRlbHRhX3N0chgCIAEoCVIIZGVsdGFTdHI=');
 @$core.Deprecated('Use newDocUserDescriptor instead')
 const NewDocUser$json = const {
   '1': 'NewDocUser',

+ 2 - 0
frontend/rust-lib/Cargo.lock

@@ -986,6 +986,7 @@ dependencies = [
 name = "flowy-folder"
 version = "0.1.0"
 dependencies = [
+ "async-trait",
  "bincode",
  "bytes",
  "chrono",
@@ -1133,6 +1134,7 @@ dependencies = [
 name = "flowy-sdk"
 version = "0.1.0"
 dependencies = [
+ "async-trait",
  "bincode",
  "bytes",
  "claim 0.5.0",

+ 2 - 2
frontend/rust-lib/dart-ffi/Cargo.toml

@@ -7,8 +7,8 @@ edition = "2018"
 [lib]
 name = "dart_ffi"
 # this value will change depending on the target os
-# default cdylib
-crate-type = ["cdylib"]
+# default staticlib
+crate-type = ["staticlib"]
 
 
 [dependencies]

+ 4 - 4
frontend/rust-lib/flowy-block/src/block_editor.rs

@@ -140,9 +140,9 @@ impl ClientBlockEditor {
         Ok(())
     }
 
-    pub async fn block_json(&self) -> FlowyResult<String> {
+    pub async fn delta_str(&self) -> FlowyResult<String> {
         let (ret, rx) = oneshot::channel::<CollaborateResult<String>>();
-        let msg = EditorCommand::ReadBlockJson { ret };
+        let msg = EditorCommand::ReadDeltaStr { ret };
         let _ = self.edit_cmd_tx.send(msg).await;
         let json = rx.await.map_err(internal_error)??;
         Ok(json)
@@ -196,7 +196,7 @@ fn spawn_edit_queue(
 impl ClientBlockEditor {
     pub async fn doc_json(&self) -> FlowyResult<String> {
         let (ret, rx) = oneshot::channel::<CollaborateResult<String>>();
-        let msg = EditorCommand::ReadBlockJson { ret };
+        let msg = EditorCommand::ReadDeltaStr { ret };
         let _ = self.edit_cmd_tx.send(msg).await;
         let s = rx.await.map_err(internal_error)??;
         Ok(s)
@@ -226,7 +226,7 @@ impl RevisionObjectBuilder for BlockInfoBuilder {
 
         Result::<BlockInfo, FlowyError>::Ok(BlockInfo {
             block_id: object_id.to_owned(),
-            text: delta.to_delta_json(),
+            text: delta.to_delta_str(),
             rev_id,
             base_rev_id,
         })

+ 1 - 1
frontend/rust-lib/flowy-block/src/event_handler.rs

@@ -21,7 +21,7 @@ pub(crate) async fn export_handler(
 ) -> DataResult<ExportData, FlowyError> {
     let params: ExportParams = data.into_inner().try_into()?;
     let editor = manager.open_block(&params.view_id).await?;
-    let delta_json = editor.block_json().await?;
+    let delta_json = editor.delta_str().await?;
     data_result(ExportData {
         data: delta_json,
         export_type: params.export_type,

+ 4 - 4
frontend/rust-lib/flowy-block/src/manager.rs

@@ -63,7 +63,7 @@ impl BlockManager {
     }
 
     #[tracing::instrument(level = "debug", skip(self, doc_id), fields(doc_id), err)]
-    pub fn delete<T: AsRef<str>>(&self, doc_id: T) -> Result<(), FlowyError> {
+    pub fn delete_block<T: AsRef<str>>(&self, doc_id: T) -> Result<(), FlowyError> {
         let doc_id = doc_id.as_ref();
         tracing::Span::current().record("doc_id", &doc_id);
         self.block_editors.remove(doc_id);
@@ -73,11 +73,11 @@ impl BlockManager {
     #[tracing::instrument(level = "debug", skip(self, delta), fields(doc_id = %delta.block_id), err)]
     pub async fn receive_local_delta(&self, delta: BlockDelta) -> Result<BlockDelta, FlowyError> {
         let editor = self.get_block_editor(&delta.block_id).await?;
-        let _ = editor.compose_local_delta(Bytes::from(delta.delta_json)).await?;
-        let document_json = editor.block_json().await?;
+        let _ = editor.compose_local_delta(Bytes::from(delta.delta_str)).await?;
+        let document_json = editor.delta_str().await?;
         Ok(BlockDelta {
             block_id: delta.block_id.clone(),
-            delta_json: document_json,
+            delta_str: document_json,
         })
     }
 

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

@@ -161,8 +161,8 @@ impl EditBlockQueue {
                 let _ = self.save_local_delta(delta, md5).await?;
                 let _ = ret.send(Ok(()));
             }
-            EditorCommand::ReadBlockJson { ret } => {
-                let data = self.document.read().await.to_json();
+            EditorCommand::ReadDeltaStr { ret } => {
+                let data = self.document.read().await.delta_str();
                 let _ = ret.send(Ok(data));
             }
             EditorCommand::ReadBlockDelta { ret } => {
@@ -265,7 +265,7 @@ pub(crate) enum EditorCommand {
     Redo {
         ret: Ret<()>,
     },
-    ReadBlockJson {
+    ReadDeltaStr {
         ret: Ret<String>,
     },
     #[allow(dead_code)]
@@ -289,7 +289,7 @@ impl std::fmt::Debug for EditorCommand {
             EditorCommand::CanRedo { .. } => "CanRedo",
             EditorCommand::Undo { .. } => "Undo",
             EditorCommand::Redo { .. } => "Redo",
-            EditorCommand::ReadBlockJson { .. } => "ReadDocumentAsJson",
+            EditorCommand::ReadDeltaStr { .. } => "ReadDeltaStr",
             EditorCommand::ReadBlockDelta { .. } => "ReadDocumentAsDelta",
         };
         f.write_str(s)

+ 1 - 1
frontend/rust-lib/flowy-block/tests/document/edit_script.rs

@@ -77,7 +77,7 @@ impl EditorTest {
                 let delta = self.editor.doc_delta().await.unwrap();
                 if expected_delta != delta {
                     eprintln!("✅ expect: {}", expected,);
-                    eprintln!("❌ receive: {}", delta.to_delta_json());
+                    eprintln!("❌ receive: {}", delta.to_delta_str());
                 }
                 assert_eq!(expected_delta, delta);
             }

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

@@ -774,7 +774,7 @@ fn delta_compose() {
         delta = delta.compose(&d).unwrap();
     }
     assert_eq!(
-        delta.to_delta_json(),
+        delta.to_delta_str(),
         r#"[{"insert":"a"},{"insert":"\n","attributes":{"list":"unchecked"}},{"insert":"\n"}]"#
     );
 

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

@@ -108,20 +108,20 @@ impl TestBuilder {
             TestOp::Insert(delta_i, s, index) => {
                 let document = &mut self.documents[*delta_i];
                 let delta = document.insert(*index, s).unwrap();
-                tracing::debug!("Insert delta: {}", delta.to_delta_json());
+                tracing::debug!("Insert delta: {}", delta.to_delta_str());
 
                 self.deltas.insert(*delta_i, Some(delta));
             }
             TestOp::Delete(delta_i, iv) => {
                 let document = &mut self.documents[*delta_i];
                 let delta = document.replace(*iv, "").unwrap();
-                tracing::trace!("Delete delta: {}", delta.to_delta_json());
+                tracing::trace!("Delete delta: {}", delta.to_delta_str());
                 self.deltas.insert(*delta_i, Some(delta));
             }
             TestOp::Replace(delta_i, iv, s) => {
                 let document = &mut self.documents[*delta_i];
                 let delta = document.replace(*iv, s).unwrap();
-                tracing::trace!("Replace delta: {}", delta.to_delta_json());
+                tracing::trace!("Replace delta: {}", delta.to_delta_str());
                 self.deltas.insert(*delta_i, Some(delta));
             }
             TestOp::InsertBold(delta_i, s, iv) => {
@@ -133,7 +133,7 @@ impl TestBuilder {
                 let document = &mut self.documents[*delta_i];
                 let attribute = RichTextAttribute::Bold(*enable);
                 let delta = document.format(*iv, attribute).unwrap();
-                tracing::trace!("Bold delta: {}", delta.to_delta_json());
+                tracing::trace!("Bold delta: {}", delta.to_delta_str());
                 self.deltas.insert(*delta_i, Some(delta));
             }
             TestOp::Italic(delta_i, iv, enable) => {
@@ -143,28 +143,28 @@ impl TestBuilder {
                     false => RichTextAttribute::Italic(false),
                 };
                 let delta = document.format(*iv, attribute).unwrap();
-                tracing::trace!("Italic delta: {}", delta.to_delta_json());
+                tracing::trace!("Italic delta: {}", delta.to_delta_str());
                 self.deltas.insert(*delta_i, Some(delta));
             }
             TestOp::Header(delta_i, iv, level) => {
                 let document = &mut self.documents[*delta_i];
                 let attribute = RichTextAttribute::Header(*level);
                 let delta = document.format(*iv, attribute).unwrap();
-                tracing::trace!("Header delta: {}", delta.to_delta_json());
+                tracing::trace!("Header delta: {}", delta.to_delta_str());
                 self.deltas.insert(*delta_i, Some(delta));
             }
             TestOp::Link(delta_i, iv, link) => {
                 let document = &mut self.documents[*delta_i];
                 let attribute = RichTextAttribute::Link(link.to_owned());
                 let delta = document.format(*iv, attribute).unwrap();
-                tracing::trace!("Link delta: {}", delta.to_delta_json());
+                tracing::trace!("Link delta: {}", delta.to_delta_str());
                 self.deltas.insert(*delta_i, Some(delta));
             }
             TestOp::Bullet(delta_i, iv, enable) => {
                 let document = &mut self.documents[*delta_i];
                 let attribute = RichTextAttribute::Bullet(*enable);
                 let delta = document.format(*iv, attribute).unwrap();
-                tracing::debug!("Bullet delta: {}", delta.to_delta_json());
+                tracing::debug!("Bullet delta: {}", delta.to_delta_str());
 
                 self.deltas.insert(*delta_i, Some(delta));
             }
@@ -194,15 +194,15 @@ impl TestBuilder {
                 let delta_a = &self.documents[*delta_a_i].delta();
                 let delta_b = &self.documents[*delta_b_i].delta();
                 tracing::debug!("Invert: ");
-                tracing::debug!("a: {}", delta_a.to_delta_json());
-                tracing::debug!("b: {}", delta_b.to_delta_json());
+                tracing::debug!("a: {}", delta_a.to_delta_str());
+                tracing::debug!("b: {}", delta_b.to_delta_str());
 
                 let (_, b_prime) = delta_a.transform(delta_b).unwrap();
                 let undo = b_prime.invert(delta_a);
 
                 let new_delta = delta_a.compose(&b_prime).unwrap();
-                tracing::debug!("new delta: {}", new_delta.to_delta_json());
-                tracing::debug!("undo delta: {}", undo.to_delta_json());
+                tracing::debug!("new delta: {}", new_delta.to_delta_str());
+                tracing::debug!("undo delta: {}", undo.to_delta_str());
 
                 let new_delta_after_undo = new_delta.compose(&undo).unwrap();
 
@@ -226,7 +226,7 @@ impl TestBuilder {
             }
 
             TestOp::AssertDocJson(delta_i, expected) => {
-                let delta_json = self.documents[*delta_i].to_json();
+                let delta_json = self.documents[*delta_i].delta_str();
                 let expected_delta: RichTextDelta = serde_json::from_str(expected).unwrap();
                 let target_delta: RichTextDelta = serde_json::from_str(&delta_json).unwrap();
 
@@ -238,7 +238,7 @@ impl TestBuilder {
             }
 
             TestOp::AssertPrimeJson(doc_i, expected) => {
-                let prime_json = self.primes[*doc_i].as_ref().unwrap().to_delta_json();
+                let prime_json = self.primes[*doc_i].as_ref().unwrap().to_delta_str();
                 let expected_prime: RichTextDelta = serde_json::from_str(expected).unwrap();
                 let target_prime: RichTextDelta = serde_json::from_str(&prime_json).unwrap();
 

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

@@ -92,7 +92,7 @@ fn delta_deserialize_null_test() {
     attribute.value = RichTextAttributeValue(None);
     let delta2 = DeltaBuilder::new().retain_with_attributes(7, attribute.into()).build();
 
-    assert_eq!(delta2.to_delta_json(), r#"[{"retain":7,"attributes":{"bold":""}}]"#);
+    assert_eq!(delta2.to_delta_str(), r#"[{"retain":7,"attributes":{"bold":""}}]"#);
     assert_eq!(delta1, delta2);
 }
 
@@ -108,10 +108,10 @@ fn document_insert_serde_test() {
     let mut document = ClientDocument::new::<PlainDoc>();
     document.insert(0, "\n").unwrap();
     document.insert(0, "123").unwrap();
-    let json = document.to_json();
+    let json = document.delta_str();
     assert_eq!(r#"[{"insert":"123\n"}]"#, json);
     assert_eq!(
         r#"[{"insert":"123\n"}]"#,
-        ClientDocument::from_json(&json).unwrap().to_json()
+        ClientDocument::from_json(&json).unwrap().delta_str()
     );
 }

+ 1 - 0
frontend/rust-lib/flowy-folder/Cargo.toml

@@ -42,6 +42,7 @@ bytes = { version = "1.0" }
 crossbeam = "0.8"
 crossbeam-utils = "0.8"
 chrono = "0.4"
+async-trait = "0.1.52"
 
 [dev-dependencies]
 serial_test = "0.5.1"

+ 27 - 17
frontend/rust-lib/flowy-folder/src/manager.rs

@@ -1,17 +1,3 @@
-use bytes::Bytes;
-use chrono::Utc;
-use flowy_collaboration::client_document::default::{initial_quill_delta, initial_quill_delta_string, initial_read_me};
-use flowy_folder_data_model::user_default;
-use flowy_sync::RevisionWebSocket;
-use lazy_static::lazy_static;
-
-use flowy_block::BlockManager;
-use flowy_collaboration::{client_folder::FolderPad, entities::ws_data::ServerRevisionWSData};
-
-use flowy_collaboration::entities::revision::{RepeatedRevision, Revision};
-use std::{collections::HashMap, convert::TryInto, fmt::Formatter, sync::Arc};
-use tokio::sync::RwLock as TokioRwLock;
-
 use crate::{
     dart_notification::{send_dart_notification, FolderNotification},
     entities::workspace::RepeatedWorkspace,
@@ -22,11 +8,22 @@ use crate::{
         TrashController, ViewController, WorkspaceController,
     },
 };
-
+use async_trait::async_trait;
+use bytes::Bytes;
+use chrono::Utc;
+use flowy_block::BlockManager;
+use flowy_collaboration::client_document::default::{initial_quill_delta, initial_quill_delta_string, initial_read_me};
+use flowy_collaboration::entities::revision::{RepeatedRevision, Revision};
+use flowy_collaboration::{client_folder::FolderPad, entities::ws_data::ServerRevisionWSData};
+use flowy_folder_data_model::entities::view::ViewDataType;
+use flowy_folder_data_model::user_default;
+use flowy_sync::RevisionWebSocket;
+use lazy_static::lazy_static;
+use std::{collections::HashMap, convert::TryInto, fmt::Formatter, sync::Arc};
+use tokio::sync::RwLock as TokioRwLock;
 lazy_static! {
     static ref INIT_FOLDER_FLAG: TokioRwLock<HashMap<String, bool>> = TokioRwLock::new(HashMap::new());
 }
-
 const FOLDER_ID: &str = "folder";
 const FOLDER_ID_SPLIT: &str = ":";
 #[derive(Clone)]
@@ -72,6 +69,7 @@ impl FolderManager {
         user: Arc<dyn WorkspaceUser>,
         cloud_service: Arc<dyn FolderCouldServiceV1>,
         database: Arc<dyn WorkspaceDatabase>,
+        data_processors: DataProcessorMap,
         block_manager: Arc<BlockManager>,
         web_socket: Arc<dyn RevisionWebSocket>,
     ) -> Self {
@@ -95,6 +93,7 @@ impl FolderManager {
             persistence.clone(),
             cloud_service.clone(),
             trash_controller.clone(),
+            data_processors,
             block_manager,
         ));
 
@@ -197,7 +196,7 @@ impl DefaultFolderBuilder {
         for app in workspace.apps.iter() {
             for (index, view) in app.belongings.iter().enumerate() {
                 let view_data = if index == 0 {
-                    initial_read_me().to_delta_json()
+                    initial_read_me().to_delta_str()
                 } else {
                     initial_quill_delta_string()
                 };
@@ -222,3 +221,14 @@ impl FolderManager {
         self.folder_editor.read().await.clone().unwrap()
     }
 }
+
+#[async_trait]
+pub trait ViewDataProcessor {
+    async fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FlowyResult<()>;
+    async fn delete_container(&self, view_id: &str) -> FlowyResult<()>;
+    async fn close_container(&self, view_id: &str) -> FlowyResult<()>;
+    async fn delta_str(&self, view_id: &str) -> FlowyResult<String>;
+    fn data_type(&self) -> ViewDataType;
+}
+
+pub type DataProcessorMap = Arc<HashMap<ViewDataType, Arc<dyn ViewDataProcessor + Send + Sync>>>;

+ 17 - 16
frontend/rust-lib/flowy-folder/src/services/view/controller.rs

@@ -6,8 +6,10 @@ use flowy_collaboration::entities::{
 
 use flowy_collaboration::client_document::default::initial_quill_delta_string;
 use futures::{FutureExt, StreamExt};
+use std::collections::HashMap;
 use std::{collections::HashSet, sync::Arc};
 
+use crate::manager::DataProcessorMap;
 use crate::{
     dart_notification::{send_dart_notification, FolderNotification},
     entities::{
@@ -23,6 +25,7 @@ use crate::{
 };
 use flowy_block::BlockManager;
 use flowy_database::kv::KV;
+use flowy_folder_data_model::entities::view::ViewDataType;
 use lib_infra::uuid;
 
 const LATEST_VIEW_ID: &str = "latest_view_id";
@@ -32,6 +35,7 @@ pub(crate) struct ViewController {
     cloud_service: Arc<dyn FolderCouldServiceV1>,
     persistence: Arc<FolderPersistence>,
     trash_controller: Arc<TrashController>,
+    data_processors: DataProcessorMap,
     block_manager: Arc<BlockManager>,
 }
 
@@ -40,15 +44,17 @@ impl ViewController {
         user: Arc<dyn WorkspaceUser>,
         persistence: Arc<FolderPersistence>,
         cloud_service: Arc<dyn FolderCouldServiceV1>,
-        trash_can: Arc<TrashController>,
-        document_manager: Arc<BlockManager>,
+        trash_controller: Arc<TrashController>,
+        data_processors: DataProcessorMap,
+        block_manager: Arc<BlockManager>,
     ) -> Self {
         Self {
             user,
             cloud_service,
             persistence,
-            trash_controller: trash_can,
-            block_manager: document_manager,
+            trash_controller,
+            data_processors,
+            block_manager,
         }
     }
 
@@ -127,11 +133,11 @@ impl ViewController {
     #[tracing::instrument(level = "debug", skip(self), err)]
     pub(crate) async fn open_view(&self, view_id: &str) -> Result<BlockDelta, FlowyError> {
         let editor = self.block_manager.open_block(view_id).await?;
+        let delta_str = editor.delta_str().await?;
         KV::set_str(LATEST_VIEW_ID, view_id.to_owned());
-        let document_json = editor.block_json().await?;
         Ok(BlockDelta {
             block_id: view_id.to_string(),
-            delta_json: document_json,
+            delta_str,
         })
     }
 
@@ -160,14 +166,14 @@ impl ViewController {
             .await?;
 
         let editor = self.block_manager.open_block(view_id).await?;
-        let document_json = editor.block_json().await?;
+        let delta_str = editor.delta_str().await?;
         let duplicate_params = CreateViewParams {
             belong_to_id: view.belong_to_id.clone(),
             name: format!("{} (copy)", &view.name),
             desc: view.desc,
             thumbnail: view.thumbnail,
             data_type: view.data_type,
-            data: document_json,
+            data: delta_str,
             view_id: uuid(),
             ext_data: view.ext_data,
             plugin_type: view.plugin_type,
@@ -208,11 +214,6 @@ impl ViewController {
         Ok(view)
     }
 
-    pub(crate) async fn receive_delta(&self, params: BlockDelta) -> Result<BlockDelta, FlowyError> {
-        let doc = self.block_manager.receive_local_delta(params).await?;
-        Ok(doc)
-    }
-
     pub(crate) async fn latest_visit_view(&self) -> FlowyResult<Option<View>> {
         match KV::get_str(LATEST_VIEW_ID) {
             None => Ok(None),
@@ -311,10 +312,10 @@ impl ViewController {
     }
 }
 
-#[tracing::instrument(level = "trace", skip(persistence, document_manager, trash_can))]
+#[tracing::instrument(level = "trace", skip(persistence, block_manager, trash_can))]
 async fn handle_trash_event(
     persistence: Arc<FolderPersistence>,
-    document_manager: Arc<BlockManager>,
+    block_manager: Arc<BlockManager>,
     trash_can: Arc<TrashController>,
     event: TrashEvent,
 ) {
@@ -352,7 +353,7 @@ async fn handle_trash_event(
                     for identifier in identifiers.items {
                         let view = transaction.read_view(&identifier.id)?;
                         let _ = transaction.delete_view(&identifier.id)?;
-                        let _ = document_manager.delete(&identifier.id)?;
+                        let _ = block_manager.delete_block(&identifier.id)?;
                         notify_ids.insert(view.belong_to_id);
                     }
 

+ 25 - 22
frontend/rust-lib/flowy-grid/src/manager.rs

@@ -41,29 +41,8 @@ impl GridManager {
     }
 
     #[tracing::instrument(level = "debug", skip_all, err)]
-    pub async fn create_grid<T: AsRef<str>>(
-        &self,
-        grid_id: T,
-        fields: Option<Vec<Field>>,
-        rows: Option<Vec<RawRow>>,
-    ) -> FlowyResult<()> {
+    pub async fn create_grid<T: AsRef<str>>(&self, grid_id: T, revisions: RepeatedRevision) -> FlowyResult<()> {
         let grid_id = grid_id.as_ref();
-        let user_id = self.grid_user.user_id()?;
-        let mut field_orders = vec![];
-        let mut row_orders = vec![];
-        if let Some(fields) = fields {
-            field_orders = fields.iter().map(|field| FieldOrder::from(field)).collect::<Vec<_>>();
-        }
-        if let Some(rows) = rows {
-            row_orders = rows.iter().map(|row| RowOrder::from(row)).collect::<Vec<_>>();
-        }
-
-        let grid = Grid {
-            id: grid_id.to_owned(),
-            field_orders: field_orders.into(),
-            row_orders: row_orders.into(),
-        };
-        let revisions = make_grid_revisions(&user_id, &grid);
         let db_pool = self.grid_user.db_pool()?;
         let rev_manager = self.make_grid_rev_manager(grid_id, db_pool)?;
         let _ = rev_manager.reset_object(revisions).await?;
@@ -144,6 +123,30 @@ impl GridManager {
     }
 }
 
+pub fn make_grid(
+    user_id: &str,
+    grid_id: &str,
+    fields: Option<Vec<Field>>,
+    rows: Option<Vec<RawRow>>,
+) -> RepeatedRevision {
+    let mut field_orders = vec![];
+    let mut row_orders = vec![];
+    if let Some(fields) = fields {
+        field_orders = fields.iter().map(|field| FieldOrder::from(field)).collect::<Vec<_>>();
+    }
+    if let Some(rows) = rows {
+        row_orders = rows.iter().map(|row| RowOrder::from(row)).collect::<Vec<_>>();
+    }
+
+    let grid = Grid {
+        id: grid_id.to_owned(),
+        field_orders: field_orders.into(),
+        row_orders: row_orders.into(),
+    };
+
+    make_grid_revisions(user_id, &grid)
+}
+
 pub struct GridEditors {
     inner: DashMap<String, Arc<ClientGridEditor>>,
 }

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

@@ -155,6 +155,10 @@ impl ClientGridEditor {
         self.grid_pad.read().await.grid_data()
     }
 
+    pub async fn delta_str(&self) -> String {
+        self.grid_pad.read().await.delta_str()
+    }
+
     async fn modify<F>(&self, f: F) -> FlowyResult<()>
     where
         F: for<'a> FnOnce(&'a mut GridPad) -> FlowyResult<Option<GridChange>>,

+ 1 - 1
frontend/rust-lib/flowy-sdk/Cargo.toml

@@ -23,7 +23,7 @@ color-eyre = { version = "0.5", default-features = false }
 bytes = "1.0"
 tokio = { version = "1", features = ["rt"] }
 parking_lot = "0.11"
-
+async-trait = "0.1.52"
 
 flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration" }
 lib-ws = { path = "../../../shared-lib/lib-ws" }

+ 88 - 2
frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs

@@ -1,12 +1,17 @@
+use async_trait::async_trait;
 use bytes::Bytes;
 use flowy_block::BlockManager;
+use flowy_collaboration::entities::revision::RepeatedRevision;
 use flowy_collaboration::entities::ws_data::ClientRevisionWSData;
 use flowy_database::ConnectionPool;
+use flowy_folder::manager::{DataProcessorMap, ViewDataProcessor};
+use flowy_folder::prelude::{FlowyResult, ViewDataType};
 use flowy_folder::{
     errors::{internal_error, FlowyError},
     event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser},
     manager::FolderManager,
 };
+use flowy_grid::manager::GridManager;
 use flowy_net::ClientServerConfiguration;
 use flowy_net::{
     http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect,
@@ -16,6 +21,7 @@ use flowy_user::services::UserSession;
 use futures_core::future::BoxFuture;
 use lib_infra::future::BoxResultFuture;
 use lib_ws::{WSChannel, WSMessageReceiver, WebSocketRawMessage};
+use std::collections::HashMap;
 use std::{convert::TryInto, sync::Arc};
 
 pub struct FolderDepsResolver();
@@ -24,8 +30,9 @@ impl FolderDepsResolver {
         local_server: Option<Arc<LocalServer>>,
         user_session: Arc<UserSession>,
         server_config: &ClientServerConfiguration,
+        ws_conn: &Arc<FlowyWebSocketConnect>,
         block_manager: &Arc<BlockManager>,
-        ws_conn: Arc<FlowyWebSocketConnect>,
+        grid_manager: &Arc<GridManager>,
     ) -> Arc<FolderManager> {
         let user: Arc<dyn WorkspaceUser> = Arc::new(WorkspaceUserImpl(user_session.clone()));
         let database: Arc<dyn WorkspaceDatabase> = Arc::new(WorkspaceDatabaseImpl(user_session));
@@ -35,8 +42,17 @@ impl FolderDepsResolver {
             Some(local_server) => local_server,
         };
 
+        let view_data_processor = make_view_data_processor(block_manager.clone(), grid_manager.clone());
         let folder_manager = Arc::new(
-            FolderManager::new(user.clone(), cloud_service, database, block_manager.clone(), web_socket).await,
+            FolderManager::new(
+                user.clone(),
+                cloud_service,
+                database,
+                view_data_processor,
+                block_manager.clone(),
+                web_socket,
+            )
+            .await,
         );
 
         if let (Ok(user_id), Ok(token)) = (user.user_id(), user.token()) {
@@ -53,6 +69,18 @@ impl FolderDepsResolver {
     }
 }
 
+fn make_view_data_processor(block_manager: Arc<BlockManager>, grid_manager: Arc<GridManager>) -> DataProcessorMap {
+    let mut map: HashMap<ViewDataType, Arc<dyn ViewDataProcessor + Send + Sync>> = HashMap::new();
+
+    let block_data_impl = BlockManagerViewDataImpl(block_manager);
+    map.insert(block_data_impl.data_type(), Arc::new(block_data_impl));
+
+    let grid_data_impl = GridManagerViewDataImpl(grid_manager);
+    map.insert(grid_data_impl.data_type(), Arc::new(grid_data_impl));
+
+    Arc::new(map)
+}
+
 struct WorkspaceDatabaseImpl(Arc<UserSession>);
 impl WorkspaceDatabase for WorkspaceDatabaseImpl {
     fn db_pool(&self) -> Result<Arc<ConnectionPool>, FlowyError> {
@@ -110,3 +138,61 @@ impl WSMessageReceiver for FolderWSMessageReceiverImpl {
         });
     }
 }
+
+struct BlockManagerViewDataImpl(Arc<BlockManager>);
+#[async_trait]
+impl ViewDataProcessor for BlockManagerViewDataImpl {
+    async fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FlowyResult<()> {
+        let _ = self.0.create_block(view_id, repeated_revision).await?;
+        Ok(())
+    }
+
+    async fn delete_container(&self, view_id: &str) -> FlowyResult<()> {
+        let _ = self.0.delete_block(view_id)?;
+        Ok(())
+    }
+
+    async fn close_container(&self, view_id: &str) -> FlowyResult<()> {
+        let _ = self.0.close_block(view_id)?;
+        Ok(())
+    }
+
+    async fn delta_str(&self, view_id: &str) -> FlowyResult<String> {
+        let editor = self.0.open_block(view_id).await?;
+        let delta_str = editor.delta_str().await?;
+        Ok(delta_str)
+    }
+
+    fn data_type(&self) -> ViewDataType {
+        ViewDataType::RichText
+    }
+}
+
+struct GridManagerViewDataImpl(Arc<GridManager>);
+#[async_trait]
+impl ViewDataProcessor for GridManagerViewDataImpl {
+    async fn create_container(&self, view_id: &str, repeated_revision: RepeatedRevision) -> FlowyResult<()> {
+        let _ = self.0.create_grid(view_id, repeated_revision).await?;
+        Ok(())
+    }
+
+    async fn delete_container(&self, view_id: &str) -> FlowyResult<()> {
+        let _ = self.0.delete_grid(view_id)?;
+        Ok(())
+    }
+
+    async fn close_container(&self, view_id: &str) -> FlowyResult<()> {
+        let _ = self.0.close_grid(view_id)?;
+        Ok(())
+    }
+
+    async fn delta_str(&self, view_id: &str) -> FlowyResult<String> {
+        let editor = self.0.open_grid(view_id).await?;
+        let delta_str = editor.delta_str().await;
+        Ok(delta_str)
+    }
+
+    fn data_type(&self) -> ViewDataType {
+        ViewDataType::Grid
+    }
+}

+ 4 - 3
frontend/rust-lib/flowy-sdk/src/lib.rs

@@ -111,17 +111,18 @@ impl FlowySDK {
                 &config.server_config,
             );
 
+            let grid_manager = GridDepsResolver::resolve(ws_conn.clone(), user_session.clone());
+
             let folder_manager = FolderDepsResolver::resolve(
                 local_server.clone(),
                 user_session.clone(),
                 &config.server_config,
+                &ws_conn,
                 &block_manager,
-                ws_conn.clone(),
+                &grid_manager,
             )
             .await;
 
-            let grid_manager = GridDepsResolver::resolve(ws_conn.clone(), user_session.clone());
-
             if let Some(local_server) = local_server.as_ref() {
                 local_server.run();
             }

+ 2 - 2
shared-lib/flowy-collaboration/src/client_document/default/mod.rs

@@ -7,7 +7,7 @@ pub fn initial_quill_delta() -> RichTextDelta {
 
 #[inline]
 pub fn initial_quill_delta_string() -> String {
-    initial_quill_delta().to_delta_json()
+    initial_quill_delta().to_delta_str()
 }
 
 #[inline]
@@ -22,6 +22,6 @@ mod tests {
 
     #[test]
     fn load_read_me() {
-        println!("{}", initial_read_me().to_delta_json());
+        println!("{}", initial_read_me().to_delta_str());
     }
 }

+ 4 - 4
shared-lib/flowy-collaboration/src/client_document/document_pad.rs

@@ -58,8 +58,8 @@ impl ClientDocument {
         Ok(Self::from_delta(delta))
     }
 
-    pub fn to_json(&self) -> String {
-        self.delta.to_delta_json()
+    pub fn delta_str(&self) -> String {
+        self.delta.to_delta_str()
     }
 
     pub fn to_bytes(&self) -> Vec<u8> {
@@ -84,7 +84,7 @@ impl ClientDocument {
     }
 
     pub fn set_delta(&mut self, data: RichTextDelta) {
-        tracing::trace!("document: {}", data.to_delta_json());
+        tracing::trace!("document: {}", data.to_delta_str());
         self.delta = data;
 
         match &self.notify {
@@ -96,7 +96,7 @@ impl ClientDocument {
     }
 
     pub fn compose_delta(&mut self, delta: RichTextDelta) -> Result<(), CollaborateError> {
-        tracing::trace!("{} compose {}", &self.delta.to_delta_json(), delta.to_delta_json());
+        tracing::trace!("{} compose {}", &self.delta.to_delta_str(), delta.to_delta_str());
         let composed_delta = self.delta.compose(&delta)?;
         let mut undo_delta = delta.invert(&self.delta);
 

+ 4 - 0
shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs

@@ -86,6 +86,10 @@ impl GridPad {
         grid_ref.clone()
     }
 
+    pub fn delta_str(&self) -> String {
+        self.delta.to_delta_str()
+    }
+
     pub fn field_orders(&self) -> &RepeatedFieldOrder {
         &self.grid.field_orders
     }

+ 2 - 2
shared-lib/flowy-collaboration/src/entities/document_info.rs

@@ -46,7 +46,7 @@ impl std::convert::TryFrom<Revision> for BlockInfo {
         }
 
         let delta = RichTextDelta::from_bytes(&revision.delta_data)?;
-        let doc_json = delta.to_delta_json();
+        let doc_json = delta.to_delta_str();
 
         Ok(BlockInfo {
             block_id: revision.object_id,
@@ -72,7 +72,7 @@ pub struct BlockDelta {
     pub block_id: String,
 
     #[pb(index = 2)]
-    pub delta_json: String,
+    pub delta_str: String,
 }
 
 #[derive(ProtoBuf, Default, Debug, Clone)]

+ 1 - 1
shared-lib/flowy-collaboration/src/entities/revision.rs

@@ -89,7 +89,7 @@ impl std::fmt::Debug for Revision {
         let _ = f.write_fmt(format_args!("rev_id {}, ", self.rev_id))?;
         match RichTextDelta::from_bytes(&self.delta_data) {
             Ok(delta) => {
-                let _ = f.write_fmt(format_args!("delta {:?}", delta.to_delta_json()))?;
+                let _ = f.write_fmt(format_args!("delta {:?}", delta.to_delta_str()))?;
             }
             Err(e) => {
                 let _ = f.write_fmt(format_args!("delta {:?}", e))?;

+ 23 - 23
shared-lib/flowy-collaboration/src/protobuf/model/document_info.rs

@@ -730,7 +730,7 @@ impl ::protobuf::reflect::ProtobufValue for ResetBlockParams {
 pub struct BlockDelta {
     // message fields
     pub block_id: ::std::string::String,
-    pub delta_json: ::std::string::String,
+    pub delta_str: ::std::string::String,
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
     pub cached_size: ::protobuf::CachedSize,
@@ -773,30 +773,30 @@ impl BlockDelta {
         ::std::mem::replace(&mut self.block_id, ::std::string::String::new())
     }
 
-    // string delta_json = 2;
+    // string delta_str = 2;
 
 
-    pub fn get_delta_json(&self) -> &str {
-        &self.delta_json
+    pub fn get_delta_str(&self) -> &str {
+        &self.delta_str
     }
-    pub fn clear_delta_json(&mut self) {
-        self.delta_json.clear();
+    pub fn clear_delta_str(&mut self) {
+        self.delta_str.clear();
     }
 
     // Param is passed by value, moved
-    pub fn set_delta_json(&mut self, v: ::std::string::String) {
-        self.delta_json = v;
+    pub fn set_delta_str(&mut self, v: ::std::string::String) {
+        self.delta_str = v;
     }
 
     // Mutable pointer to the field.
     // If field is not initialized, it is initialized with default value first.
-    pub fn mut_delta_json(&mut self) -> &mut ::std::string::String {
-        &mut self.delta_json
+    pub fn mut_delta_str(&mut self) -> &mut ::std::string::String {
+        &mut self.delta_str
     }
 
     // Take field
-    pub fn take_delta_json(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.delta_json, ::std::string::String::new())
+    pub fn take_delta_str(&mut self) -> ::std::string::String {
+        ::std::mem::replace(&mut self.delta_str, ::std::string::String::new())
     }
 }
 
@@ -813,7 +813,7 @@ impl ::protobuf::Message for BlockDelta {
                     ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.block_id)?;
                 },
                 2 => {
-                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.delta_json)?;
+                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.delta_str)?;
                 },
                 _ => {
                     ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
@@ -830,8 +830,8 @@ impl ::protobuf::Message for BlockDelta {
         if !self.block_id.is_empty() {
             my_size += ::protobuf::rt::string_size(1, &self.block_id);
         }
-        if !self.delta_json.is_empty() {
-            my_size += ::protobuf::rt::string_size(2, &self.delta_json);
+        if !self.delta_str.is_empty() {
+            my_size += ::protobuf::rt::string_size(2, &self.delta_str);
         }
         my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
         self.cached_size.set(my_size);
@@ -842,8 +842,8 @@ impl ::protobuf::Message for BlockDelta {
         if !self.block_id.is_empty() {
             os.write_string(1, &self.block_id)?;
         }
-        if !self.delta_json.is_empty() {
-            os.write_string(2, &self.delta_json)?;
+        if !self.delta_str.is_empty() {
+            os.write_string(2, &self.delta_str)?;
         }
         os.write_unknown_fields(self.get_unknown_fields())?;
         ::std::result::Result::Ok(())
@@ -889,9 +889,9 @@ impl ::protobuf::Message for BlockDelta {
                 |m: &mut BlockDelta| { &mut m.block_id },
             ));
             fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
-                "delta_json",
-                |m: &BlockDelta| { &m.delta_json },
-                |m: &mut BlockDelta| { &mut m.delta_json },
+                "delta_str",
+                |m: &BlockDelta| { &m.delta_str },
+                |m: &mut BlockDelta| { &mut m.delta_str },
             ));
             ::protobuf::reflect::MessageDescriptor::new_pb_name::<BlockDelta>(
                 "BlockDelta",
@@ -910,7 +910,7 @@ impl ::protobuf::Message for BlockDelta {
 impl ::protobuf::Clear for BlockDelta {
     fn clear(&mut self) {
         self.block_id.clear();
-        self.delta_json.clear();
+        self.delta_str.clear();
         self.unknown_fields.clear();
     }
 }
@@ -1330,9 +1330,9 @@ static file_descriptor_proto_data: &'static [u8] = b"\
     \x20\x01(\tR\x04text\x12\x15\n\x06rev_id\x18\x03\x20\x01(\x03R\x05revId\
     \x12\x1e\n\x0bbase_rev_id\x18\x04\x20\x01(\x03R\tbaseRevId\"^\n\x10Reset\
     BlockParams\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12/\n\
-    \trevisions\x18\x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"F\n\
+    \trevisions\x18\x02\x20\x01(\x0b2\x11.RepeatedRevisionR\trevisions\"D\n\
     \nBlockDelta\x12\x19\n\x08block_id\x18\x01\x20\x01(\tR\x07blockId\x12\
-    \x1d\n\ndelta_json\x18\x02\x20\x01(\tR\tdeltaJson\"S\n\nNewDocUser\x12\
+    \x1b\n\tdelta_str\x18\x02\x20\x01(\tR\x08deltaStr\"S\n\nNewDocUser\x12\
     \x17\n\x07user_id\x18\x01\x20\x01(\tR\x06userId\x12\x15\n\x06rev_id\x18\
     \x02\x20\x01(\x03R\x05revId\x12\x15\n\x06doc_id\x18\x03\x20\x01(\tR\x05d\
     ocId\"\x1f\n\x07BlockId\x12\x14\n\x05value\x18\x01\x20\x01(\tR\x05valueb\

+ 1 - 1
shared-lib/flowy-collaboration/src/protobuf/proto/document_info.proto

@@ -17,7 +17,7 @@ message ResetBlockParams {
 }
 message BlockDelta {
     string block_id = 1;
-    string delta_json = 2;
+    string delta_str = 2;
 }
 message NewDocUser {
     string user_id = 1;

+ 1 - 1
shared-lib/flowy-collaboration/src/server_document/document_pad.rs

@@ -39,7 +39,7 @@ impl RevisionSyncObject<RichTextAttributes> for ServerDocument {
     }
 
     fn to_json(&self) -> String {
-        self.delta.to_delta_json()
+        self.delta.to_delta_str()
     }
 
     fn set_delta(&mut self, new_delta: Delta<RichTextAttributes>) {

+ 1 - 1
shared-lib/flowy-collaboration/src/server_folder/folder_pad.rs

@@ -32,7 +32,7 @@ impl RevisionSyncObject<PlainTextAttributes> for ServerFolder {
     }
 
     fn to_json(&self) -> String {
-        self.delta.to_delta_json()
+        self.delta.to_delta_str()
     }
 
     fn set_delta(&mut self, new_delta: PlainTextDelta) {

+ 2 - 2
shared-lib/flowy-collaboration/src/util.rs

@@ -189,7 +189,7 @@ pub fn make_folder_pb_from_revisions_pb(
         folder_delta = folder_delta.compose(&delta)?;
     }
 
-    let text = folder_delta.to_delta_json();
+    let text = folder_delta.to_delta_str();
     let mut folder_info = FolderInfoPB::new();
     folder_info.set_folder_id(folder_id.to_owned());
     folder_info.set_text(text);
@@ -239,7 +239,7 @@ pub fn make_document_info_pb_from_revisions_pb(
         document_delta = document_delta.compose(&delta)?;
     }
 
-    let text = document_delta.to_delta_json();
+    let text = document_delta.to_delta_str();
     let mut block_info = BlockInfoPB::new();
     block_info.set_block_id(doc_id.to_owned());
     block_info.set_text(text);

+ 1 - 1
shared-lib/flowy-folder-data-model/src/entities/view.rs

@@ -80,7 +80,7 @@ impl std::convert::From<View> for Trash {
     }
 }
 
-#[derive(Eq, PartialEq, Debug, ProtoBuf_Enum, Clone, Serialize_repr, Deserialize_repr)]
+#[derive(Eq, PartialEq, Hash, Debug, ProtoBuf_Enum, Clone, Serialize_repr, Deserialize_repr)]
 #[repr(u8)]
 pub enum ViewDataType {
     RichText = 0,

+ 2 - 2
shared-lib/lib-ot/src/core/delta/delta.rs

@@ -521,7 +521,7 @@ impl<T> Delta<T>
 where
     T: Attributes + serde::Serialize,
 {
-    pub fn to_delta_json(&self) -> String {
+    pub fn to_delta_str(&self) -> String {
         serde_json::to_string(self).unwrap_or_else(|_| "".to_owned())
     }
 
@@ -530,7 +530,7 @@ where
     }
 
     pub fn to_bytes(&self) -> Bytes {
-        let json = self.to_delta_json();
+        let json = self.to_delta_str();
         Bytes::from(json.into_bytes())
     }
 }