Преглед на файлове

[rust]: refactor flowy-document crate

appflowy преди 3 години
родител
ревизия
7c60626049
променени са 63 файла, в които са добавени 367 реда и са изтрити 365 реда
  1. 1 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document-infra/protobuf.dart
  2. 0 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document-infra/ws.pb.dart
  3. 0 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document-infra/ws.pbenum.dart
  4. 0 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document-infra/ws.pbjson.dart
  5. 0 0
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document-infra/ws.pbserver.dart
  6. 1 1
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document/errors.pb.dart
  7. 3 11
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document/errors.pbenum.dart
  8. 3 7
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document/errors.pbjson.dart
  9. 0 1
      app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document/protobuf.dart
  10. 0 1
      backend/Cargo.toml
  11. 7 18
      backend/src/service/doc/edit/edit_doc.rs
  12. 1 2
      backend/src/service/doc/ws_actor.rs
  13. 16 0
      backend/src/service/ws/entities/message.rs
  14. 2 2
      rust-lib/dart-ffi/Cargo.toml
  15. 2 2
      rust-lib/flowy-derive/src/derive_cache/derive_cache.rs
  16. 8 1
      rust-lib/flowy-document-infra/Cargo.toml
  17. 0 0
      rust-lib/flowy-document-infra/src/core/data.rs
  18. 19 16
      rust-lib/flowy-document-infra/src/core/document.rs
  19. 1 1
      rust-lib/flowy-document-infra/src/core/extensions/delete/default_delete.rs
  20. 0 0
      rust-lib/flowy-document-infra/src/core/extensions/delete/mod.rs
  21. 1 2
      rust-lib/flowy-document-infra/src/core/extensions/delete/preserve_line_format_merge.rs
  22. 0 0
      rust-lib/flowy-document-infra/src/core/extensions/format/format_at_position.rs
  23. 1 1
      rust-lib/flowy-document-infra/src/core/extensions/format/helper.rs
  24. 0 0
      rust-lib/flowy-document-infra/src/core/extensions/format/mod.rs
  25. 4 2
      rust-lib/flowy-document-infra/src/core/extensions/format/resolve_block_format.rs
  26. 4 2
      rust-lib/flowy-document-infra/src/core/extensions/format/resolve_inline_format.rs
  27. 1 2
      rust-lib/flowy-document-infra/src/core/extensions/insert/auto_exit_block.rs
  28. 1 2
      rust-lib/flowy-document-infra/src/core/extensions/insert/auto_format.rs
  29. 1 1
      rust-lib/flowy-document-infra/src/core/extensions/insert/default_insert.rs
  30. 1 1
      rust-lib/flowy-document-infra/src/core/extensions/insert/mod.rs
  31. 1 3
      rust-lib/flowy-document-infra/src/core/extensions/insert/preserve_block_format.rs
  32. 4 2
      rust-lib/flowy-document-infra/src/core/extensions/insert/preserve_inline_format.rs
  33. 1 2
      rust-lib/flowy-document-infra/src/core/extensions/insert/reset_format_on_new_line.rs
  34. 0 0
      rust-lib/flowy-document-infra/src/core/extensions/mod.rs
  35. 0 0
      rust-lib/flowy-document-infra/src/core/history.rs
  36. 3 2
      rust-lib/flowy-document-infra/src/core/mod.rs
  37. 2 3
      rust-lib/flowy-document-infra/src/core/view.rs
  38. 1 0
      rust-lib/flowy-document-infra/src/entities/mod.rs
  39. 0 0
      rust-lib/flowy-document-infra/src/entities/ws/mod.rs
  40. 6 16
      rust-lib/flowy-document-infra/src/entities/ws/ws.rs
  41. 65 0
      rust-lib/flowy-document-infra/src/errors.rs
  42. 2 0
      rust-lib/flowy-document-infra/src/lib.rs
  43. 50 50
      rust-lib/flowy-document-infra/src/protobuf/model/doc.rs
  44. 3 0
      rust-lib/flowy-document-infra/src/protobuf/model/mod.rs
  45. 38 38
      rust-lib/flowy-document-infra/src/protobuf/model/revision.rs
  46. 22 22
      rust-lib/flowy-document-infra/src/protobuf/model/ws.rs
  47. 1 0
      rust-lib/flowy-document-infra/src/protobuf/proto/doc.proto
  48. 1 0
      rust-lib/flowy-document-infra/src/protobuf/proto/revision.proto
  49. 1 0
      rust-lib/flowy-document-infra/src/protobuf/proto/ws.proto
  50. 1 1
      rust-lib/flowy-document/Flowy.toml
  51. 0 1
      rust-lib/flowy-document/src/entities/mod.rs
  52. 8 19
      rust-lib/flowy-document/src/errors.rs
  53. 0 1
      rust-lib/flowy-document/src/lib.rs
  54. 26 48
      rust-lib/flowy-document/src/protobuf/model/errors.rs
  55. 0 3
      rust-lib/flowy-document/src/protobuf/model/mod.rs
  56. 2 6
      rust-lib/flowy-document/src/protobuf/proto/errors.proto
  57. 0 1
      rust-lib/flowy-document/src/services/doc/document/selection.rs
  58. 8 24
      rust-lib/flowy-document/src/services/doc/edit/doc_actor.rs
  59. 26 25
      rust-lib/flowy-document/src/services/doc/edit/edit_doc.rs
  60. 1 11
      rust-lib/flowy-document/src/services/doc/mod.rs
  61. 2 2
      rust-lib/flowy-document/src/services/ws/ws_manager.rs
  62. 1 0
      rust-lib/flowy-sdk/Cargo.toml
  63. 13 9
      rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs

+ 1 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document-infra/protobuf.dart

@@ -1,3 +1,4 @@
 // Auto-generated, do not edit 
+export './ws.pb.dart';
 export './revision.pb.dart';
 export './doc.pb.dart';

+ 0 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document/ws.pb.dart → app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document-infra/ws.pb.dart


+ 0 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document/ws.pbenum.dart → app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document-infra/ws.pbenum.dart


+ 0 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document/ws.pbjson.dart → app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document-infra/ws.pbjson.dart


+ 0 - 0
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document/ws.pbserver.dart → app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document-infra/ws.pbserver.dart


+ 1 - 1
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document/errors.pb.dart

@@ -15,7 +15,7 @@ export 'errors.pbenum.dart';
 
 class DocError extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DocError', createEmptyInstance: create)
-    ..e<ErrorCode>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code', $pb.PbFieldType.OE, defaultOrMaker: ErrorCode.DocIdInvalid, valueOf: ErrorCode.valueOf, enumValues: ErrorCode.values)
+    ..e<ErrorCode>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code', $pb.PbFieldType.OE, defaultOrMaker: ErrorCode.WsConnectError, valueOf: ErrorCode.valueOf, enumValues: ErrorCode.values)
     ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'msg')
     ..hasRequiredFields = false
   ;

+ 3 - 11
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document/errors.pbenum.dart

@@ -10,23 +10,15 @@ import 'dart:core' as $core;
 import 'package:protobuf/protobuf.dart' as $pb;
 
 class ErrorCode extends $pb.ProtobufEnum {
-  static const ErrorCode DocIdInvalid = ErrorCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DocIdInvalid');
+  static const ErrorCode WsConnectError = ErrorCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WsConnectError');
   static const ErrorCode DocNotfound = ErrorCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DocNotfound');
-  static const ErrorCode WsConnectError = ErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WsConnectError');
-  static const ErrorCode UndoFail = ErrorCode._(200, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UndoFail');
-  static const ErrorCode RedoFail = ErrorCode._(201, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RedoFail');
-  static const ErrorCode OutOfBound = ErrorCode._(202, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'OutOfBound');
-  static const ErrorCode DuplicateRevision = ErrorCode._(400, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateRevision');
+  static const ErrorCode DuplicateRevision = ErrorCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DuplicateRevision');
   static const ErrorCode UserUnauthorized = ErrorCode._(999, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserUnauthorized');
   static const ErrorCode InternalError = ErrorCode._(1000, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InternalError');
 
   static const $core.List<ErrorCode> values = <ErrorCode> [
-    DocIdInvalid,
-    DocNotfound,
     WsConnectError,
-    UndoFail,
-    RedoFail,
-    OutOfBound,
+    DocNotfound,
     DuplicateRevision,
     UserUnauthorized,
     InternalError,

+ 3 - 7
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document/errors.pbjson.dart

@@ -12,20 +12,16 @@ import 'dart:typed_data' as $typed_data;
 const ErrorCode$json = const {
   '1': 'ErrorCode',
   '2': const [
-    const {'1': 'DocIdInvalid', '2': 0},
+    const {'1': 'WsConnectError', '2': 0},
     const {'1': 'DocNotfound', '2': 1},
-    const {'1': 'WsConnectError', '2': 10},
-    const {'1': 'UndoFail', '2': 200},
-    const {'1': 'RedoFail', '2': 201},
-    const {'1': 'OutOfBound', '2': 202},
-    const {'1': 'DuplicateRevision', '2': 400},
+    const {'1': 'DuplicateRevision', '2': 2},
     const {'1': 'UserUnauthorized', '2': 999},
     const {'1': 'InternalError', '2': 1000},
   ],
 };
 
 /// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSEAoMRG9jSWRJbnZhbGlkEAASDwoLRG9jTm90Zm91bmQQARISCg5Xc0Nvbm5lY3RFcnJvchAKEg0KCFVuZG9GYWlsEMgBEg0KCFJlZG9GYWlsEMkBEg8KCk91dE9mQm91bmQQygESFgoRRHVwbGljYXRlUmV2aXNpb24QkAMSFQoQVXNlclVuYXV0aG9yaXplZBDnBxISCg1JbnRlcm5hbEVycm9yEOgH');
+final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSEgoOV3NDb25uZWN0RXJyb3IQABIPCgtEb2NOb3Rmb3VuZBABEhUKEUR1cGxpY2F0ZVJldmlzaW9uEAISFQoQVXNlclVuYXV0aG9yaXplZBDnBxISCg1JbnRlcm5hbEVycm9yEOgH');
 @$core.Deprecated('Use docErrorDescriptor instead')
 const DocError$json = const {
   '1': 'DocError',

+ 0 - 1
app_flowy/packages/flowy_sdk/lib/protobuf/flowy-document/protobuf.dart

@@ -1,4 +1,3 @@
 // Auto-generated, do not edit 
-export './ws.pb.dart';
 export './observable.pb.dart';
 export './errors.pb.dart';

+ 0 - 1
backend/Cargo.toml

@@ -63,7 +63,6 @@ async-stream = "0.3.2"
 flowy-user-infra = { path = "../rust-lib/flowy-user-infra" }
 flowy-workspace-infra = { path = "../rust-lib/flowy-workspace-infra" }
 flowy-document-infra = { path = "../rust-lib/flowy-document-infra" }
-flowy-document = { path = "../rust-lib/flowy-document" }
 flowy-ws = { path = "../rust-lib/flowy-ws" }
 flowy-ot = { path = "../rust-lib/flowy-ot" }
 flowy-net = { path = "../rust-lib/flowy-net", features = ["http_server"] }

+ 7 - 18
backend/src/service/doc/edit/edit_doc.rs

@@ -1,27 +1,22 @@
 use crate::service::{
     doc::{edit::edit_actor::EditUser, update_doc},
     util::md5,
-    ws::WsMessageAdaptor,
+    ws::{entities::Socket, WsMessageAdaptor},
 };
 use actix_web::web::Data;
-
-use crate::service::ws::entities::Socket;
-use bytes::Bytes;
 use dashmap::DashMap;
-use flowy_document::{
+use flowy_document_infra::{
+    core::Document,
     entities::ws::{WsDataType, WsDocumentData},
-    services::doc::Document,
+    protobuf::{Doc, RevId, RevType, Revision, RevisionRange, UpdateDocParams},
 };
-use flowy_document_infra::protobuf::{Doc, RevId, RevType, Revision, RevisionRange, UpdateDocParams};
 use flowy_net::errors::{internal_error, ServerError};
 use flowy_ot::core::{Delta, OperationTransformable};
-use flowy_ws::WsMessage;
 use parking_lot::RwLock;
 use protobuf::Message;
 use sqlx::PgPool;
 use std::{
     cmp::Ordering,
-    convert::TryInto,
     sync::{
         atomic::{AtomicI64, Ordering::SeqCst},
         Arc,
@@ -213,7 +208,7 @@ fn mk_push_message(doc_id: &str, revision: Revision) -> WsMessageAdaptor {
         ty: WsDataType::PushRev,
         data: bytes,
     };
-    mk_ws_message(data)
+    data.into()
 }
 
 #[tracing::instrument(level = "debug", skip(socket, doc_id), err)]
@@ -236,7 +231,7 @@ fn mk_pull_message(doc_id: &str, from_rev_id: i64, to_rev_id: i64) -> WsMessageA
         ty: WsDataType::PullRev,
         data: bytes,
     };
-    mk_ws_message(data)
+    data.into()
 }
 
 #[tracing::instrument(level = "debug", skip(socket, revision), err)]
@@ -259,13 +254,7 @@ fn mk_acked_message(revision: &Revision) -> WsMessageAdaptor {
         data,
     };
 
-    mk_ws_message(data)
-}
-
-fn mk_ws_message<T: Into<WsMessage>>(data: T) -> WsMessageAdaptor {
-    let msg: WsMessage = data.into();
-    let bytes: Bytes = msg.try_into().unwrap();
-    WsMessageAdaptor(bytes)
+    data.into()
 }
 
 #[inline]

+ 1 - 2
backend/src/service/doc/ws_actor.rs

@@ -6,8 +6,7 @@ use crate::service::{
 use actix_rt::task::spawn_blocking;
 use actix_web::web::Data;
 use async_stream::stream;
-use flowy_document::protobuf::{WsDataType, WsDocumentData};
-use flowy_document_infra::protobuf::{NewDocUser, Revision};
+use flowy_document_infra::protobuf::{NewDocUser, Revision, WsDataType, WsDocumentData};
 use flowy_net::errors::{internal_error, Result as DocResult, ServerError};
 use futures::stream::StreamExt;
 use sqlx::PgPool;

+ 16 - 0
backend/src/service/ws/entities/message.rs

@@ -1,5 +1,8 @@
 use actix::Message;
 use bytes::Bytes;
+use flowy_document_infra::entities::ws::WsDocumentData;
+use flowy_ws::{WsMessage, WsModule};
+use std::convert::TryInto;
 
 #[derive(Debug, Message, Clone)]
 #[rtype(result = "()")]
@@ -10,3 +13,16 @@ impl std::ops::Deref for WsMessageAdaptor {
 
     fn deref(&self) -> &Self::Target { &self.0 }
 }
+
+impl std::convert::From<WsDocumentData> for WsMessageAdaptor {
+    fn from(data: WsDocumentData) -> Self {
+        let bytes: Bytes = data.try_into().unwrap();
+        let msg = WsMessage {
+            module: WsModule::Doc,
+            data: bytes.to_vec(),
+        };
+
+        let bytes: Bytes = msg.try_into().unwrap();
+        WsMessageAdaptor(bytes)
+    }
+}

+ 2 - 2
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 staticlib
-crate-type = ["staticlib"]
+# default cdylib
+crate-type = ["cdylib"]
 
 
 [dependencies]

+ 2 - 2
rust-lib/flowy-derive/src/derive_cache/derive_cache.rs

@@ -57,6 +57,7 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
         | "RevId"
         | "Revision"
         | "RevisionRange"
+        | "WsDocumentData"
         | "KeyValue"
         | "WorkspaceError"
         | "WsError"
@@ -71,7 +72,6 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
         | "UserProfile"
         | "UpdateUserRequest"
         | "UpdateUserParams"
-        | "WsDocumentData"
         | "DocError"
         | "FFIRequest"
         | "FFIResponse"
@@ -83,10 +83,10 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
         | "ExportType"
         | "ErrorCode"
         | "RevType"
+        | "WsDataType"
         | "WorkspaceEvent"
         | "WorkspaceNotification"
         | "WsModule"
-        | "WsDataType"
         | "DocObservable"
         | "FFIStatusCode"
         | "UserEvent"

+ 8 - 1
rust-lib/flowy-document-infra/Cargo.toml

@@ -11,4 +11,11 @@ flowy-derive = { path = "../flowy-derive" }
 protobuf = {version = "2.18.0"}
 bytes = "1.0"
 log = "0.4.14"
-md5 = "0.7.0"
+md5 = "0.7.0"
+tokio = {version = "1", features = ["sync"]}
+serde = { version = "1.0", features = ["derive"] }
+tracing = { version = "0.1", features = ["log"] }
+url = "2.2"
+strum = "0.21"
+strum_macros = "0.21"
+chrono = "0.4.19"

+ 0 - 0
rust-lib/flowy-document/src/services/doc/document/data.rs → rust-lib/flowy-document-infra/src/core/data.rs


+ 19 - 16
rust-lib/flowy-document/src/services/doc/document/document.rs → rust-lib/flowy-document-infra/src/core/document.rs

@@ -1,8 +1,11 @@
 use crate::{
-    errors::DocError,
-    services::doc::{view::View, History, UndoResult, RECORD_THRESHOLD},
+    core::{
+        history::{History, UndoResult},
+        view::{View, RECORD_THRESHOLD},
+    },
+    errors::DocumentError,
+    user_default::doc_initial_delta,
 };
-use flowy_document_infra::user_default::doc_initial_delta;
 use flowy_ot::core::*;
 use tokio::sync::mpsc;
 
@@ -41,7 +44,7 @@ impl Document {
         }
     }
 
-    pub fn from_json(json: &str) -> Result<Self, DocError> {
+    pub fn from_json(json: &str) -> Result<Self, DocumentError> {
         let delta = Delta::from_json(json)?;
         Ok(Self::from_delta(delta))
     }
@@ -67,7 +70,7 @@ impl Document {
         }
     }
 
-    pub fn compose_delta(&mut self, mut delta: Delta) -> Result<(), DocError> {
+    pub fn compose_delta(&mut self, mut delta: Delta) -> Result<(), DocumentError> {
         trim(&mut delta);
         tracing::trace!("{} compose {}", &self.delta.to_json(), delta.to_json());
         let mut composed_delta = self.delta.compose(&delta)?;
@@ -97,7 +100,7 @@ impl Document {
         Ok(())
     }
 
-    pub fn insert<T: ToString>(&mut self, index: usize, data: T) -> Result<Delta, DocError> {
+    pub fn insert<T: ToString>(&mut self, index: usize, data: T) -> Result<Delta, DocumentError> {
         let interval = Interval::new(index, index);
         let _ = validate_interval(&self.delta, &interval)?;
 
@@ -108,7 +111,7 @@ impl Document {
         Ok(delta)
     }
 
-    pub fn delete(&mut self, interval: Interval) -> Result<Delta, DocError> {
+    pub fn delete(&mut self, interval: Interval) -> Result<Delta, DocumentError> {
         let _ = validate_interval(&self.delta, &interval)?;
         debug_assert_eq!(interval.is_empty(), false);
         let delete = self.view.delete(&self.delta, interval)?;
@@ -119,7 +122,7 @@ impl Document {
         Ok(delete)
     }
 
-    pub fn format(&mut self, interval: Interval, attribute: Attribute) -> Result<Delta, DocError> {
+    pub fn format(&mut self, interval: Interval, attribute: Attribute) -> Result<Delta, DocumentError> {
         let _ = validate_interval(&self.delta, &interval)?;
         tracing::trace!("format with {} at {}", attribute, interval);
         let format_delta = self.view.format(&self.delta, attribute.clone(), interval).unwrap();
@@ -129,7 +132,7 @@ impl Document {
         Ok(format_delta)
     }
 
-    pub fn replace<T: ToString>(&mut self, interval: Interval, data: T) -> Result<Delta, DocError> {
+    pub fn replace<T: ToString>(&mut self, interval: Interval, data: T) -> Result<Delta, DocumentError> {
         let _ = validate_interval(&self.delta, &interval)?;
         let mut delta = Delta::default();
         let text = data.to_string();
@@ -151,9 +154,9 @@ impl Document {
 
     pub fn can_redo(&self) -> bool { self.history.can_redo() }
 
-    pub fn undo(&mut self) -> Result<UndoResult, DocError> {
+    pub fn undo(&mut self) -> Result<UndoResult, DocumentError> {
         match self.history.undo() {
-            None => Err(DocError::undo().context("Undo stack is empty")),
+            None => Err(DocumentError::undo().context("Undo stack is empty")),
             Some(undo_delta) => {
                 let (new_delta, inverted_delta) = self.invert(&undo_delta)?;
                 let result = UndoResult::success(new_delta.target_len as usize);
@@ -165,9 +168,9 @@ impl Document {
         }
     }
 
-    pub fn redo(&mut self) -> Result<UndoResult, DocError> {
+    pub fn redo(&mut self) -> Result<UndoResult, DocumentError> {
         match self.history.redo() {
-            None => Err(DocError::redo()),
+            None => Err(DocumentError::redo()),
             Some(redo_delta) => {
                 let (new_delta, inverted_delta) = self.invert(&redo_delta)?;
                 let result = UndoResult::success(new_delta.target_len as usize);
@@ -181,7 +184,7 @@ impl Document {
 }
 
 impl Document {
-    fn invert(&self, delta: &Delta) -> Result<(Delta, Delta), DocError> {
+    fn invert(&self, delta: &Delta) -> Result<(Delta, Delta), DocumentError> {
         // c = a.compose(b)
         // d = b.invert(a)
         // a = c.compose(d)
@@ -192,10 +195,10 @@ impl Document {
     }
 }
 
-fn validate_interval(delta: &Delta, interval: &Interval) -> Result<(), DocError> {
+fn validate_interval(delta: &Delta, interval: &Interval) -> Result<(), DocumentError> {
     if delta.target_len < interval.end {
         log::error!("{:?} out of bounds. should 0..{}", interval, delta.target_len);
-        return Err(DocError::out_of_bound());
+        return Err(DocumentError::out_of_bound());
     }
     Ok(())
 }

+ 1 - 1
rust-lib/flowy-document/src/services/doc/extensions/delete/default_delete.rs → rust-lib/flowy-document-infra/src/core/extensions/delete/default_delete.rs

@@ -1,4 +1,4 @@
-use crate::services::doc::extensions::DeleteExt;
+use crate::core::extensions::DeleteExt;
 use flowy_ot::core::{Delta, DeltaBuilder, Interval};
 
 pub struct DefaultDelete {}

+ 0 - 0
rust-lib/flowy-document/src/services/doc/extensions/delete/mod.rs → rust-lib/flowy-document-infra/src/core/extensions/delete/mod.rs


+ 1 - 2
rust-lib/flowy-document/src/services/doc/extensions/delete/preserve_line_format_merge.rs → rust-lib/flowy-document-infra/src/core/extensions/delete/preserve_line_format_merge.rs

@@ -1,5 +1,4 @@
-use crate::services::doc::extensions::DeleteExt;
-use flowy_document_infra::util::is_newline;
+use crate::{core::extensions::DeleteExt, util::is_newline};
 use flowy_ot::core::{plain_attributes, CharMetric, Delta, DeltaBuilder, DeltaIter, Interval, NEW_LINE};
 
 pub struct PreserveLineFormatOnMerge {}

+ 0 - 0
rust-lib/flowy-document/src/services/doc/extensions/format/format_at_position.rs → rust-lib/flowy-document-infra/src/core/extensions/format/format_at_position.rs


+ 1 - 1
rust-lib/flowy-document/src/services/doc/extensions/format/helper.rs → rust-lib/flowy-document-infra/src/core/extensions/format/helper.rs

@@ -1,4 +1,4 @@
-use flowy_document_infra::util::find_newline;
+use crate::util::find_newline;
 use flowy_ot::core::{plain_attributes, Attribute, AttributeScope, Delta, Operation};
 
 pub(crate) fn line_break(op: &Operation, attribute: &Attribute, scope: AttributeScope) -> Delta {

+ 0 - 0
rust-lib/flowy-document/src/services/doc/extensions/format/mod.rs → rust-lib/flowy-document-infra/src/core/extensions/format/mod.rs


+ 4 - 2
rust-lib/flowy-document/src/services/doc/extensions/format/resolve_block_format.rs → rust-lib/flowy-document-infra/src/core/extensions/format/resolve_block_format.rs

@@ -1,5 +1,7 @@
-use crate::services::doc::extensions::{format::helper::line_break, FormatExt};
-use flowy_document_infra::util::find_newline;
+use crate::{
+    core::extensions::{format::helper::line_break, FormatExt},
+    util::find_newline,
+};
 use flowy_ot::core::{plain_attributes, Attribute, AttributeScope, Delta, DeltaBuilder, DeltaIter, Interval};
 
 pub struct ResolveBlockFormat {}

+ 4 - 2
rust-lib/flowy-document/src/services/doc/extensions/format/resolve_inline_format.rs → rust-lib/flowy-document-infra/src/core/extensions/format/resolve_inline_format.rs

@@ -1,5 +1,7 @@
-use crate::services::doc::extensions::{format::helper::line_break, FormatExt};
-use flowy_document_infra::util::find_newline;
+use crate::{
+    core::extensions::{format::helper::line_break, FormatExt},
+    util::find_newline,
+};
 use flowy_ot::core::{Attribute, AttributeScope, Delta, DeltaBuilder, DeltaIter, Interval};
 
 pub struct ResolveInlineFormat {}

+ 1 - 2
rust-lib/flowy-document/src/services/doc/extensions/insert/auto_exit_block.rs → rust-lib/flowy-document-infra/src/core/extensions/insert/auto_exit_block.rs

@@ -1,5 +1,4 @@
-use crate::services::doc::extensions::InsertExt;
-use flowy_document_infra::util::is_newline;
+use crate::{core::extensions::InsertExt, util::is_newline};
 use flowy_ot::core::{attributes_except_header, is_empty_line_at_index, AttributeKey, Delta, DeltaBuilder, DeltaIter};
 
 pub struct AutoExitBlock {}

+ 1 - 2
rust-lib/flowy-document/src/services/doc/extensions/insert/auto_format.rs → rust-lib/flowy-document-infra/src/core/extensions/insert/auto_format.rs

@@ -1,5 +1,4 @@
-use crate::services::doc::extensions::InsertExt;
-use flowy_document_infra::util::is_whitespace;
+use crate::{core::extensions::InsertExt, util::is_whitespace};
 use flowy_ot::core::{count_utf16_code_units, plain_attributes, Attribute, Attributes, Delta, DeltaBuilder, DeltaIter};
 use std::cmp::min;
 use url::Url;

+ 1 - 1
rust-lib/flowy-document/src/services/doc/extensions/insert/default_insert.rs → rust-lib/flowy-document-infra/src/core/extensions/insert/default_insert.rs

@@ -1,4 +1,4 @@
-use crate::services::doc::extensions::InsertExt;
+use crate::core::extensions::InsertExt;
 use flowy_ot::core::{AttributeKey, Attributes, Delta, DeltaBuilder, DeltaIter, NEW_LINE};
 
 pub struct DefaultInsertAttribute {}

+ 1 - 1
rust-lib/flowy-document/src/services/doc/extensions/insert/mod.rs → rust-lib/flowy-document-infra/src/core/extensions/insert/mod.rs

@@ -1,4 +1,4 @@
-use crate::services::doc::extensions::InsertExt;
+use crate::core::extensions::InsertExt;
 pub use auto_exit_block::*;
 pub use auto_format::*;
 pub use default_insert::*;

+ 1 - 3
rust-lib/flowy-document/src/services/doc/extensions/insert/preserve_block_format.rs → rust-lib/flowy-document-infra/src/core/extensions/insert/preserve_block_format.rs

@@ -1,3 +1,4 @@
+use crate::{core::extensions::InsertExt, util::is_newline};
 use flowy_ot::core::{
     attributes_except_header,
     plain_attributes,
@@ -10,9 +11,6 @@ use flowy_ot::core::{
     NEW_LINE,
 };
 
-use crate::services::doc::extensions::InsertExt;
-use flowy_document_infra::util::is_newline;
-
 pub struct PreserveBlockFormatOnInsert {}
 impl InsertExt for PreserveBlockFormatOnInsert {
     fn ext_name(&self) -> &str { std::any::type_name::<PreserveBlockFormatOnInsert>() }

+ 4 - 2
rust-lib/flowy-document/src/services/doc/extensions/insert/preserve_inline_format.rs → rust-lib/flowy-document-infra/src/core/extensions/insert/preserve_inline_format.rs

@@ -1,5 +1,7 @@
-use crate::services::doc::extensions::InsertExt;
-use flowy_document_infra::util::{contain_newline, is_newline};
+use crate::{
+    core::extensions::InsertExt,
+    util::{contain_newline, is_newline},
+};
 use flowy_ot::core::{plain_attributes, AttributeKey, Delta, DeltaBuilder, DeltaIter, OpNewline, NEW_LINE};
 
 pub struct PreserveInlineFormat {}

+ 1 - 2
rust-lib/flowy-document/src/services/doc/extensions/insert/reset_format_on_new_line.rs → rust-lib/flowy-document-infra/src/core/extensions/insert/reset_format_on_new_line.rs

@@ -1,5 +1,4 @@
-use crate::services::doc::extensions::InsertExt;
-use flowy_document_infra::util::is_newline;
+use crate::{core::extensions::InsertExt, util::is_newline};
 use flowy_ot::core::{AttributeKey, Attributes, CharMetric, Delta, DeltaBuilder, DeltaIter, NEW_LINE};
 
 pub struct ResetLineFormatOnNewLine {}

+ 0 - 0
rust-lib/flowy-document/src/services/doc/extensions/mod.rs → rust-lib/flowy-document-infra/src/core/extensions/mod.rs


+ 0 - 0
rust-lib/flowy-document/src/services/doc/history.rs → rust-lib/flowy-document-infra/src/core/history.rs


+ 3 - 2
rust-lib/flowy-document/src/services/doc/document/mod.rs → rust-lib/flowy-document-infra/src/core/mod.rs

@@ -1,6 +1,7 @@
 mod data;
 mod document;
-mod selection;
+mod extensions;
+pub mod history;
+mod view;
 
-pub use data::*;
 pub use document::*;

+ 2 - 3
rust-lib/flowy-document/src/services/doc/view.rs → rust-lib/flowy-document-infra/src/core/view.rs

@@ -1,7 +1,6 @@
-use super::extensions::*;
-use crate::services::doc::trim;
+use crate::core::extensions::*;
 use flowy_ot::{
-    core::{Attribute, Delta, Interval},
+    core::{trim, Attribute, Delta, Interval},
     errors::{ErrorBuilder, OTError, OTErrorCode},
 };
 

+ 1 - 0
rust-lib/flowy-document-infra/src/entities/mod.rs

@@ -1 +1,2 @@
 pub mod doc;
+pub mod ws;

+ 0 - 0
rust-lib/flowy-document/src/entities/ws/mod.rs → rust-lib/flowy-document-infra/src/entities/ws/mod.rs


+ 6 - 16
rust-lib/flowy-document/src/entities/ws/ws.rs → rust-lib/flowy-document-infra/src/entities/ws/ws.rs

@@ -1,8 +1,9 @@
-use crate::errors::DocError;
+use crate::{
+    entities::doc::{NewDocUser, Revision},
+    errors::DocumentError,
+};
 use bytes::Bytes;
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
-use flowy_document_infra::entities::doc::{NewDocUser, Revision};
-use flowy_ws::{WsMessage, WsModule};
 use std::convert::{TryFrom, TryInto};
 
 #[derive(Debug, Clone, ProtoBuf_Enum, Eq, PartialEq, Hash)]
@@ -15,9 +16,9 @@ pub enum WsDataType {
 }
 
 impl WsDataType {
-    pub fn data<T>(&self, bytes: Bytes) -> Result<T, DocError>
+    pub fn data<T>(&self, bytes: Bytes) -> Result<T, DocumentError>
     where
-        T: TryFrom<Bytes, Error = DocError>,
+        T: TryFrom<Bytes, Error = DocumentError>,
     {
         T::try_from(bytes)
     }
@@ -63,14 +64,3 @@ impl std::convert::From<NewDocUser> for WsDocumentData {
         }
     }
 }
-
-impl std::convert::Into<WsMessage> for WsDocumentData {
-    fn into(self) -> WsMessage {
-        let bytes: Bytes = self.try_into().unwrap();
-        let msg = WsMessage {
-            module: WsModule::Doc,
-            data: bytes.to_vec(),
-        };
-        msg
-    }
-}

+ 65 - 0
rust-lib/flowy-document-infra/src/errors.rs

@@ -0,0 +1,65 @@
+use std::{fmt, fmt::Debug};
+use strum_macros::Display;
+
+macro_rules! static_doc_error {
+    ($name:ident, $status:expr) => {
+        #[allow(non_snake_case, missing_docs)]
+        pub fn $name() -> DocumentError {
+            DocumentError {
+                code: $status,
+                msg: format!("{}", $status),
+            }
+        }
+    };
+}
+
+pub type DocumentResult<T> = std::result::Result<T, DocumentError>;
+
+#[derive(Debug, Clone)]
+pub struct DocumentError {
+    pub code: ErrorCode,
+    pub msg: String,
+}
+
+impl DocumentError {
+    fn new(code: ErrorCode, msg: &str) -> Self {
+        Self {
+            code,
+            msg: msg.to_owned(),
+        }
+    }
+
+    pub fn context<T: Debug>(mut self, error: T) -> Self {
+        self.msg = format!("{:?}", error);
+        self
+    }
+
+    static_doc_error!(internal, ErrorCode::InternalError);
+    static_doc_error!(undo, ErrorCode::UndoFail);
+    static_doc_error!(redo, ErrorCode::RedoFail);
+    static_doc_error!(out_of_bound, ErrorCode::OutOfBound);
+}
+
+impl fmt::Display for DocumentError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}: {}", &self.code, &self.msg) }
+}
+
+#[derive(Debug, Clone, Display, PartialEq, Eq)]
+pub enum ErrorCode {
+    DocIdInvalid  = 0,
+    DocNotfound   = 1,
+    UndoFail      = 200,
+    RedoFail      = 201,
+    OutOfBound    = 202,
+    InternalError = 1000,
+}
+
+impl std::convert::From<flowy_ot::errors::OTError> for DocumentError {
+    fn from(error: flowy_ot::errors::OTError) -> Self {
+        DocumentError::new(ErrorCode::InternalError, "").context(error)
+    }
+}
+
+impl std::convert::From<protobuf::ProtobufError> for DocumentError {
+    fn from(e: protobuf::ProtobufError) -> Self { DocumentError::internal().context(e) }
+}

+ 2 - 0
rust-lib/flowy-document-infra/src/lib.rs

@@ -1,4 +1,6 @@
+pub mod core;
 pub mod entities;
+pub mod errors;
 pub mod protobuf;
 pub mod user_default;
 pub mod util;

+ 50 - 50
rust-lib/flowy-document-infra/src/protobuf/model/doc.rs

@@ -1340,56 +1340,56 @@ static file_descriptor_proto_data: &'static [u8] = b"\
     \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\"&\n\rDocIdentifier\x12\x15\n\x06doc_id\x18\x01\x20\x01(\tR\x05docI\
-    dJ\xdb\x07\n\x06\x12\x04\0\0\x1b\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\
-    \n\x02\x04\0\x12\x04\x01\0\x04\x01\n\n\n\x03\x04\0\x01\x12\x03\x01\x08\
-    \x17\n\x0b\n\x04\x04\0\x02\0\x12\x03\x02\x04\x12\n\x0c\n\x05\x04\0\x02\0\
-    \x05\x12\x03\x02\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x02\x0b\r\n\
-    \x0c\n\x05\x04\0\x02\0\x03\x12\x03\x02\x10\x11\n\x0b\n\x04\x04\0\x02\x01\
-    \x12\x03\x03\x04\x14\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x03\x04\n\n\
-    \x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x03\x0b\x0f\n\x0c\n\x05\x04\0\x02\
-    \x01\x03\x12\x03\x03\x12\x13\n\n\n\x02\x04\x01\x12\x04\x05\0\n\x01\n\n\n\
-    \x03\x04\x01\x01\x12\x03\x05\x08\x0b\n\x0b\n\x04\x04\x01\x02\0\x12\x03\
-    \x06\x04\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x06\x04\n\n\x0c\n\x05\
-    \x04\x01\x02\0\x01\x12\x03\x06\x0b\r\n\x0c\n\x05\x04\x01\x02\0\x03\x12\
-    \x03\x06\x10\x11\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\x07\x04\x14\n\x0c\n\
-    \x05\x04\x01\x02\x01\x05\x12\x03\x07\x04\n\n\x0c\n\x05\x04\x01\x02\x01\
-    \x01\x12\x03\x07\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\x07\x12\
-    \x13\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\x08\x04\x15\n\x0c\n\x05\x04\x01\
-    \x02\x02\x05\x12\x03\x08\x04\t\n\x0c\n\x05\x04\x01\x02\x02\x01\x12\x03\
-    \x08\n\x10\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\x08\x13\x14\n\x0b\n\
-    \x04\x04\x01\x02\x03\x12\x03\t\x04\x1a\n\x0c\n\x05\x04\x01\x02\x03\x05\
-    \x12\x03\t\x04\t\n\x0c\n\x05\x04\x01\x02\x03\x01\x12\x03\t\n\x15\n\x0c\n\
-    \x05\x04\x01\x02\x03\x03\x12\x03\t\x18\x19\n\n\n\x02\x04\x02\x12\x04\x0b\
-    \0\x0f\x01\n\n\n\x03\x04\x02\x01\x12\x03\x0b\x08\x17\n\x0b\n\x04\x04\x02\
-    \x02\0\x12\x03\x0c\x04\x16\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\x0c\x04\
-    \n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\x0c\x0b\x11\n\x0c\n\x05\x04\x02\
-    \x02\0\x03\x12\x03\x0c\x14\x15\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\r\x04\
-    \x14\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\x03\r\x04\n\n\x0c\n\x05\x04\x02\
-    \x02\x01\x01\x12\x03\r\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\r\
-    \x12\x13\n\x0b\n\x04\x04\x02\x02\x02\x12\x03\x0e\x04\x15\n\x0c\n\x05\x04\
-    \x02\x02\x02\x05\x12\x03\x0e\x04\t\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\
-    \x03\x0e\n\x10\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x0e\x13\x14\n\n\n\
-    \x02\x04\x03\x12\x04\x10\0\x13\x01\n\n\n\x03\x04\x03\x01\x12\x03\x10\x08\
-    \x10\n\x0b\n\x04\x04\x03\x02\0\x12\x03\x11\x04\x16\n\x0c\n\x05\x04\x03\
-    \x02\0\x05\x12\x03\x11\x04\n\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x11\
-    \x0b\x11\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x11\x14\x15\n\x0b\n\x04\
-    \x04\x03\x02\x01\x12\x03\x12\x04\x14\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\
-    \x03\x12\x04\n\n\x0c\n\x05\x04\x03\x02\x01\x01\x12\x03\x12\x0b\x0f\n\x0c\
-    \n\x05\x04\x03\x02\x01\x03\x12\x03\x12\x12\x13\n\n\n\x02\x04\x04\x12\x04\
-    \x14\0\x18\x01\n\n\n\x03\x04\x04\x01\x12\x03\x14\x08\x12\n\x0b\n\x04\x04\
-    \x04\x02\0\x12\x03\x15\x04\x17\n\x0c\n\x05\x04\x04\x02\0\x05\x12\x03\x15\
-    \x04\n\n\x0c\n\x05\x04\x04\x02\0\x01\x12\x03\x15\x0b\x12\n\x0c\n\x05\x04\
-    \x04\x02\0\x03\x12\x03\x15\x15\x16\n\x0b\n\x04\x04\x04\x02\x01\x12\x03\
-    \x16\x04\x15\n\x0c\n\x05\x04\x04\x02\x01\x05\x12\x03\x16\x04\t\n\x0c\n\
-    \x05\x04\x04\x02\x01\x01\x12\x03\x16\n\x10\n\x0c\n\x05\x04\x04\x02\x01\
-    \x03\x12\x03\x16\x13\x14\n\x0b\n\x04\x04\x04\x02\x02\x12\x03\x17\x04\x16\
-    \n\x0c\n\x05\x04\x04\x02\x02\x05\x12\x03\x17\x04\n\n\x0c\n\x05\x04\x04\
-    \x02\x02\x01\x12\x03\x17\x0b\x11\n\x0c\n\x05\x04\x04\x02\x02\x03\x12\x03\
-    \x17\x14\x15\n\n\n\x02\x04\x05\x12\x04\x19\0\x1b\x01\n\n\n\x03\x04\x05\
-    \x01\x12\x03\x19\x08\x15\n\x0b\n\x04\x04\x05\x02\0\x12\x03\x1a\x04\x16\n\
-    \x0c\n\x05\x04\x05\x02\0\x05\x12\x03\x1a\x04\n\n\x0c\n\x05\x04\x05\x02\0\
-    \x01\x12\x03\x1a\x0b\x11\n\x0c\n\x05\x04\x05\x02\0\x03\x12\x03\x1a\x14\
-    \x15b\x06proto3\
+    dJ\xdb\x07\n\x06\x12\x04\0\0\x1c\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\
+    \n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\
+    \x17\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x12\n\x0c\n\x05\x04\0\x02\0\
+    \x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0b\r\n\
+    \x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x10\x11\n\x0b\n\x04\x04\0\x02\x01\
+    \x12\x03\x04\x04\x14\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\
+    \x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\x0f\n\x0c\n\x05\x04\0\x02\
+    \x01\x03\x12\x03\x04\x12\x13\n\n\n\x02\x04\x01\x12\x04\x06\0\x0b\x01\n\n\
+    \n\x03\x04\x01\x01\x12\x03\x06\x08\x0b\n\x0b\n\x04\x04\x01\x02\0\x12\x03\
+    \x07\x04\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x07\x04\n\n\x0c\n\x05\
+    \x04\x01\x02\0\x01\x12\x03\x07\x0b\r\n\x0c\n\x05\x04\x01\x02\0\x03\x12\
+    \x03\x07\x10\x11\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\x08\x04\x14\n\x0c\n\
+    \x05\x04\x01\x02\x01\x05\x12\x03\x08\x04\n\n\x0c\n\x05\x04\x01\x02\x01\
+    \x01\x12\x03\x08\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\x08\x12\
+    \x13\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\t\x04\x15\n\x0c\n\x05\x04\x01\
+    \x02\x02\x05\x12\x03\t\x04\t\n\x0c\n\x05\x04\x01\x02\x02\x01\x12\x03\t\n\
+    \x10\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\t\x13\x14\n\x0b\n\x04\x04\
+    \x01\x02\x03\x12\x03\n\x04\x1a\n\x0c\n\x05\x04\x01\x02\x03\x05\x12\x03\n\
+    \x04\t\n\x0c\n\x05\x04\x01\x02\x03\x01\x12\x03\n\n\x15\n\x0c\n\x05\x04\
+    \x01\x02\x03\x03\x12\x03\n\x18\x19\n\n\n\x02\x04\x02\x12\x04\x0c\0\x10\
+    \x01\n\n\n\x03\x04\x02\x01\x12\x03\x0c\x08\x17\n\x0b\n\x04\x04\x02\x02\0\
+    \x12\x03\r\x04\x16\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\r\x04\n\n\x0c\n\
+    \x05\x04\x02\x02\0\x01\x12\x03\r\x0b\x11\n\x0c\n\x05\x04\x02\x02\0\x03\
+    \x12\x03\r\x14\x15\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0e\x04\x14\n\x0c\
+    \n\x05\x04\x02\x02\x01\x05\x12\x03\x0e\x04\n\n\x0c\n\x05\x04\x02\x02\x01\
+    \x01\x12\x03\x0e\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\x0e\x12\
+    \x13\n\x0b\n\x04\x04\x02\x02\x02\x12\x03\x0f\x04\x15\n\x0c\n\x05\x04\x02\
+    \x02\x02\x05\x12\x03\x0f\x04\t\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\x03\
+    \x0f\n\x10\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x0f\x13\x14\n\n\n\x02\
+    \x04\x03\x12\x04\x11\0\x14\x01\n\n\n\x03\x04\x03\x01\x12\x03\x11\x08\x10\
+    \n\x0b\n\x04\x04\x03\x02\0\x12\x03\x12\x04\x16\n\x0c\n\x05\x04\x03\x02\0\
+    \x05\x12\x03\x12\x04\n\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x12\x0b\x11\
+    \n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x12\x14\x15\n\x0b\n\x04\x04\x03\
+    \x02\x01\x12\x03\x13\x04\x14\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\x03\x13\
+    \x04\n\n\x0c\n\x05\x04\x03\x02\x01\x01\x12\x03\x13\x0b\x0f\n\x0c\n\x05\
+    \x04\x03\x02\x01\x03\x12\x03\x13\x12\x13\n\n\n\x02\x04\x04\x12\x04\x15\0\
+    \x19\x01\n\n\n\x03\x04\x04\x01\x12\x03\x15\x08\x12\n\x0b\n\x04\x04\x04\
+    \x02\0\x12\x03\x16\x04\x17\n\x0c\n\x05\x04\x04\x02\0\x05\x12\x03\x16\x04\
+    \n\n\x0c\n\x05\x04\x04\x02\0\x01\x12\x03\x16\x0b\x12\n\x0c\n\x05\x04\x04\
+    \x02\0\x03\x12\x03\x16\x15\x16\n\x0b\n\x04\x04\x04\x02\x01\x12\x03\x17\
+    \x04\x15\n\x0c\n\x05\x04\x04\x02\x01\x05\x12\x03\x17\x04\t\n\x0c\n\x05\
+    \x04\x04\x02\x01\x01\x12\x03\x17\n\x10\n\x0c\n\x05\x04\x04\x02\x01\x03\
+    \x12\x03\x17\x13\x14\n\x0b\n\x04\x04\x04\x02\x02\x12\x03\x18\x04\x16\n\
+    \x0c\n\x05\x04\x04\x02\x02\x05\x12\x03\x18\x04\n\n\x0c\n\x05\x04\x04\x02\
+    \x02\x01\x12\x03\x18\x0b\x11\n\x0c\n\x05\x04\x04\x02\x02\x03\x12\x03\x18\
+    \x14\x15\n\n\n\x02\x04\x05\x12\x04\x1a\0\x1c\x01\n\n\n\x03\x04\x05\x01\
+    \x12\x03\x1a\x08\x15\n\x0b\n\x04\x04\x05\x02\0\x12\x03\x1b\x04\x16\n\x0c\
+    \n\x05\x04\x05\x02\0\x05\x12\x03\x1b\x04\n\n\x0c\n\x05\x04\x05\x02\0\x01\
+    \x12\x03\x1b\x0b\x11\n\x0c\n\x05\x04\x05\x02\0\x03\x12\x03\x1b\x14\x15b\
+    \x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 3 - 0
rust-lib/flowy-document-infra/src/protobuf/model/mod.rs

@@ -1,5 +1,8 @@
 // Auto-generated, do not edit 
 
+mod ws; 
+pub use ws::*; 
+
 mod revision; 
 pub use revision::*; 
 

+ 38 - 38
rust-lib/flowy-document-infra/src/protobuf/model/revision.rs

@@ -808,44 +808,44 @@ static file_descriptor_proto_data: &'static [u8] = b"\
     \n\rRevisionRange\x12\x15\n\x06doc_id\x18\x01\x20\x01(\tR\x05docId\x12\
     \x14\n\x05start\x18\x02\x20\x01(\x03R\x05start\x12\x10\n\x03end\x18\x03\
     \x20\x01(\x03R\x03end*\x20\n\x07RevType\x12\t\n\x05Local\x10\0\x12\n\n\
-    \x06Remote\x10\x01J\xea\x05\n\x06\x12\x04\0\0\x14\x01\n\x08\n\x01\x0c\
-    \x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x01\0\x03\x01\n\n\n\x03\x04\0\
-    \x01\x12\x03\x01\x08\r\n\x0b\n\x04\x04\0\x02\0\x12\x03\x02\x04\x14\n\x0c\
-    \n\x05\x04\0\x02\0\x05\x12\x03\x02\x04\t\n\x0c\n\x05\x04\0\x02\0\x01\x12\
-    \x03\x02\n\x0f\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x02\x12\x13\n\n\n\x02\
-    \x04\x01\x12\x04\x04\0\x0b\x01\n\n\n\x03\x04\x01\x01\x12\x03\x04\x08\x10\
-    \n\x0b\n\x04\x04\x01\x02\0\x12\x03\x05\x04\x1a\n\x0c\n\x05\x04\x01\x02\0\
-    \x05\x12\x03\x05\x04\t\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x05\n\x15\n\
-    \x0c\n\x05\x04\x01\x02\0\x03\x12\x03\x05\x18\x19\n\x0b\n\x04\x04\x01\x02\
-    \x01\x12\x03\x06\x04\x15\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\x06\x04\
-    \t\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\x06\n\x10\n\x0c\n\x05\x04\x01\
-    \x02\x01\x03\x12\x03\x06\x13\x14\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\x07\
-    \x04\x19\n\x0c\n\x05\x04\x01\x02\x02\x05\x12\x03\x07\x04\t\n\x0c\n\x05\
-    \x04\x01\x02\x02\x01\x12\x03\x07\n\x14\n\x0c\n\x05\x04\x01\x02\x02\x03\
-    \x12\x03\x07\x17\x18\n\x0b\n\x04\x04\x01\x02\x03\x12\x03\x08\x04\x13\n\
-    \x0c\n\x05\x04\x01\x02\x03\x05\x12\x03\x08\x04\n\n\x0c\n\x05\x04\x01\x02\
-    \x03\x01\x12\x03\x08\x0b\x0e\n\x0c\n\x05\x04\x01\x02\x03\x03\x12\x03\x08\
-    \x11\x12\n\x0b\n\x04\x04\x01\x02\x04\x12\x03\t\x04\x16\n\x0c\n\x05\x04\
-    \x01\x02\x04\x05\x12\x03\t\x04\n\n\x0c\n\x05\x04\x01\x02\x04\x01\x12\x03\
-    \t\x0b\x11\n\x0c\n\x05\x04\x01\x02\x04\x03\x12\x03\t\x14\x15\n\x0b\n\x04\
-    \x04\x01\x02\x05\x12\x03\n\x04\x13\n\x0c\n\x05\x04\x01\x02\x05\x06\x12\
-    \x03\n\x04\x0b\n\x0c\n\x05\x04\x01\x02\x05\x01\x12\x03\n\x0c\x0e\n\x0c\n\
-    \x05\x04\x01\x02\x05\x03\x12\x03\n\x11\x12\n\n\n\x02\x04\x02\x12\x04\x0c\
-    \0\x10\x01\n\n\n\x03\x04\x02\x01\x12\x03\x0c\x08\x15\n\x0b\n\x04\x04\x02\
-    \x02\0\x12\x03\r\x04\x16\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\r\x04\n\n\
-    \x0c\n\x05\x04\x02\x02\0\x01\x12\x03\r\x0b\x11\n\x0c\n\x05\x04\x02\x02\0\
-    \x03\x12\x03\r\x14\x15\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0e\x04\x14\n\
-    \x0c\n\x05\x04\x02\x02\x01\x05\x12\x03\x0e\x04\t\n\x0c\n\x05\x04\x02\x02\
-    \x01\x01\x12\x03\x0e\n\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\x0e\
-    \x12\x13\n\x0b\n\x04\x04\x02\x02\x02\x12\x03\x0f\x04\x12\n\x0c\n\x05\x04\
-    \x02\x02\x02\x05\x12\x03\x0f\x04\t\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\
-    \x03\x0f\n\r\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x0f\x10\x11\n\n\n\
-    \x02\x05\0\x12\x04\x11\0\x14\x01\n\n\n\x03\x05\0\x01\x12\x03\x11\x05\x0c\
-    \n\x0b\n\x04\x05\0\x02\0\x12\x03\x12\x04\x0e\n\x0c\n\x05\x05\0\x02\0\x01\
-    \x12\x03\x12\x04\t\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x12\x0c\r\n\x0b\n\
-    \x04\x05\0\x02\x01\x12\x03\x13\x04\x0f\n\x0c\n\x05\x05\0\x02\x01\x01\x12\
-    \x03\x13\x04\n\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x13\r\x0eb\x06proto\
-    3\
+    \x06Remote\x10\x01J\xea\x05\n\x06\x12\x04\0\0\x15\x01\n\x08\n\x01\x0c\
+    \x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x04\x01\n\n\n\x03\x04\0\
+    \x01\x12\x03\x02\x08\r\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x14\n\x0c\
+    \n\x05\x04\0\x02\0\x05\x12\x03\x03\x04\t\n\x0c\n\x05\x04\0\x02\0\x01\x12\
+    \x03\x03\n\x0f\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x12\x13\n\n\n\x02\
+    \x04\x01\x12\x04\x05\0\x0c\x01\n\n\n\x03\x04\x01\x01\x12\x03\x05\x08\x10\
+    \n\x0b\n\x04\x04\x01\x02\0\x12\x03\x06\x04\x1a\n\x0c\n\x05\x04\x01\x02\0\
+    \x05\x12\x03\x06\x04\t\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x06\n\x15\n\
+    \x0c\n\x05\x04\x01\x02\0\x03\x12\x03\x06\x18\x19\n\x0b\n\x04\x04\x01\x02\
+    \x01\x12\x03\x07\x04\x15\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\x07\x04\
+    \t\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\x07\n\x10\n\x0c\n\x05\x04\x01\
+    \x02\x01\x03\x12\x03\x07\x13\x14\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\x08\
+    \x04\x19\n\x0c\n\x05\x04\x01\x02\x02\x05\x12\x03\x08\x04\t\n\x0c\n\x05\
+    \x04\x01\x02\x02\x01\x12\x03\x08\n\x14\n\x0c\n\x05\x04\x01\x02\x02\x03\
+    \x12\x03\x08\x17\x18\n\x0b\n\x04\x04\x01\x02\x03\x12\x03\t\x04\x13\n\x0c\
+    \n\x05\x04\x01\x02\x03\x05\x12\x03\t\x04\n\n\x0c\n\x05\x04\x01\x02\x03\
+    \x01\x12\x03\t\x0b\x0e\n\x0c\n\x05\x04\x01\x02\x03\x03\x12\x03\t\x11\x12\
+    \n\x0b\n\x04\x04\x01\x02\x04\x12\x03\n\x04\x16\n\x0c\n\x05\x04\x01\x02\
+    \x04\x05\x12\x03\n\x04\n\n\x0c\n\x05\x04\x01\x02\x04\x01\x12\x03\n\x0b\
+    \x11\n\x0c\n\x05\x04\x01\x02\x04\x03\x12\x03\n\x14\x15\n\x0b\n\x04\x04\
+    \x01\x02\x05\x12\x03\x0b\x04\x13\n\x0c\n\x05\x04\x01\x02\x05\x06\x12\x03\
+    \x0b\x04\x0b\n\x0c\n\x05\x04\x01\x02\x05\x01\x12\x03\x0b\x0c\x0e\n\x0c\n\
+    \x05\x04\x01\x02\x05\x03\x12\x03\x0b\x11\x12\n\n\n\x02\x04\x02\x12\x04\r\
+    \0\x11\x01\n\n\n\x03\x04\x02\x01\x12\x03\r\x08\x15\n\x0b\n\x04\x04\x02\
+    \x02\0\x12\x03\x0e\x04\x16\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\x0e\x04\
+    \n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\x0e\x0b\x11\n\x0c\n\x05\x04\x02\
+    \x02\0\x03\x12\x03\x0e\x14\x15\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0f\
+    \x04\x14\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\x03\x0f\x04\t\n\x0c\n\x05\
+    \x04\x02\x02\x01\x01\x12\x03\x0f\n\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\
+    \x12\x03\x0f\x12\x13\n\x0b\n\x04\x04\x02\x02\x02\x12\x03\x10\x04\x12\n\
+    \x0c\n\x05\x04\x02\x02\x02\x05\x12\x03\x10\x04\t\n\x0c\n\x05\x04\x02\x02\
+    \x02\x01\x12\x03\x10\n\r\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x10\x10\
+    \x11\n\n\n\x02\x05\0\x12\x04\x12\0\x15\x01\n\n\n\x03\x05\0\x01\x12\x03\
+    \x12\x05\x0c\n\x0b\n\x04\x05\0\x02\0\x12\x03\x13\x04\x0e\n\x0c\n\x05\x05\
+    \0\x02\0\x01\x12\x03\x13\x04\t\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x13\
+    \x0c\r\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x14\x04\x0f\n\x0c\n\x05\x05\0\
+    \x02\x01\x01\x12\x03\x14\x04\n\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x14\
+    \r\x0eb\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 22 - 22
rust-lib/flowy-document/src/protobuf/model/ws.rs → rust-lib/flowy-document-infra/src/protobuf/model/ws.rs

@@ -320,28 +320,28 @@ static file_descriptor_proto_data: &'static [u8] = b"\
     \x02ty\x12\x12\n\x04data\x18\x03\x20\x01(\x0cR\x04data*O\n\nWsDataType\
     \x12\t\n\x05Acked\x10\0\x12\x0b\n\x07PushRev\x10\x01\x12\x0b\n\x07PullRe\
     v\x10\x02\x12\x0c\n\x08Conflict\x10\x03\x12\x0e\n\nNewDocUser\x10\x04J\
-    \xb4\x03\n\x06\x12\x04\0\0\x0c\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\
-    \x02\x04\0\x12\x04\x01\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x01\x08\x16\
-    \n\x0b\n\x04\x04\0\x02\0\x12\x03\x02\x04\x16\n\x0c\n\x05\x04\0\x02\0\x05\
-    \x12\x03\x02\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x02\x0b\x11\n\x0c\
-    \n\x05\x04\0\x02\0\x03\x12\x03\x02\x14\x15\n\x0b\n\x04\x04\0\x02\x01\x12\
-    \x03\x03\x04\x16\n\x0c\n\x05\x04\0\x02\x01\x06\x12\x03\x03\x04\x0e\n\x0c\
-    \n\x05\x04\0\x02\x01\x01\x12\x03\x03\x0f\x11\n\x0c\n\x05\x04\0\x02\x01\
-    \x03\x12\x03\x03\x14\x15\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x04\x04\x13\n\
-    \x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x04\x04\t\n\x0c\n\x05\x04\0\x02\x02\
-    \x01\x12\x03\x04\n\x0e\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\x04\x11\x12\
-    \n\n\n\x02\x05\0\x12\x04\x06\0\x0c\x01\n\n\n\x03\x05\0\x01\x12\x03\x06\
-    \x05\x0f\n\x0b\n\x04\x05\0\x02\0\x12\x03\x07\x04\x0e\n\x0c\n\x05\x05\0\
-    \x02\0\x01\x12\x03\x07\x04\t\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x07\x0c\
-    \r\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x08\x04\x10\n\x0c\n\x05\x05\0\x02\
-    \x01\x01\x12\x03\x08\x04\x0b\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x08\
-    \x0e\x0f\n\x0b\n\x04\x05\0\x02\x02\x12\x03\t\x04\x10\n\x0c\n\x05\x05\0\
-    \x02\x02\x01\x12\x03\t\x04\x0b\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\t\
-    \x0e\x0f\n\x0b\n\x04\x05\0\x02\x03\x12\x03\n\x04\x11\n\x0c\n\x05\x05\0\
-    \x02\x03\x01\x12\x03\n\x04\x0c\n\x0c\n\x05\x05\0\x02\x03\x02\x12\x03\n\
-    \x0f\x10\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x0b\x04\x13\n\x0c\n\x05\x05\0\
-    \x02\x04\x01\x12\x03\x0b\x04\x0e\n\x0c\n\x05\x05\0\x02\x04\x02\x12\x03\
-    \x0b\x11\x12b\x06proto3\
+    \xb4\x03\n\x06\x12\x04\0\0\r\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\
+    \x02\x04\0\x12\x04\x02\0\x06\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x16\
+    \n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x16\n\x0c\n\x05\x04\0\x02\0\x05\
+    \x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0b\x11\n\x0c\
+    \n\x05\x04\0\x02\0\x03\x12\x03\x03\x14\x15\n\x0b\n\x04\x04\0\x02\x01\x12\
+    \x03\x04\x04\x16\n\x0c\n\x05\x04\0\x02\x01\x06\x12\x03\x04\x04\x0e\n\x0c\
+    \n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0f\x11\n\x0c\n\x05\x04\0\x02\x01\
+    \x03\x12\x03\x04\x14\x15\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x05\x04\x13\n\
+    \x0c\n\x05\x04\0\x02\x02\x05\x12\x03\x05\x04\t\n\x0c\n\x05\x04\0\x02\x02\
+    \x01\x12\x03\x05\n\x0e\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\x05\x11\x12\
+    \n\n\n\x02\x05\0\x12\x04\x07\0\r\x01\n\n\n\x03\x05\0\x01\x12\x03\x07\x05\
+    \x0f\n\x0b\n\x04\x05\0\x02\0\x12\x03\x08\x04\x0e\n\x0c\n\x05\x05\0\x02\0\
+    \x01\x12\x03\x08\x04\t\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x08\x0c\r\n\
+    \x0b\n\x04\x05\0\x02\x01\x12\x03\t\x04\x10\n\x0c\n\x05\x05\0\x02\x01\x01\
+    \x12\x03\t\x04\x0b\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\t\x0e\x0f\n\x0b\
+    \n\x04\x05\0\x02\x02\x12\x03\n\x04\x10\n\x0c\n\x05\x05\0\x02\x02\x01\x12\
+    \x03\n\x04\x0b\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\n\x0e\x0f\n\x0b\n\
+    \x04\x05\0\x02\x03\x12\x03\x0b\x04\x11\n\x0c\n\x05\x05\0\x02\x03\x01\x12\
+    \x03\x0b\x04\x0c\n\x0c\n\x05\x05\0\x02\x03\x02\x12\x03\x0b\x0f\x10\n\x0b\
+    \n\x04\x05\0\x02\x04\x12\x03\x0c\x04\x13\n\x0c\n\x05\x05\0\x02\x04\x01\
+    \x12\x03\x0c\x04\x0e\n\x0c\n\x05\x05\0\x02\x04\x02\x12\x03\x0c\x11\x12b\
+    \x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 1 - 0
rust-lib/flowy-document-infra/src/protobuf/proto/doc.proto

@@ -1,4 +1,5 @@
 syntax = "proto3";
+
 message CreateDocParams {
     string id = 1;
     string data = 2;

+ 1 - 0
rust-lib/flowy-document-infra/src/protobuf/proto/revision.proto

@@ -1,4 +1,5 @@
 syntax = "proto3";
+
 message RevId {
     int64 value = 1;
 }

+ 1 - 0
rust-lib/flowy-document/src/protobuf/proto/ws.proto → rust-lib/flowy-document-infra/src/protobuf/proto/ws.proto

@@ -1,4 +1,5 @@
 syntax = "proto3";
+
 message WsDocumentData {
     string doc_id = 1;
     WsDataType ty = 2;

+ 1 - 1
rust-lib/flowy-document/Flowy.toml

@@ -1,3 +1,3 @@
 
-proto_crates = ["src/entities", "src/event.rs", "src/errors.rs", "src/notify"]
+proto_crates = ["src/event.rs", "src/errors.rs", "src/notify"]
 event_files = []

+ 0 - 1
rust-lib/flowy-document/src/entities/mod.rs

@@ -1 +0,0 @@
-pub mod ws;

+ 8 - 19
rust-lib/flowy-document/src/errors.rs

@@ -43,14 +43,10 @@ impl DocError {
 
     pub fn is_record_not_found(&self) -> bool { self.code == ErrorCode::DocNotfound }
 
-    static_doc_error!(id_invalid, ErrorCode::DocIdInvalid);
     static_doc_error!(internal, ErrorCode::InternalError);
-    static_doc_error!(record_not_found, ErrorCode::DocNotfound);
     static_doc_error!(unauthorized, ErrorCode::UserUnauthorized);
     static_doc_error!(ws, ErrorCode::WsConnectError);
-    static_doc_error!(undo, ErrorCode::UndoFail);
-    static_doc_error!(redo, ErrorCode::RedoFail);
-    static_doc_error!(out_of_bound, ErrorCode::OutOfBound);
+    static_doc_error!(record_not_found, ErrorCode::DocNotfound);
     static_doc_error!(duplicate_rev, ErrorCode::DuplicateRevision);
 }
 
@@ -63,25 +59,14 @@ where
 
 #[derive(Debug, Clone, ProtoBuf_Enum, Display, PartialEq, Eq)]
 pub enum ErrorCode {
-    #[display(fmt = "DocIdInvalid")]
-    DocIdInvalid      = 0,
+    #[display(fmt = "Document websocket error")]
+    WsConnectError    = 0,
 
     #[display(fmt = "DocNotfound")]
     DocNotfound       = 1,
 
-    #[display(fmt = "Document websocket error")]
-    WsConnectError    = 10,
-
-    #[display(fmt = "Undo failed")]
-    UndoFail          = 200,
-    #[display(fmt = "Redo failed")]
-    RedoFail          = 201,
-
-    #[display(fmt = "Interval out of bound")]
-    OutOfBound        = 202,
-
     #[display(fmt = "Duplicate revision")]
-    DuplicateRevision = 400,
+    DuplicateRevision = 2,
 
     #[display(fmt = "UserUnauthorized")]
     UserUnauthorized  = 999,
@@ -107,6 +92,10 @@ impl std::convert::From<flowy_ot::errors::OTError> for DocError {
     fn from(error: flowy_ot::errors::OTError) -> Self { DocError::internal().context(error) }
 }
 
+impl std::convert::From<flowy_document_infra::errors::DocumentError> for DocError {
+    fn from(error: flowy_document_infra::errors::DocumentError) -> Self { DocError::internal().context(error) }
+}
+
 impl std::convert::From<std::io::Error> for DocError {
     fn from(error: std::io::Error) -> Self { DocError::internal().context(error) }
 }

+ 0 - 1
rust-lib/flowy-document/src/lib.rs

@@ -1,6 +1,5 @@
 #![feature(vecdeque_binary_search)]
 
-pub mod entities;
 pub mod errors;
 pub mod module;
 mod notify;

+ 26 - 48
rust-lib/flowy-document/src/protobuf/model/errors.rs

@@ -51,7 +51,7 @@ impl DocError {
         self.code
     }
     pub fn clear_code(&mut self) {
-        self.code = ErrorCode::DocIdInvalid;
+        self.code = ErrorCode::WsConnectError;
     }
 
     // Param is passed by value, moved
@@ -113,7 +113,7 @@ impl ::protobuf::Message for DocError {
     #[allow(unused_variables)]
     fn compute_size(&self) -> u32 {
         let mut my_size = 0;
-        if self.code != ErrorCode::DocIdInvalid {
+        if self.code != ErrorCode::WsConnectError {
             my_size += ::protobuf::rt::enum_size(1, self.code);
         }
         if !self.msg.is_empty() {
@@ -125,7 +125,7 @@ impl ::protobuf::Message for DocError {
     }
 
     fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
-        if self.code != ErrorCode::DocIdInvalid {
+        if self.code != ErrorCode::WsConnectError {
             os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.code))?;
         }
         if !self.msg.is_empty() {
@@ -195,7 +195,7 @@ impl ::protobuf::Message for DocError {
 
 impl ::protobuf::Clear for DocError {
     fn clear(&mut self) {
-        self.code = ErrorCode::DocIdInvalid;
+        self.code = ErrorCode::WsConnectError;
         self.msg.clear();
         self.unknown_fields.clear();
     }
@@ -215,13 +215,9 @@ impl ::protobuf::reflect::ProtobufValue for DocError {
 
 #[derive(Clone,PartialEq,Eq,Debug,Hash)]
 pub enum ErrorCode {
-    DocIdInvalid = 0,
+    WsConnectError = 0,
     DocNotfound = 1,
-    WsConnectError = 10,
-    UndoFail = 200,
-    RedoFail = 201,
-    OutOfBound = 202,
-    DuplicateRevision = 400,
+    DuplicateRevision = 2,
     UserUnauthorized = 999,
     InternalError = 1000,
 }
@@ -233,13 +229,9 @@ impl ::protobuf::ProtobufEnum for ErrorCode {
 
     fn from_i32(value: i32) -> ::std::option::Option<ErrorCode> {
         match value {
-            0 => ::std::option::Option::Some(ErrorCode::DocIdInvalid),
+            0 => ::std::option::Option::Some(ErrorCode::WsConnectError),
             1 => ::std::option::Option::Some(ErrorCode::DocNotfound),
-            10 => ::std::option::Option::Some(ErrorCode::WsConnectError),
-            200 => ::std::option::Option::Some(ErrorCode::UndoFail),
-            201 => ::std::option::Option::Some(ErrorCode::RedoFail),
-            202 => ::std::option::Option::Some(ErrorCode::OutOfBound),
-            400 => ::std::option::Option::Some(ErrorCode::DuplicateRevision),
+            2 => ::std::option::Option::Some(ErrorCode::DuplicateRevision),
             999 => ::std::option::Option::Some(ErrorCode::UserUnauthorized),
             1000 => ::std::option::Option::Some(ErrorCode::InternalError),
             _ => ::std::option::Option::None
@@ -248,12 +240,8 @@ impl ::protobuf::ProtobufEnum for ErrorCode {
 
     fn values() -> &'static [Self] {
         static values: &'static [ErrorCode] = &[
-            ErrorCode::DocIdInvalid,
-            ErrorCode::DocNotfound,
             ErrorCode::WsConnectError,
-            ErrorCode::UndoFail,
-            ErrorCode::RedoFail,
-            ErrorCode::OutOfBound,
+            ErrorCode::DocNotfound,
             ErrorCode::DuplicateRevision,
             ErrorCode::UserUnauthorized,
             ErrorCode::InternalError,
@@ -274,7 +262,7 @@ impl ::std::marker::Copy for ErrorCode {
 
 impl ::std::default::Default for ErrorCode {
     fn default() -> Self {
-        ErrorCode::DocIdInvalid
+        ErrorCode::WsConnectError
     }
 }
 
@@ -286,39 +274,29 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode {
 
 static file_descriptor_proto_data: &'static [u8] = b"\
     \n\x0cerrors.proto\"<\n\x08DocError\x12\x1e\n\x04code\x18\x01\x20\x01(\
-    \x0e2\n.ErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03msg*\
-    \xb4\x01\n\tErrorCode\x12\x10\n\x0cDocIdInvalid\x10\0\x12\x0f\n\x0bDocNo\
-    tfound\x10\x01\x12\x12\n\x0eWsConnectError\x10\n\x12\r\n\x08UndoFail\x10\
-    \xc8\x01\x12\r\n\x08RedoFail\x10\xc9\x01\x12\x0f\n\nOutOfBound\x10\xca\
-    \x01\x12\x16\n\x11DuplicateRevision\x10\x90\x03\x12\x15\n\x10UserUnautho\
-    rized\x10\xe7\x07\x12\x12\n\rInternalError\x10\xe8\x07J\xa1\x04\n\x06\
-    \x12\x04\0\0\x10\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\
+    \x0e2\n.ErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03msg*r\
+    \n\tErrorCode\x12\x12\n\x0eWsConnectError\x10\0\x12\x0f\n\x0bDocNotfound\
+    \x10\x01\x12\x15\n\x11DuplicateRevision\x10\x02\x12\x15\n\x10UserUnautho\
+    rized\x10\xe7\x07\x12\x12\n\rInternalError\x10\xe8\x07J\xfd\x02\n\x06\
+    \x12\x04\0\0\x0c\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\
     \x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x10\n\x0b\n\x04\
     \x04\0\x02\0\x12\x03\x03\x04\x17\n\x0c\n\x05\x04\0\x02\0\x06\x12\x03\x03\
     \x04\r\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0e\x12\n\x0c\n\x05\x04\0\
     \x02\0\x03\x12\x03\x03\x15\x16\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\
     \x13\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\
     \x02\x01\x01\x12\x03\x04\x0b\x0e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\
-    \x04\x11\x12\n\n\n\x02\x05\0\x12\x04\x06\0\x10\x01\n\n\n\x03\x05\0\x01\
-    \x12\x03\x06\x05\x0e\n\x0b\n\x04\x05\0\x02\0\x12\x03\x07\x04\x15\n\x0c\n\
-    \x05\x05\0\x02\0\x01\x12\x03\x07\x04\x10\n\x0c\n\x05\x05\0\x02\0\x02\x12\
-    \x03\x07\x13\x14\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x08\x04\x14\n\x0c\n\
+    \x04\x11\x12\n\n\n\x02\x05\0\x12\x04\x06\0\x0c\x01\n\n\n\x03\x05\0\x01\
+    \x12\x03\x06\x05\x0e\n\x0b\n\x04\x05\0\x02\0\x12\x03\x07\x04\x17\n\x0c\n\
+    \x05\x05\0\x02\0\x01\x12\x03\x07\x04\x12\n\x0c\n\x05\x05\0\x02\0\x02\x12\
+    \x03\x07\x15\x16\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x08\x04\x14\n\x0c\n\
     \x05\x05\0\x02\x01\x01\x12\x03\x08\x04\x0f\n\x0c\n\x05\x05\0\x02\x01\x02\
-    \x12\x03\x08\x12\x13\n\x0b\n\x04\x05\0\x02\x02\x12\x03\t\x04\x18\n\x0c\n\
-    \x05\x05\0\x02\x02\x01\x12\x03\t\x04\x12\n\x0c\n\x05\x05\0\x02\x02\x02\
-    \x12\x03\t\x15\x17\n\x0b\n\x04\x05\0\x02\x03\x12\x03\n\x04\x13\n\x0c\n\
-    \x05\x05\0\x02\x03\x01\x12\x03\n\x04\x0c\n\x0c\n\x05\x05\0\x02\x03\x02\
-    \x12\x03\n\x0f\x12\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x0b\x04\x13\n\x0c\n\
-    \x05\x05\0\x02\x04\x01\x12\x03\x0b\x04\x0c\n\x0c\n\x05\x05\0\x02\x04\x02\
-    \x12\x03\x0b\x0f\x12\n\x0b\n\x04\x05\0\x02\x05\x12\x03\x0c\x04\x15\n\x0c\
-    \n\x05\x05\0\x02\x05\x01\x12\x03\x0c\x04\x0e\n\x0c\n\x05\x05\0\x02\x05\
-    \x02\x12\x03\x0c\x11\x14\n\x0b\n\x04\x05\0\x02\x06\x12\x03\r\x04\x1c\n\
-    \x0c\n\x05\x05\0\x02\x06\x01\x12\x03\r\x04\x15\n\x0c\n\x05\x05\0\x02\x06\
-    \x02\x12\x03\r\x18\x1b\n\x0b\n\x04\x05\0\x02\x07\x12\x03\x0e\x04\x1b\n\
-    \x0c\n\x05\x05\0\x02\x07\x01\x12\x03\x0e\x04\x14\n\x0c\n\x05\x05\0\x02\
-    \x07\x02\x12\x03\x0e\x17\x1a\n\x0b\n\x04\x05\0\x02\x08\x12\x03\x0f\x04\
-    \x19\n\x0c\n\x05\x05\0\x02\x08\x01\x12\x03\x0f\x04\x11\n\x0c\n\x05\x05\0\
-    \x02\x08\x02\x12\x03\x0f\x14\x18b\x06proto3\
+    \x12\x03\x08\x12\x13\n\x0b\n\x04\x05\0\x02\x02\x12\x03\t\x04\x1a\n\x0c\n\
+    \x05\x05\0\x02\x02\x01\x12\x03\t\x04\x15\n\x0c\n\x05\x05\0\x02\x02\x02\
+    \x12\x03\t\x18\x19\n\x0b\n\x04\x05\0\x02\x03\x12\x03\n\x04\x1b\n\x0c\n\
+    \x05\x05\0\x02\x03\x01\x12\x03\n\x04\x14\n\x0c\n\x05\x05\0\x02\x03\x02\
+    \x12\x03\n\x17\x1a\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x0b\x04\x19\n\x0c\n\
+    \x05\x05\0\x02\x04\x01\x12\x03\x0b\x04\x11\n\x0c\n\x05\x05\0\x02\x04\x02\
+    \x12\x03\x0b\x14\x18b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 0 - 3
rust-lib/flowy-document/src/protobuf/model/mod.rs

@@ -1,8 +1,5 @@
 // Auto-generated, do not edit 
 
-mod ws; 
-pub use ws::*; 
-
 mod observable; 
 pub use observable::*; 
 

+ 2 - 6
rust-lib/flowy-document/src/protobuf/proto/errors.proto

@@ -5,13 +5,9 @@ message DocError {
     string msg = 2;
 }
 enum ErrorCode {
-    DocIdInvalid = 0;
+    WsConnectError = 0;
     DocNotfound = 1;
-    WsConnectError = 10;
-    UndoFail = 200;
-    RedoFail = 201;
-    OutOfBound = 202;
-    DuplicateRevision = 400;
+    DuplicateRevision = 2;
     UserUnauthorized = 999;
     InternalError = 1000;
 }

+ 0 - 1
rust-lib/flowy-document/src/services/doc/document/selection.rs

@@ -1 +0,0 @@
-

+ 8 - 24
rust-lib/flowy-document/src/services/doc/edit/doc_actor.rs

@@ -1,10 +1,10 @@
-use crate::{
-    errors::DocResult,
-    services::doc::{Document, UndoResult},
-};
 use async_stream::stream;
 use bytes::Bytes;
-use flowy_document_infra::entities::doc::{RevId, Revision};
+use flowy_document_infra::{
+    core::{history::UndoResult, Document},
+    entities::doc::{RevId, Revision},
+    errors::DocumentError,
+};
 use flowy_ot::core::{Attribute, Delta, Interval, OperationTransformable};
 use futures::stream::StreamExt;
 use std::{convert::TryFrom, sync::Arc};
@@ -46,7 +46,7 @@ impl DocumentActor {
             .await;
     }
 
-    async fn handle_message(&self, msg: DocumentMsg) -> DocResult<()> {
+    async fn handle_message(&self, msg: DocumentMsg) -> Result<(), DocumentError> {
         match msg {
             DocumentMsg::Delta { delta, ret } => {
                 let result = self.composed_delta(delta).await;
@@ -107,7 +107,7 @@ impl DocumentActor {
     }
 
     #[tracing::instrument(level = "debug", skip(self, delta), fields(compose_result), err)]
-    async fn composed_delta(&self, delta: Delta) -> DocResult<()> {
+    async fn composed_delta(&self, delta: Delta) -> Result<(), DocumentError> {
         // tracing::debug!("{:?} thread handle_message", thread::current(),);
         let mut document = self.document.write().await;
         tracing::Span::current().record(
@@ -122,23 +122,7 @@ impl DocumentActor {
     }
 }
 
-// #[tracing::instrument(level = "debug", skip(self, params), err)]
-// fn update_doc_on_server(&self, params: UpdateDocParams) -> Result<(),
-//     DocError> {     let token = self.user.token()?;
-//     let server = self.server.clone();
-//     tokio::spawn(async move {
-//         match server.update_doc(&token, params).await {
-//             Ok(_) => {},
-//             Err(e) => {
-//                 // TODO: retry?
-//                 log::error!("Update doc failed: {}", e);
-//             },
-//         }
-//     });
-//     Ok(())
-// }
-
-pub type Ret<T> = oneshot::Sender<DocResult<T>>;
+pub type Ret<T> = oneshot::Sender<Result<T, DocumentError>>;
 pub enum DocumentMsg {
     Delta {
         delta: Delta,

+ 26 - 25
rust-lib/flowy-document/src/services/doc/edit/edit_doc.rs

@@ -1,23 +1,21 @@
 use crate::{
-    entities::ws::{WsDataType, WsDocumentData},
     errors::{internal_error, DocError, DocResult},
     module::DocumentUser,
     services::{
-        doc::{
-            DocumentActor,
-            DocumentMsg,
-            OpenDocAction,
-            RevisionManager,
-            RevisionServer,
-            TransformDeltas,
-            UndoResult,
-        },
+        doc::{DocumentActor, DocumentMsg, OpenDocAction, RevisionManager, RevisionServer, TransformDeltas},
         ws::{DocumentWebSocket, WsDocumentHandler},
     },
 };
 use bytes::Bytes;
 use flowy_database::ConnectionPool;
-use flowy_document_infra::entities::doc::{DocDelta, RevId, RevType, Revision, RevisionRange};
+use flowy_document_infra::{
+    core::history::UndoResult,
+    entities::{
+        doc::{DocDelta, RevId, RevType, Revision, RevisionRange},
+        ws::{WsDataType, WsDocumentData},
+    },
+    errors::DocumentResult,
+};
 use flowy_infra::retry::{ExponentialBackoff, Retry};
 use flowy_ot::core::{Attribute, Delta, Interval};
 use flowy_ws::WsState;
@@ -62,7 +60,7 @@ impl ClientEditDoc {
     }
 
     pub async fn insert<T: ToString>(&self, index: usize, data: T) -> Result<(), DocError> {
-        let (ret, rx) = oneshot::channel::<DocResult<Delta>>();
+        let (ret, rx) = oneshot::channel::<DocumentResult<Delta>>();
         let msg = DocumentMsg::Insert {
             index,
             data: data.to_string(),
@@ -75,7 +73,7 @@ impl ClientEditDoc {
     }
 
     pub async fn delete(&self, interval: Interval) -> Result<(), DocError> {
-        let (ret, rx) = oneshot::channel::<DocResult<Delta>>();
+        let (ret, rx) = oneshot::channel::<DocumentResult<Delta>>();
         let msg = DocumentMsg::Delete { interval, ret };
         let _ = self.document.send(msg);
         let delta = rx.await.map_err(internal_error)??;
@@ -84,7 +82,7 @@ impl ClientEditDoc {
     }
 
     pub async fn format(&self, interval: Interval, attribute: Attribute) -> Result<(), DocError> {
-        let (ret, rx) = oneshot::channel::<DocResult<Delta>>();
+        let (ret, rx) = oneshot::channel::<DocumentResult<Delta>>();
         let msg = DocumentMsg::Format {
             interval,
             attribute,
@@ -97,7 +95,7 @@ impl ClientEditDoc {
     }
 
     pub async fn replace<T: ToString>(&mut self, interval: Interval, data: T) -> Result<(), DocError> {
-        let (ret, rx) = oneshot::channel::<DocResult<Delta>>();
+        let (ret, rx) = oneshot::channel::<DocumentResult<Delta>>();
         let msg = DocumentMsg::Replace {
             interval,
             data: data.to_string(),
@@ -124,21 +122,23 @@ impl ClientEditDoc {
     }
 
     pub async fn undo(&self) -> Result<UndoResult, DocError> {
-        let (ret, rx) = oneshot::channel::<DocResult<UndoResult>>();
+        let (ret, rx) = oneshot::channel::<DocumentResult<UndoResult>>();
         let msg = DocumentMsg::Undo { ret };
         let _ = self.document.send(msg);
-        rx.await.map_err(internal_error)?
+        let r = rx.await.map_err(internal_error)??;
+        Ok(r)
     }
 
     pub async fn redo(&self) -> Result<UndoResult, DocError> {
-        let (ret, rx) = oneshot::channel::<DocResult<UndoResult>>();
+        let (ret, rx) = oneshot::channel::<DocumentResult<UndoResult>>();
         let msg = DocumentMsg::Redo { ret };
         let _ = self.document.send(msg);
-        rx.await.map_err(internal_error)?
+        let r = rx.await.map_err(internal_error)??;
+        Ok(r)
     }
 
     pub async fn delta(&self) -> DocResult<DocDelta> {
-        let (ret, rx) = oneshot::channel::<DocResult<String>>();
+        let (ret, rx) = oneshot::channel::<DocumentResult<String>>();
         let msg = DocumentMsg::Doc { ret };
         let _ = self.document.send(msg);
         let data = rx.await.map_err(internal_error)??;
@@ -161,7 +161,7 @@ impl ClientEditDoc {
     #[tracing::instrument(level = "debug", skip(self, data), err)]
     pub(crate) async fn composing_local_delta(&self, data: Bytes) -> Result<(), DocError> {
         let delta = Delta::from_bytes(&data)?;
-        let (ret, rx) = oneshot::channel::<DocResult<()>>();
+        let (ret, rx) = oneshot::channel::<DocumentResult<()>>();
         let msg = DocumentMsg::Delta {
             delta: delta.clone(),
             ret,
@@ -175,10 +175,11 @@ impl ClientEditDoc {
 
     #[cfg(feature = "flowy_test")]
     pub async fn doc_json(&self) -> DocResult<String> {
-        let (ret, rx) = oneshot::channel::<DocResult<String>>();
+        let (ret, rx) = oneshot::channel::<DocumentResult<String>>();
         let msg = DocumentMsg::Doc { ret };
         let _ = self.document.send(msg);
-        rx.await.map_err(internal_error)?
+        let s = rx.await.map_err(internal_error)??;
+        Ok(s)
     }
 
     #[tracing::instrument(level = "debug", skip(self))]
@@ -201,7 +202,7 @@ impl ClientEditDoc {
     #[tracing::instrument(level = "debug", skip(self))]
     async fn handle_push_rev(&self, bytes: Bytes) -> DocResult<()> {
         // Transform the revision
-        let (ret, rx) = oneshot::channel::<DocResult<TransformDeltas>>();
+        let (ret, rx) = oneshot::channel::<DocumentResult<TransformDeltas>>();
         let _ = self.document.send(DocumentMsg::RemoteRevision { bytes, ret });
         let TransformDeltas {
             client_prime,
@@ -215,7 +216,7 @@ impl ClientEditDoc {
         }
 
         // compose delta
-        let (ret, rx) = oneshot::channel::<DocResult<()>>();
+        let (ret, rx) = oneshot::channel::<DocumentResult<()>>();
         let msg = DocumentMsg::Delta {
             delta: client_prime.clone(),
             ret,

+ 1 - 11
rust-lib/flowy-document/src/services/doc/mod.rs

@@ -1,16 +1,6 @@
-pub use document::*;
-pub use history::*;
-pub use view::*;
-
-mod document;
-mod history;
-mod view;
-
-pub(crate) mod doc_controller;
 mod edit;
-mod extensions;
 mod revision;
 
+pub(crate) mod doc_controller;
 pub use edit::*;
-
 pub(crate) use revision::*;

+ 2 - 2
rust-lib/flowy-document/src/services/ws/ws_manager.rs

@@ -1,7 +1,7 @@
-use crate::{entities::ws::WsDocumentData, errors::DocError};
+use crate::errors::DocError;
 use bytes::Bytes;
-
 use dashmap::DashMap;
+use flowy_document_infra::entities::ws::WsDocumentData;
 use flowy_ws::WsState;
 use std::{convert::TryInto, sync::Arc};
 

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

@@ -13,6 +13,7 @@ flowy-infra = { path = "../flowy-infra" }
 flowy-workspace = { path = "../flowy-workspace", default-features = false }
 flowy-database = { path = "../flowy-database" }
 flowy-document = { path = "../flowy-document" }
+flowy-document-infra = { path = "../flowy-document-infra" }
 flowy-ws = { path = "../flowy-ws" }
 flowy-net = { path = "../flowy-net" }
 tracing = { version = "0.1" }

+ 13 - 9
rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs

@@ -1,17 +1,17 @@
 use bytes::Bytes;
+use flowy_database::ConnectionPool;
 use flowy_document::{
-    entities::ws::WsDocumentData,
     errors::{internal_error, DocError},
     module::DocumentUser,
-    services::ws::WsStateReceiver,
+    services::ws::{DocumentWebSocket, WsDocumentManager, WsStateReceiver},
+};
+use flowy_document_infra::entities::ws::WsDocumentData;
+use flowy_user::{
+    errors::{ErrorCode, UserError},
+    services::user::UserSession,
 };
-use flowy_user::{errors::ErrorCode, services::user::UserSession};
 use flowy_ws::{WsMessage, WsMessageHandler, WsModule};
-
-use flowy_database::ConnectionPool;
-use flowy_document::services::ws::{DocumentWebSocket, WsDocumentManager};
-use flowy_user::errors::UserError;
-use std::{path::Path, sync::Arc};
+use std::{convert::TryInto, path::Path, sync::Arc};
 
 pub struct DocumentDepsResolver {
     user_session: Arc<UserSession>,
@@ -75,7 +75,11 @@ struct WsSenderImpl {
 impl DocumentWebSocket for WsSenderImpl {
     fn send(&self, data: WsDocumentData) -> Result<(), DocError> {
         if cfg!(feature = "http_server") {
-            let msg: WsMessage = data.into();
+            let bytes: Bytes = data.try_into().unwrap();
+            let msg = WsMessage {
+                module: WsModule::Doc,
+                data: bytes.to_vec(),
+            };
             let sender = self.user.ws_controller.sender().map_err(internal_error)?;
             sender.send_msg(msg).map_err(internal_error)?;
         }