Browse Source

mv revision to flowy-collaborate

appflowy 3 năm trước cách đây
mục cha
commit
777082c879
53 tập tin đã thay đổi với 683 bổ sung229 xóa
  1. 0 2
      backend/Cargo.lock
  2. 8 5
      backend/src/services/core/view/controller.rs
  3. 9 2
      backend/src/services/core/view/router.rs
  4. 7 9
      backend/src/services/document/controller.rs
  5. 1 1
      backend/src/services/document/persistence/kv.rs
  6. 15 7
      backend/src/services/document/persistence/postgres.rs
  7. 13 5
      backend/src/services/document/router.rs
  8. 3 3
      backend/src/services/document/ws_actor.rs
  9. 8 4
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/doc.pb.dart
  10. 2 2
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/doc.pbjson.dart
  11. 1 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/protobuf.dart
  12. 310 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pb.dart
  13. 41 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbenum.dart
  14. 80 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbjson.dart
  15. 9 0
      frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbserver.dart
  16. 8 2
      frontend/rust-lib/flowy-document/src/services/doc/edit/editor.rs
  17. 1 1
      frontend/rust-lib/flowy-document/src/services/doc/edit/editor_cmd_queue.rs
  18. 2 4
      frontend/rust-lib/flowy-document/src/services/doc/revision/cache/cache.rs
  19. 1 1
      frontend/rust-lib/flowy-document/src/services/doc/revision/cache/disk.rs
  20. 1 2
      frontend/rust-lib/flowy-document/src/services/doc/revision/cache/memory.rs
  21. 4 2
      frontend/rust-lib/flowy-document/src/services/doc/revision/manager.rs
  22. 4 2
      frontend/rust-lib/flowy-document/src/services/doc/web_socket/http_ws_impl.rs
  23. 5 5
      frontend/rust-lib/flowy-document/src/services/doc/web_socket/web_socket.rs
  24. 1 1
      frontend/rust-lib/flowy-document/src/sql_tables/doc/rev_sql.rs
  25. 4 2
      frontend/rust-lib/flowy-document/src/sql_tables/doc/rev_table.rs
  26. 1 1
      frontend/rust-lib/flowy-net/src/services/mock/ws_mock.rs
  27. 2 2
      frontend/rust-lib/flowy-test/src/doc_script.rs
  28. 0 2
      shared-lib/Cargo.lock
  29. 2 2
      shared-lib/flowy-collaboration/src/core/sync/server_editor.rs
  30. 5 7
      shared-lib/flowy-collaboration/src/core/sync/synchronizer.rs
  31. 6 12
      shared-lib/flowy-collaboration/src/entities/doc.rs
  32. 0 5
      shared-lib/flowy-collaboration/src/entities/doc/mod.rs
  33. 2 0
      shared-lib/flowy-collaboration/src/entities/mod.rs
  34. 0 0
      shared-lib/flowy-collaboration/src/entities/parser/doc_id.rs
  35. 0 0
      shared-lib/flowy-collaboration/src/entities/parser/mod.rs
  36. 1 1
      shared-lib/flowy-collaboration/src/entities/revision.rs
  37. 4 3
      shared-lib/flowy-collaboration/src/entities/ws.rs
  38. 0 4
      shared-lib/flowy-collaboration/src/entities/ws/mod.rs
  39. 1 1
      shared-lib/flowy-collaboration/src/lib.rs
  40. 94 78
      shared-lib/flowy-collaboration/src/protobuf/model/doc.rs
  41. 3 0
      shared-lib/flowy-collaboration/src/protobuf/model/mod.rs
  42. 14 14
      shared-lib/flowy-collaboration/src/protobuf/model/revision.rs
  43. 2 1
      shared-lib/flowy-collaboration/src/protobuf/proto/doc.proto
  44. 0 0
      shared-lib/flowy-collaboration/src/protobuf/proto/revision.proto
  45. 6 6
      shared-lib/flowy-derive/src/derive_cache/derive_cache.rs
  46. 2 2
      shared-lib/lib-ot/Cargo.toml
  47. 0 3
      shared-lib/lib-ot/Flowy.toml
  48. 0 2
      shared-lib/lib-ot/src/lib.rs
  49. 0 4
      shared-lib/lib-ot/src/protobuf/document
  50. 0 4
      shared-lib/lib-ot/src/protobuf/mod.rs
  51. 0 5
      shared-lib/lib-ot/src/protobuf/model/document
  52. 0 5
      shared-lib/lib-ot/src/protobuf/model/mod.rs
  53. 0 3
      shared-lib/lib-ot/src/revision/mod.rs

+ 0 - 2
backend/Cargo.lock

@@ -2035,11 +2035,9 @@ dependencies = [
  "bytes",
  "dashmap",
  "derive_more",
- "flowy-derive",
  "lazy_static",
  "log",
  "md5",
- "protobuf",
  "serde",
  "serde_json",
  "strum",

+ 8 - 5
backend/src/services/core/view/controller.rs

@@ -2,7 +2,7 @@ use crate::{
     entities::logged_user::LoggedUser,
     services::{
         core::{trash::read_trash_ids, view::persistence::*},
-        document::persistence::{create_doc_with_transaction, delete_doc},
+        document::persistence::{create_doc_with_transaction, delete_doc, DocumentKVPersistence},
     },
     util::sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
 };
@@ -17,6 +17,7 @@ use flowy_core_data_model::{
     protobuf::{CreateViewParams, RepeatedView, View},
 };
 use sqlx::{postgres::PgArguments, Postgres};
+use std::sync::Arc;
 use uuid::Uuid;
 
 pub(crate) async fn update_view(
@@ -56,9 +57,10 @@ pub(crate) async fn delete_view(transaction: &mut DBTransaction<'_>, view_ids: V
     Ok(())
 }
 
-#[tracing::instrument(name = "create_view", level = "debug", skip(transaction), err)]
+#[tracing::instrument(name = "create_view", level = "debug", skip(transaction, kv_store), err)]
 pub(crate) async fn create_view(
     transaction: &mut DBTransaction<'_>,
+    kv_store: Arc<DocumentKVPersistence>,
     params: CreateViewParams,
 ) -> Result<View, ServerError> {
     let name = ViewName::parse(params.name).map_err(invalid_params)?;
@@ -73,12 +75,13 @@ pub(crate) async fn create_view(
         .view_type(params.view_type)
         .build()?;
 
-    let view = create_view_with_args(transaction, sql, args, view, params.data).await?;
+    let view = create_view_with_args(transaction, kv_store, sql, args, view, params.data).await?;
     Ok(view)
 }
 
-pub(crate) async fn create_view_with_args(
+async fn create_view_with_args(
     transaction: &mut DBTransaction<'_>,
+    kv_store: Arc<DocumentKVPersistence>,
     sql: String,
     args: PgArguments,
     view: View,
@@ -92,7 +95,7 @@ pub(crate) async fn create_view_with_args(
     let mut create_doc_params = CreateDocParams::new();
     create_doc_params.set_data(view_data);
     create_doc_params.set_id(view.id.clone());
-    let _ = create_doc_with_transaction(transaction, create_doc_params).await?;
+    let _ = create_doc_with_transaction(transaction, kv_store, create_doc_params).await?;
     Ok(view)
 }
 

+ 9 - 2
backend/src/services/core/view/router.rs

@@ -1,4 +1,5 @@
 use crate::{
+    context::FlowyPersistence,
     entities::logged_user::LoggedUser,
     services::core::view::{create_view, delete_view, persistence::check_view_ids, read_view, update_view},
     util::serde_ext::parse_from_payload,
@@ -17,15 +18,21 @@ use flowy_core_data_model::{
     protobuf::{CreateViewParams, QueryViewRequest, UpdateViewParams, ViewIdentifier},
 };
 use sqlx::PgPool;
+use std::sync::Arc;
 
-pub async fn create_handler(payload: Payload, pool: Data<PgPool>) -> Result<HttpResponse, ServerError> {
+pub async fn create_handler(
+    payload: Payload,
+    persistence: Data<Arc<FlowyPersistence>>,
+) -> Result<HttpResponse, ServerError> {
     let params: CreateViewParams = parse_from_payload(payload).await?;
+    let kv_store = persistence.kv_store();
+    let pool = persistence.pg_pool();
     let mut transaction = pool
         .begin()
         .await
         .context("Failed to acquire a Postgres connection to create view")?;
 
-    let view = create_view(&mut transaction, params).await?;
+    let view = create_view(&mut transaction, kv_store, params).await?;
     transaction
         .commit()
         .await

+ 7 - 9
backend/src/services/document/controller.rs

@@ -6,18 +6,16 @@ use crate::services::{
     web_socket::{WSClientData, WebSocketReceiver},
 };
 
-use backend_service::errors::ServerError;
-
 use crate::context::FlowyPersistence;
+use backend_service::errors::ServerError;
 use flowy_collaboration::{
     core::sync::{DocumentPersistence, ServerDocumentManager},
-    entities::doc::Doc,
+    entities::{doc::Doc, revision::Revision},
     errors::CollaborateError,
     protobuf::{CreateDocParams, DocIdentifier, UpdateDocParams},
 };
 use lib_infra::future::FutureResultSend;
-use lib_ot::{revision::Revision, rich_text::RichTextDelta};
-
+use lib_ot::rich_text::RichTextDelta;
 use std::{convert::TryInto, sync::Arc};
 use tokio::sync::{mpsc, oneshot};
 
@@ -90,9 +88,9 @@ impl DocumentPersistence for DocumentPersistenceImpl {
             doc_id: doc_id.to_string(),
             ..Default::default()
         };
-        let pg_pool = self.0.pg_pool();
+        let persistence = self.0.clone();
         FutureResultSend::new(async move {
-            let mut pb_doc = read_doc(&pg_pool, params)
+            let mut pb_doc = read_doc(&persistence, params)
                 .await
                 .map_err(server_error_to_collaborate_error)?;
             let doc = (&mut pb_doc)
@@ -103,7 +101,7 @@ impl DocumentPersistence for DocumentPersistenceImpl {
     }
 
     fn create_doc(&self, revision: Revision) -> FutureResultSend<Doc, CollaborateError> {
-        let pg_pool = self.0.pg_pool();
+        let persistence = self.0.clone();
         FutureResultSend::new(async move {
             let delta = RichTextDelta::from_bytes(&revision.delta_data)?;
             let doc_json = delta.to_json();
@@ -115,7 +113,7 @@ impl DocumentPersistence for DocumentPersistenceImpl {
                 cached_size: Default::default(),
             };
 
-            let _ = create_doc(&pg_pool, params)
+            let _ = create_doc(&persistence, params)
                 .await
                 .map_err(server_error_to_collaborate_error)?;
             let doc: Doc = revision.try_into()?;

+ 1 - 1
backend/src/services/document/persistence/kv.rs

@@ -1,7 +1,7 @@
 use crate::{services::kv_store::KVStore, util::serde_ext::parse_from_bytes};
 use backend_service::errors::ServerError;
 use bytes::Bytes;
-use lib_ot::protobuf::{RepeatedRevision, Revision};
+use flowy_collaboration::protobuf::{RepeatedRevision, Revision};
 use protobuf::Message;
 use std::sync::Arc;
 

+ 15 - 7
backend/src/services/document/persistence/postgres.rs

@@ -1,5 +1,6 @@
 use crate::{
-    services::kv_store::KVStore,
+    context::FlowyPersistence,
+    services::{document::persistence::DocumentKVPersistence, kv_store::KVStore},
     util::sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
 };
 use anyhow::Context;
@@ -7,15 +8,16 @@ use backend_service::errors::ServerError;
 use flowy_collaboration::protobuf::{CreateDocParams, Doc, DocIdentifier, UpdateDocParams};
 use protobuf::Message;
 use sqlx::{postgres::PgArguments, PgPool, Postgres};
+use std::sync::Arc;
 use uuid::Uuid;
 
 const DOC_TABLE: &str = "doc_table";
 
-#[tracing::instrument(level = "debug", skip(transaction), err)]
+#[tracing::instrument(level = "debug", skip(transaction, kv_store), err)]
 pub(crate) async fn create_doc_with_transaction(
     transaction: &mut DBTransaction<'_>,
+    kv_store: Arc<DocumentKVPersistence>,
     params: CreateDocParams,
-    // kv_store: Data<Arc<dyn KVStore>>,
 ) -> Result<(), ServerError> {
     let uuid = Uuid::parse_str(&params.id)?;
     let (sql, args) = SqlBuilder::create(DOC_TABLE)
@@ -24,6 +26,7 @@ pub(crate) async fn create_doc_with_transaction(
         .build()?;
 
     // TODO kv
+    // kv_store.set_revision()
     let _ = sqlx::query_with(&sql, args)
         .execute(transaction)
         .await
@@ -32,13 +35,18 @@ pub(crate) async fn create_doc_with_transaction(
     Ok(())
 }
 
-pub(crate) async fn create_doc(pool: &PgPool, params: CreateDocParams) -> Result<(), ServerError> {
+pub(crate) async fn create_doc(
+    persistence: &Arc<FlowyPersistence>,
+    params: CreateDocParams,
+) -> Result<(), ServerError> {
+    let pool = persistence.pg_pool();
+    let kv_store = persistence.kv_store();
     let mut transaction = pool
         .begin()
         .await
         .context("Failed to acquire a Postgres connection to create document")?;
 
-    let _ = create_doc_with_transaction(&mut transaction, params).await?;
+    let _ = create_doc_with_transaction(&mut transaction, kv_store, params).await?;
 
     transaction
         .commit()
@@ -48,8 +56,8 @@ pub(crate) async fn create_doc(pool: &PgPool, params: CreateDocParams) -> Result
     Ok(())
 }
 
-#[tracing::instrument(level = "debug", skip(pool), err)]
-pub(crate) async fn read_doc(pool: &PgPool, params: DocIdentifier) -> Result<Doc, ServerError> {
+#[tracing::instrument(level = "debug", skip(persistence), err)]
+pub(crate) async fn read_doc(persistence: &Arc<FlowyPersistence>, params: DocIdentifier) -> Result<Doc, ServerError> {
     let doc_id = Uuid::parse_str(&params.doc_id)?;
     let mut transaction = pool
         .begin()

+ 13 - 5
backend/src/services/document/router.rs

@@ -1,4 +1,5 @@
 use crate::{
+    context::FlowyPersistence,
     services::document::persistence::{create_doc, read_doc, update_doc},
     util::serde_ext::parse_from_payload,
 };
@@ -9,17 +10,24 @@ use actix_web::{
 use backend_service::{errors::ServerError, response::FlowyResponse};
 use flowy_collaboration::protobuf::{CreateDocParams, DocIdentifier, UpdateDocParams};
 use sqlx::PgPool;
+use std::sync::Arc;
 
-pub async fn create_handler(payload: Payload, pool: Data<PgPool>) -> Result<HttpResponse, ServerError> {
+pub async fn create_handler(
+    payload: Payload,
+    persistence: Data<Arc<FlowyPersistence>>,
+) -> Result<HttpResponse, ServerError> {
     let params: CreateDocParams = parse_from_payload(payload).await?;
-    let _ = create_doc(&pool, params).await?;
+    let _ = create_doc(persistence.get_ref(), params).await?;
     Ok(FlowyResponse::success().into())
 }
 
-#[tracing::instrument(level = "debug", skip(payload, pool), err)]
-pub async fn read_handler(payload: Payload, pool: Data<PgPool>) -> Result<HttpResponse, ServerError> {
+#[tracing::instrument(level = "debug", skip(payload, persistence), err)]
+pub async fn read_handler(
+    payload: Payload,
+    persistence: Data<Arc<FlowyPersistence>>,
+) -> Result<HttpResponse, ServerError> {
     let params: DocIdentifier = parse_from_payload(payload).await?;
-    let doc = read_doc(pool.get_ref(), params).await?;
+    let doc = read_doc(persistence.get_ref(), params).await?;
     let response = FlowyResponse::success().pb(doc)?;
     Ok(response.into())
 }

+ 3 - 3
backend/src/services/document/ws_actor.rs

@@ -11,10 +11,9 @@ use async_stream::stream;
 use backend_service::errors::{internal_error, Result, ServerError};
 use flowy_collaboration::{
     core::sync::{RevisionUser, ServerDocumentManager, SyncResponse},
-    protobuf::{DocumentWSData, DocumentWSDataType, NewDocumentUser, UpdateDocParams},
+    protobuf::{DocumentWSData, DocumentWSDataType, NewDocumentUser, Revision, UpdateDocParams},
 };
 use futures::stream::StreamExt;
-use lib_ot::protobuf::Revision;
 use sqlx::PgPool;
 use std::{convert::TryInto, sync::Arc};
 use tokio::sync::{mpsc, oneshot};
@@ -123,7 +122,8 @@ impl DocumentWebSocketActor {
     }
 
     async fn handle_revision(&self, user: Arc<ServerDocUser>, mut revision: Revision) -> Result<()> {
-        let revision: lib_ot::revision::Revision = (&mut revision).try_into().map_err(internal_error)?;
+        let revision: flowy_collaboration::entities::revision::Revision =
+            (&mut revision).try_into().map_err(internal_error)?;
         // Create the document if it doesn't exist
         let handler = match self.doc_manager.get(&revision.doc_id).await {
             None => self

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

@@ -10,17 +10,19 @@ import 'dart:core' as $core;
 import 'package:fixnum/fixnum.dart' as $fixnum;
 import 'package:protobuf/protobuf.dart' as $pb;
 
+import 'revision.pb.dart' as $0;
+
 class CreateDocParams extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CreateDocParams', createEmptyInstance: create)
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
-    ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data')
+    ..aOM<$0.RepeatedRevision>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', subBuilder: $0.RepeatedRevision.create)
     ..hasRequiredFields = false
   ;
 
   CreateDocParams._() : super();
   factory CreateDocParams({
     $core.String? id,
-    $core.String? data,
+    $0.RepeatedRevision? data,
   }) {
     final _result = create();
     if (id != null) {
@@ -62,13 +64,15 @@ class CreateDocParams extends $pb.GeneratedMessage {
   void clearId() => clearField(1);
 
   @$pb.TagNumber(2)
-  $core.String get data => $_getSZ(1);
+  $0.RepeatedRevision get data => $_getN(1);
   @$pb.TagNumber(2)
-  set data($core.String v) { $_setString(1, v); }
+  set data($0.RepeatedRevision v) { setField(2, v); }
   @$pb.TagNumber(2)
   $core.bool hasData() => $_has(1);
   @$pb.TagNumber(2)
   void clearData() => clearField(2);
+  @$pb.TagNumber(2)
+  $0.RepeatedRevision ensureData() => $_ensure(1);
 }
 
 class Doc extends $pb.GeneratedMessage {

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

@@ -13,12 +13,12 @@ const CreateDocParams$json = const {
   '1': 'CreateDocParams',
   '2': const [
     const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
-    const {'1': 'data', '3': 2, '4': 1, '5': 9, '10': 'data'},
+    const {'1': 'data', '3': 2, '4': 1, '5': 11, '6': '.RepeatedRevision', '10': 'data'},
   ],
 };
 
 /// Descriptor for `CreateDocParams`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List createDocParamsDescriptor = $convert.base64Decode('Cg9DcmVhdGVEb2NQYXJhbXMSDgoCaWQYASABKAlSAmlkEhIKBGRhdGEYAiABKAlSBGRhdGE=');
+final $typed_data.Uint8List createDocParamsDescriptor = $convert.base64Decode('Cg9DcmVhdGVEb2NQYXJhbXMSDgoCaWQYASABKAlSAmlkEiUKBGRhdGEYAiABKAsyES5SZXBlYXRlZFJldmlzaW9uUgRkYXRh');
 @$core.Deprecated('Use docDescriptor instead')
 const Doc$json = const {
   '1': 'Doc',

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

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

+ 310 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pb.dart

@@ -0,0 +1,310 @@
+///
+//  Generated code. Do not modify.
+//  source: revision.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
+
+import 'dart:core' as $core;
+
+import 'package:fixnum/fixnum.dart' as $fixnum;
+import 'package:protobuf/protobuf.dart' as $pb;
+
+import 'revision.pbenum.dart';
+
+export 'revision.pbenum.dart';
+
+class Revision extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Revision', createEmptyInstance: create)
+    ..aInt64(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'baseRevId')
+    ..aInt64(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revId')
+    ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'deltaData', $pb.PbFieldType.OY)
+    ..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'md5')
+    ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'docId')
+    ..e<RevType>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ty', $pb.PbFieldType.OE, defaultOrMaker: RevType.Local, valueOf: RevType.valueOf, enumValues: RevType.values)
+    ..aOS(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'userId')
+    ..hasRequiredFields = false
+  ;
+
+  Revision._() : super();
+  factory Revision({
+    $fixnum.Int64? baseRevId,
+    $fixnum.Int64? revId,
+    $core.List<$core.int>? deltaData,
+    $core.String? md5,
+    $core.String? docId,
+    RevType? ty,
+    $core.String? userId,
+  }) {
+    final _result = create();
+    if (baseRevId != null) {
+      _result.baseRevId = baseRevId;
+    }
+    if (revId != null) {
+      _result.revId = revId;
+    }
+    if (deltaData != null) {
+      _result.deltaData = deltaData;
+    }
+    if (md5 != null) {
+      _result.md5 = md5;
+    }
+    if (docId != null) {
+      _result.docId = docId;
+    }
+    if (ty != null) {
+      _result.ty = ty;
+    }
+    if (userId != null) {
+      _result.userId = userId;
+    }
+    return _result;
+  }
+  factory Revision.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory Revision.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  Revision clone() => Revision()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  Revision copyWith(void Function(Revision) updates) => super.copyWith((message) => updates(message as Revision)) as Revision; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static Revision create() => Revision._();
+  Revision createEmptyInstance() => create();
+  static $pb.PbList<Revision> createRepeated() => $pb.PbList<Revision>();
+  @$core.pragma('dart2js:noInline')
+  static Revision getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Revision>(create);
+  static Revision? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $fixnum.Int64 get baseRevId => $_getI64(0);
+  @$pb.TagNumber(1)
+  set baseRevId($fixnum.Int64 v) { $_setInt64(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasBaseRevId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearBaseRevId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $fixnum.Int64 get revId => $_getI64(1);
+  @$pb.TagNumber(2)
+  set revId($fixnum.Int64 v) { $_setInt64(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasRevId() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearRevId() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.List<$core.int> get deltaData => $_getN(2);
+  @$pb.TagNumber(3)
+  set deltaData($core.List<$core.int> v) { $_setBytes(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasDeltaData() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearDeltaData() => clearField(3);
+
+  @$pb.TagNumber(4)
+  $core.String get md5 => $_getSZ(3);
+  @$pb.TagNumber(4)
+  set md5($core.String v) { $_setString(3, v); }
+  @$pb.TagNumber(4)
+  $core.bool hasMd5() => $_has(3);
+  @$pb.TagNumber(4)
+  void clearMd5() => clearField(4);
+
+  @$pb.TagNumber(5)
+  $core.String get docId => $_getSZ(4);
+  @$pb.TagNumber(5)
+  set docId($core.String v) { $_setString(4, v); }
+  @$pb.TagNumber(5)
+  $core.bool hasDocId() => $_has(4);
+  @$pb.TagNumber(5)
+  void clearDocId() => clearField(5);
+
+  @$pb.TagNumber(6)
+  RevType get ty => $_getN(5);
+  @$pb.TagNumber(6)
+  set ty(RevType v) { setField(6, v); }
+  @$pb.TagNumber(6)
+  $core.bool hasTy() => $_has(5);
+  @$pb.TagNumber(6)
+  void clearTy() => clearField(6);
+
+  @$pb.TagNumber(7)
+  $core.String get userId => $_getSZ(6);
+  @$pb.TagNumber(7)
+  set userId($core.String v) { $_setString(6, v); }
+  @$pb.TagNumber(7)
+  $core.bool hasUserId() => $_has(6);
+  @$pb.TagNumber(7)
+  void clearUserId() => clearField(7);
+}
+
+class RepeatedRevision extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RepeatedRevision', createEmptyInstance: create)
+    ..pc<Revision>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Revision.create)
+    ..hasRequiredFields = false
+  ;
+
+  RepeatedRevision._() : super();
+  factory RepeatedRevision({
+    $core.Iterable<Revision>? items,
+  }) {
+    final _result = create();
+    if (items != null) {
+      _result.items.addAll(items);
+    }
+    return _result;
+  }
+  factory RepeatedRevision.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory RepeatedRevision.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  RepeatedRevision clone() => RepeatedRevision()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  RepeatedRevision copyWith(void Function(RepeatedRevision) updates) => super.copyWith((message) => updates(message as RepeatedRevision)) as RepeatedRevision; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static RepeatedRevision create() => RepeatedRevision._();
+  RepeatedRevision createEmptyInstance() => create();
+  static $pb.PbList<RepeatedRevision> createRepeated() => $pb.PbList<RepeatedRevision>();
+  @$core.pragma('dart2js:noInline')
+  static RepeatedRevision getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RepeatedRevision>(create);
+  static RepeatedRevision? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.List<Revision> get items => $_getList(0);
+}
+
+class RevId extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RevId', createEmptyInstance: create)
+    ..aInt64(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'value')
+    ..hasRequiredFields = false
+  ;
+
+  RevId._() : super();
+  factory RevId({
+    $fixnum.Int64? value,
+  }) {
+    final _result = create();
+    if (value != null) {
+      _result.value = value;
+    }
+    return _result;
+  }
+  factory RevId.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory RevId.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  RevId clone() => RevId()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  RevId copyWith(void Function(RevId) updates) => super.copyWith((message) => updates(message as RevId)) as RevId; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static RevId create() => RevId._();
+  RevId createEmptyInstance() => create();
+  static $pb.PbList<RevId> createRepeated() => $pb.PbList<RevId>();
+  @$core.pragma('dart2js:noInline')
+  static RevId getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RevId>(create);
+  static RevId? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $fixnum.Int64 get value => $_getI64(0);
+  @$pb.TagNumber(1)
+  set value($fixnum.Int64 v) { $_setInt64(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasValue() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearValue() => clearField(1);
+}
+
+class RevisionRange extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RevisionRange', createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'docId')
+    ..aInt64(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'start')
+    ..aInt64(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'end')
+    ..hasRequiredFields = false
+  ;
+
+  RevisionRange._() : super();
+  factory RevisionRange({
+    $core.String? docId,
+    $fixnum.Int64? start,
+    $fixnum.Int64? end,
+  }) {
+    final _result = create();
+    if (docId != null) {
+      _result.docId = docId;
+    }
+    if (start != null) {
+      _result.start = start;
+    }
+    if (end != null) {
+      _result.end = end;
+    }
+    return _result;
+  }
+  factory RevisionRange.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory RevisionRange.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
+  'Will be removed in next major version')
+  RevisionRange clone() => RevisionRange()..mergeFromMessage(this);
+  @$core.Deprecated(
+  'Using this can add significant overhead to your binary. '
+  'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
+  'Will be removed in next major version')
+  RevisionRange copyWith(void Function(RevisionRange) updates) => super.copyWith((message) => updates(message as RevisionRange)) as RevisionRange; // ignore: deprecated_member_use
+  $pb.BuilderInfo get info_ => _i;
+  @$core.pragma('dart2js:noInline')
+  static RevisionRange create() => RevisionRange._();
+  RevisionRange createEmptyInstance() => create();
+  static $pb.PbList<RevisionRange> createRepeated() => $pb.PbList<RevisionRange>();
+  @$core.pragma('dart2js:noInline')
+  static RevisionRange getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RevisionRange>(create);
+  static RevisionRange? _defaultInstance;
+
+  @$pb.TagNumber(1)
+  $core.String get docId => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set docId($core.String v) { $_setString(0, v); }
+  @$pb.TagNumber(1)
+  $core.bool hasDocId() => $_has(0);
+  @$pb.TagNumber(1)
+  void clearDocId() => clearField(1);
+
+  @$pb.TagNumber(2)
+  $fixnum.Int64 get start => $_getI64(1);
+  @$pb.TagNumber(2)
+  set start($fixnum.Int64 v) { $_setInt64(1, v); }
+  @$pb.TagNumber(2)
+  $core.bool hasStart() => $_has(1);
+  @$pb.TagNumber(2)
+  void clearStart() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $fixnum.Int64 get end => $_getI64(2);
+  @$pb.TagNumber(3)
+  set end($fixnum.Int64 v) { $_setInt64(2, v); }
+  @$pb.TagNumber(3)
+  $core.bool hasEnd() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearEnd() => clearField(3);
+}
+

+ 41 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbenum.dart

@@ -0,0 +1,41 @@
+///
+//  Generated code. Do not modify.
+//  source: revision.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
+
+// ignore_for_file: UNDEFINED_SHOWN_NAME
+import 'dart:core' as $core;
+import 'package:protobuf/protobuf.dart' as $pb;
+
+class RevType extends $pb.ProtobufEnum {
+  static const RevType Local = RevType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Local');
+  static const RevType Remote = RevType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Remote');
+
+  static const $core.List<RevType> values = <RevType> [
+    Local,
+    Remote,
+  ];
+
+  static final $core.Map<$core.int, RevType> _byValue = $pb.ProtobufEnum.initByValue(values);
+  static RevType? valueOf($core.int value) => _byValue[value];
+
+  const RevType._($core.int v, $core.String n) : super(v, n);
+}
+
+class RevState extends $pb.ProtobufEnum {
+  static const RevState StateLocal = RevState._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'StateLocal');
+  static const RevState Ack = RevState._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Ack');
+
+  static const $core.List<RevState> values = <RevState> [
+    StateLocal,
+    Ack,
+  ];
+
+  static final $core.Map<$core.int, RevState> _byValue = $pb.ProtobufEnum.initByValue(values);
+  static RevState? valueOf($core.int value) => _byValue[value];
+
+  const RevState._($core.int v, $core.String n) : super(v, n);
+}
+

+ 80 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbjson.dart

@@ -0,0 +1,80 @@
+///
+//  Generated code. Do not modify.
+//  source: revision.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
+
+import 'dart:core' as $core;
+import 'dart:convert' as $convert;
+import 'dart:typed_data' as $typed_data;
+@$core.Deprecated('Use revTypeDescriptor instead')
+const RevType$json = const {
+  '1': 'RevType',
+  '2': const [
+    const {'1': 'Local', '2': 0},
+    const {'1': 'Remote', '2': 1},
+  ],
+};
+
+/// Descriptor for `RevType`. Decode as a `google.protobuf.EnumDescriptorProto`.
+final $typed_data.Uint8List revTypeDescriptor = $convert.base64Decode('CgdSZXZUeXBlEgkKBUxvY2FsEAASCgoGUmVtb3RlEAE=');
+@$core.Deprecated('Use revStateDescriptor instead')
+const RevState$json = const {
+  '1': 'RevState',
+  '2': const [
+    const {'1': 'StateLocal', '2': 0},
+    const {'1': 'Ack', '2': 1},
+  ],
+};
+
+/// Descriptor for `RevState`. Decode as a `google.protobuf.EnumDescriptorProto`.
+final $typed_data.Uint8List revStateDescriptor = $convert.base64Decode('CghSZXZTdGF0ZRIOCgpTdGF0ZUxvY2FsEAASBwoDQWNrEAE=');
+@$core.Deprecated('Use revisionDescriptor instead')
+const Revision$json = const {
+  '1': 'Revision',
+  '2': const [
+    const {'1': 'base_rev_id', '3': 1, '4': 1, '5': 3, '10': 'baseRevId'},
+    const {'1': 'rev_id', '3': 2, '4': 1, '5': 3, '10': 'revId'},
+    const {'1': 'delta_data', '3': 3, '4': 1, '5': 12, '10': 'deltaData'},
+    const {'1': 'md5', '3': 4, '4': 1, '5': 9, '10': 'md5'},
+    const {'1': 'doc_id', '3': 5, '4': 1, '5': 9, '10': 'docId'},
+    const {'1': 'ty', '3': 6, '4': 1, '5': 14, '6': '.RevType', '10': 'ty'},
+    const {'1': 'user_id', '3': 7, '4': 1, '5': 9, '10': 'userId'},
+  ],
+};
+
+/// Descriptor for `Revision`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List revisionDescriptor = $convert.base64Decode('CghSZXZpc2lvbhIeCgtiYXNlX3Jldl9pZBgBIAEoA1IJYmFzZVJldklkEhUKBnJldl9pZBgCIAEoA1IFcmV2SWQSHQoKZGVsdGFfZGF0YRgDIAEoDFIJZGVsdGFEYXRhEhAKA21kNRgEIAEoCVIDbWQ1EhUKBmRvY19pZBgFIAEoCVIFZG9jSWQSGAoCdHkYBiABKA4yCC5SZXZUeXBlUgJ0eRIXCgd1c2VyX2lkGAcgASgJUgZ1c2VySWQ=');
+@$core.Deprecated('Use repeatedRevisionDescriptor instead')
+const RepeatedRevision$json = const {
+  '1': 'RepeatedRevision',
+  '2': const [
+    const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Revision', '10': 'items'},
+  ],
+};
+
+/// Descriptor for `RepeatedRevision`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List repeatedRevisionDescriptor = $convert.base64Decode('ChBSZXBlYXRlZFJldmlzaW9uEh8KBWl0ZW1zGAEgAygLMgkuUmV2aXNpb25SBWl0ZW1z');
+@$core.Deprecated('Use revIdDescriptor instead')
+const RevId$json = const {
+  '1': 'RevId',
+  '2': const [
+    const {'1': 'value', '3': 1, '4': 1, '5': 3, '10': 'value'},
+  ],
+};
+
+/// Descriptor for `RevId`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List revIdDescriptor = $convert.base64Decode('CgVSZXZJZBIUCgV2YWx1ZRgBIAEoA1IFdmFsdWU=');
+@$core.Deprecated('Use revisionRangeDescriptor instead')
+const RevisionRange$json = const {
+  '1': 'RevisionRange',
+  '2': const [
+    const {'1': 'doc_id', '3': 1, '4': 1, '5': 9, '10': 'docId'},
+    const {'1': 'start', '3': 2, '4': 1, '5': 3, '10': 'start'},
+    const {'1': 'end', '3': 3, '4': 1, '5': 3, '10': 'end'},
+  ],
+};
+
+/// Descriptor for `RevisionRange`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List revisionRangeDescriptor = $convert.base64Decode('Cg1SZXZpc2lvblJhbmdlEhUKBmRvY19pZBgBIAEoCVIFZG9jSWQSFAoFc3RhcnQYAiABKANSBXN0YXJ0EhAKA2VuZBgDIAEoA1IDZW5k');

+ 9 - 0
frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-collaboration/revision.pbserver.dart

@@ -0,0 +1,9 @@
+///
+//  Generated code. Do not modify.
+//  source: revision.proto
+//
+// @dart = 2.12
+// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
+
+export 'revision.pb.dart';
+

+ 8 - 2
frontend/rust-lib/flowy-document/src/services/doc/edit/editor.rs

@@ -7,12 +7,18 @@ use crate::{
     },
 };
 use bytes::Bytes;
-use flowy_collaboration::{core::document::history::UndoResult, entities::doc::DocDelta, errors::CollaborateResult};
+use flowy_collaboration::{
+    core::document::history::UndoResult,
+    entities::{
+        doc::DocDelta,
+        revision::{RevId, RevType, Revision},
+    },
+    errors::CollaborateResult,
+};
 use flowy_database::ConnectionPool;
 use flowy_error::{internal_error, FlowyResult};
 use lib_ot::{
     core::Interval,
-    revision::{RevId, RevType, Revision},
     rich_text::{RichTextAttribute, RichTextDelta},
 };
 use std::sync::Arc;

+ 1 - 1
frontend/rust-lib/flowy-document/src/services/doc/edit/editor_cmd_queue.rs

@@ -2,13 +2,13 @@ use async_stream::stream;
 use bytes::Bytes;
 use flowy_collaboration::{
     core::document::{history::UndoResult, Document},
+    entities::revision::{RevId, Revision},
     errors::CollaborateError,
 };
 use flowy_error::FlowyError;
 use futures::stream::StreamExt;
 use lib_ot::{
     core::{Interval, OperationTransformable},
-    revision::{RevId, Revision},
     rich_text::{RichTextAttribute, RichTextDelta},
 };
 use std::{convert::TryFrom, sync::Arc};

+ 2 - 4
frontend/rust-lib/flowy-document/src/services/doc/revision/cache/cache.rs

@@ -7,13 +7,11 @@ use crate::{
     sql_tables::{RevChangeset, RevTableState},
 };
 use dashmap::DashMap;
+use flowy_collaboration::entities::revision::{RevState, Revision, RevisionRange};
 use flowy_database::ConnectionPool;
 use flowy_error::{internal_error, FlowyResult};
 use lib_infra::future::FutureResult;
-use lib_ot::{
-    errors::OTError,
-    revision::{RevState, Revision, RevisionRange},
-};
+use lib_ot::errors::OTError;
 use std::{
     collections::VecDeque,
     sync::{

+ 1 - 1
frontend/rust-lib/flowy-document/src/services/doc/revision/cache/disk.rs

@@ -1,9 +1,9 @@
 use crate::services::doc::revision::RevisionRecord;
 
 use crate::sql_tables::{RevChangeset, RevTableSql};
+use flowy_collaboration::entities::revision::RevisionRange;
 use flowy_database::ConnectionPool;
 use flowy_error::{internal_error, FlowyError, FlowyResult};
-use lib_ot::revision::RevisionRange;
 use std::{fmt::Debug, sync::Arc};
 
 pub trait RevisionDiskCache: Sync + Send {

+ 1 - 2
frontend/rust-lib/flowy-document/src/services/doc/revision/cache/memory.rs

@@ -1,8 +1,7 @@
 use crate::services::doc::RevisionRecord;
 use dashmap::DashMap;
+use flowy_collaboration::entities::revision::RevisionRange;
 use flowy_error::{FlowyError, FlowyResult};
-
-use lib_ot::revision::RevisionRange;
 use std::{sync::Arc, time::Duration};
 use tokio::{sync::RwLock, task::JoinHandle};
 

+ 4 - 2
frontend/rust-lib/flowy-document/src/services/doc/revision/manager.rs

@@ -1,14 +1,16 @@
 use crate::{errors::FlowyError, services::doc::revision::RevisionCache};
 use bytes::Bytes;
 use flowy_collaboration::{
-    entities::doc::Doc,
+    entities::{
+        doc::Doc,
+        revision::{RevState, RevType, Revision, RevisionRange},
+    },
     util::{md5, RevIdCounter},
 };
 use flowy_error::FlowyResult;
 use lib_infra::future::FutureResult;
 use lib_ot::{
     core::{Operation, OperationTransformable},
-    revision::{RevState, RevType, Revision, RevisionRange},
     rich_text::RichTextDelta,
 };
 use std::sync::Arc;

+ 4 - 2
frontend/rust-lib/flowy-document/src/services/doc/web_socket/http_ws_impl.rs

@@ -4,11 +4,13 @@ use crate::services::{
 };
 use async_stream::stream;
 use bytes::Bytes;
-use flowy_collaboration::entities::ws::{DocumentWSData, DocumentWSDataType, NewDocumentUser};
+use flowy_collaboration::entities::{
+    revision::RevisionRange,
+    ws::{DocumentWSData, DocumentWSDataType, NewDocumentUser},
+};
 use flowy_error::{internal_error, FlowyError, FlowyResult};
 use futures::stream::StreamExt;
 use lib_infra::future::FutureResult;
-use lib_ot::revision::RevisionRange;
 use lib_ws::WSConnectState;
 use std::{convert::TryFrom, sync::Arc};
 use tokio::{

+ 5 - 5
frontend/rust-lib/flowy-document/src/services/doc/web_socket/web_socket.rs

@@ -14,15 +14,15 @@ use crate::services::doc::{
 };
 use bytes::Bytes;
 use flowy_collaboration::{
-    entities::ws::{DocumentWSData, DocumentWSDataBuilder, DocumentWSDataType, NewDocumentUser},
+    entities::{
+        revision::{Revision, RevisionRange},
+        ws::{DocumentWSData, DocumentWSDataBuilder, DocumentWSDataType, NewDocumentUser},
+    },
     errors::CollaborateResult,
 };
 use flowy_error::{internal_error, FlowyError, FlowyResult};
 use lib_infra::future::FutureResult;
-use lib_ot::{
-    revision::{Revision, RevisionRange},
-    rich_text::RichTextDelta,
-};
+use lib_ot::rich_text::RichTextDelta;
 use lib_ws::WSConnectState;
 use std::{
     collections::VecDeque,

+ 1 - 1
frontend/rust-lib/flowy-document/src/sql_tables/doc/rev_sql.rs

@@ -4,8 +4,8 @@ use crate::{
     sql_tables::{doc::RevTable, mk_revision_record_from_table, RevChangeset, RevTableState, RevTableType},
 };
 use diesel::update;
+use flowy_collaboration::entities::revision::RevisionRange;
 use flowy_database::{insert_or_ignore_into, prelude::*, schema::rev_table::dsl, SqliteConnection};
-use lib_ot::revision::RevisionRange;
 
 pub struct RevTableSql {}
 

+ 4 - 2
frontend/rust-lib/flowy-document/src/sql_tables/doc/rev_table.rs

@@ -1,8 +1,10 @@
 use crate::services::doc::revision::RevisionRecord;
 use diesel::sql_types::Integer;
-use flowy_collaboration::util::md5;
+use flowy_collaboration::{
+    entities::revision::{RevId, RevState, RevType, Revision},
+    util::md5,
+};
 use flowy_database::schema::rev_table;
-use lib_ot::revision::{RevId, RevState, RevType, Revision};
 
 #[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)]
 #[table_name = "rev_table"]

+ 1 - 1
frontend/rust-lib/flowy-net/src/services/mock/ws_mock.rs

@@ -5,10 +5,10 @@ use flowy_collaboration::{
     core::sync::{DocumentPersistence, RevisionUser, ServerDocumentManager, SyncResponse},
     entities::{
         doc::Doc,
+        revision::Revision,
         ws::{DocumentWSData, DocumentWSDataBuilder, DocumentWSDataType, NewDocumentUser},
     },
     errors::CollaborateError,
-    Revision,
     RichTextDelta,
 };
 use lazy_static::lazy_static;

+ 2 - 2
frontend/rust-lib/flowy-test/src/doc_script.rs

@@ -1,7 +1,7 @@
 use crate::{helper::ViewTest, FlowySDKTest};
-use flowy_collaboration::entities::doc::DocIdentifier;
+use flowy_collaboration::entities::{doc::DocIdentifier, revision::RevState};
 use flowy_document::services::doc::{edit::ClientDocEditor, SYNC_INTERVAL_IN_MILLIS};
-use lib_ot::{core::Interval, revision::RevState, rich_text::RichTextDelta};
+use lib_ot::{core::Interval, rich_text::RichTextDelta};
 use std::sync::Arc;
 use tokio::time::{sleep, Duration};
 

+ 0 - 2
shared-lib/Cargo.lock

@@ -1090,11 +1090,9 @@ dependencies = [
  "bytes",
  "dashmap",
  "derive_more",
- "flowy-derive",
  "lazy_static",
  "log",
  "md5",
- "protobuf",
  "serde",
  "serde_json",
  "strum",

+ 2 - 2
shared-lib/flowy-collaboration/src/core/sync/server_editor.rs

@@ -3,14 +3,14 @@ use crate::{
         document::Document,
         sync::{RevisionSynchronizer, RevisionUser},
     },
-    entities::doc::Doc,
+    entities::{doc::Doc, revision::Revision},
     errors::{internal_error, CollaborateError, CollaborateResult},
 };
 use async_stream::stream;
 use dashmap::DashMap;
 use futures::stream::StreamExt;
 use lib_infra::future::FutureResultSend;
-use lib_ot::{errors::OTError, revision::Revision, rich_text::RichTextDelta};
+use lib_ot::{errors::OTError, rich_text::RichTextDelta};
 use std::sync::{atomic::Ordering::SeqCst, Arc};
 use tokio::{
     sync::{mpsc, oneshot},

+ 5 - 7
shared-lib/flowy-collaboration/src/core/sync/synchronizer.rs

@@ -1,13 +1,11 @@
 use crate::{
     core::document::Document,
-    entities::ws::{DocumentWSData, DocumentWSDataBuilder},
-};
-use lib_ot::{
-    core::OperationTransformable,
-    errors::OTError,
-    revision::{RevType, Revision, RevisionRange},
-    rich_text::RichTextDelta,
+    entities::{
+        revision::{RevType, Revision, RevisionRange},
+        ws::{DocumentWSData, DocumentWSDataBuilder},
+    },
 };
+use lib_ot::{core::OperationTransformable, errors::OTError, rich_text::RichTextDelta};
 use parking_lot::RwLock;
 use std::{
     cmp::Ordering,

+ 6 - 12
shared-lib/flowy-collaboration/src/entities/doc/doc.rs → shared-lib/flowy-collaboration/src/entities/doc.rs

@@ -1,6 +1,9 @@
-use crate::errors::CollaborateError;
+use crate::{
+    entities::revision::{RepeatedRevision, Revision},
+    errors::CollaborateError,
+};
 use flowy_derive::ProtoBuf;
-use lib_ot::{errors::OTError, revision::Revision, rich_text::RichTextDelta};
+use lib_ot::{errors::OTError, rich_text::RichTextDelta};
 
 #[derive(ProtoBuf, Default, Debug, Clone)]
 pub struct CreateDocParams {
@@ -8,16 +11,7 @@ pub struct CreateDocParams {
     pub id: String,
 
     #[pb(index = 2)]
-    pub data: String,
-}
-
-impl CreateDocParams {
-    pub fn new(id: &str, data: String) -> Self {
-        Self {
-            id: id.to_owned(),
-            data,
-        }
-    }
+    pub data: RepeatedRevision,
 }
 
 #[derive(ProtoBuf, Default, Debug, Clone, Eq, PartialEq)]

+ 0 - 5
shared-lib/flowy-collaboration/src/entities/doc/mod.rs

@@ -1,5 +0,0 @@
-#![allow(clippy::module_inception)]
-mod doc;
-pub mod parser;
-
-pub use doc::*;

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

@@ -1,2 +1,4 @@
 pub mod doc;
+pub mod parser;
+pub mod revision;
 pub mod ws;

+ 0 - 0
shared-lib/flowy-collaboration/src/entities/doc/parser/doc_id.rs → shared-lib/flowy-collaboration/src/entities/parser/doc_id.rs


+ 0 - 0
shared-lib/flowy-collaboration/src/entities/doc/parser/mod.rs → shared-lib/flowy-collaboration/src/entities/parser/mod.rs


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

@@ -1,6 +1,6 @@
-use crate::rich_text::RichTextDelta;
 use bytes::Bytes;
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
+use lib_ot::rich_text::RichTextDelta;
 use std::{convert::TryFrom, fmt::Formatter, ops::RangeInclusive};
 
 #[derive(PartialEq, Eq, Clone, Default, ProtoBuf)]

+ 4 - 3
shared-lib/flowy-collaboration/src/entities/ws/ws.rs → shared-lib/flowy-collaboration/src/entities/ws.rs

@@ -1,8 +1,9 @@
-use crate::errors::CollaborateError;
+use crate::{
+    entities::revision::{Revision, RevisionRange},
+    errors::CollaborateError,
+};
 use bytes::Bytes;
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
-
-use lib_ot::revision::{Revision, RevisionRange};
 use std::convert::{TryFrom, TryInto};
 
 #[derive(Debug, Clone, ProtoBuf_Enum, Eq, PartialEq, Hash)]

+ 0 - 4
shared-lib/flowy-collaboration/src/entities/ws/mod.rs

@@ -1,4 +0,0 @@
-#![allow(clippy::module_inception)]
-mod ws;
-
-pub use ws::*;

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

@@ -4,4 +4,4 @@ pub mod errors;
 pub mod protobuf;
 pub mod util;
 
-pub use lib_ot::{revision::Revision, rich_text::RichTextDelta};
+pub use lib_ot::rich_text::RichTextDelta;

+ 94 - 78
shared-lib/flowy-collaboration/src/protobuf/model/doc.rs

@@ -27,7 +27,7 @@
 pub struct CreateDocParams {
     // message fields
     pub id: ::std::string::String,
-    pub data: ::std::string::String,
+    pub data: ::protobuf::SingularPtrField<super::revision::RepeatedRevision>,
     // special fields
     pub unknown_fields: ::protobuf::UnknownFields,
     pub cached_size: ::protobuf::CachedSize,
@@ -70,35 +70,47 @@ impl CreateDocParams {
         ::std::mem::replace(&mut self.id, ::std::string::String::new())
     }
 
-    // string data = 2;
+    // .RepeatedRevision data = 2;
 
 
-    pub fn get_data(&self) -> &str {
-        &self.data
+    pub fn get_data(&self) -> &super::revision::RepeatedRevision {
+        self.data.as_ref().unwrap_or_else(|| <super::revision::RepeatedRevision as ::protobuf::Message>::default_instance())
     }
     pub fn clear_data(&mut self) {
         self.data.clear();
     }
 
+    pub fn has_data(&self) -> bool {
+        self.data.is_some()
+    }
+
     // Param is passed by value, moved
-    pub fn set_data(&mut self, v: ::std::string::String) {
-        self.data = v;
+    pub fn set_data(&mut self, v: super::revision::RepeatedRevision) {
+        self.data = ::protobuf::SingularPtrField::some(v);
     }
 
     // Mutable pointer to the field.
     // If field is not initialized, it is initialized with default value first.
-    pub fn mut_data(&mut self) -> &mut ::std::string::String {
-        &mut self.data
+    pub fn mut_data(&mut self) -> &mut super::revision::RepeatedRevision {
+        if self.data.is_none() {
+            self.data.set_default();
+        }
+        self.data.as_mut().unwrap()
     }
 
     // Take field
-    pub fn take_data(&mut self) -> ::std::string::String {
-        ::std::mem::replace(&mut self.data, ::std::string::String::new())
+    pub fn take_data(&mut self) -> super::revision::RepeatedRevision {
+        self.data.take().unwrap_or_else(|| super::revision::RepeatedRevision::new())
     }
 }
 
 impl ::protobuf::Message for CreateDocParams {
     fn is_initialized(&self) -> bool {
+        for v in &self.data {
+            if !v.is_initialized() {
+                return false;
+            }
+        };
         true
     }
 
@@ -110,7 +122,7 @@ impl ::protobuf::Message for CreateDocParams {
                     ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?;
                 },
                 2 => {
-                    ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.data)?;
+                    ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.data)?;
                 },
                 _ => {
                     ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
@@ -127,8 +139,9 @@ impl ::protobuf::Message for CreateDocParams {
         if !self.id.is_empty() {
             my_size += ::protobuf::rt::string_size(1, &self.id);
         }
-        if !self.data.is_empty() {
-            my_size += ::protobuf::rt::string_size(2, &self.data);
+        if let Some(ref v) = self.data.as_ref() {
+            let len = v.compute_size();
+            my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len;
         }
         my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
         self.cached_size.set(my_size);
@@ -139,8 +152,10 @@ impl ::protobuf::Message for CreateDocParams {
         if !self.id.is_empty() {
             os.write_string(1, &self.id)?;
         }
-        if !self.data.is_empty() {
-            os.write_string(2, &self.data)?;
+        if let Some(ref v) = self.data.as_ref() {
+            os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?;
+            os.write_raw_varint32(v.get_cached_size())?;
+            v.write_to_with_cached_sizes(os)?;
         }
         os.write_unknown_fields(self.get_unknown_fields())?;
         ::std::result::Result::Ok(())
@@ -185,7 +200,7 @@ impl ::protobuf::Message for CreateDocParams {
                 |m: &CreateDocParams| { &m.id },
                 |m: &mut CreateDocParams| { &mut m.id },
             ));
-            fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
+            fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<super::revision::RepeatedRevision>>(
                 "data",
                 |m: &CreateDocParams| { &m.data },
                 |m: &mut CreateDocParams| { &mut m.data },
@@ -1328,68 +1343,69 @@ impl ::protobuf::reflect::ProtobufValue for DocIdentifier {
 }
 
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\tdoc.proto\"5\n\x0fCreateDocParams\x12\x0e\n\x02id\x18\x01\x20\x01(\t\
-    R\x02id\x12\x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"`\n\x03Doc\x12\
-    \x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04data\x18\x02\x20\x01\
-    (\tR\x04data\x12\x15\n\x06rev_id\x18\x03\x20\x01(\x03R\x05revId\x12\x1e\
-    \n\x0bbase_rev_id\x18\x04\x20\x01(\x03R\tbaseRevId\"S\n\x0fUpdateDocPara\
-    ms\x12\x15\n\x06doc_id\x18\x01\x20\x01(\tR\x05docId\x12\x12\n\x04data\
-    \x18\x02\x20\x01(\tR\x04data\x12\x15\n\x06rev_id\x18\x03\x20\x01(\x03R\
-    \x05revId\"5\n\x08DocDelta\x12\x15\n\x06doc_id\x18\x01\x20\x01(\tR\x05do\
-    cId\x12\x12\n\x04data\x18\x02\x20\x01(\tR\x04data\"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\"&\n\rDocIdentifier\x12\x15\n\x06doc_id\x18\x01\x20\x01(\tR\x05docI\
-    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\
+    \n\tdoc.proto\x1a\x0erevision.proto\"H\n\x0fCreateDocParams\x12\x0e\n\
+    \x02id\x18\x01\x20\x01(\tR\x02id\x12%\n\x04data\x18\x02\x20\x01(\x0b2\
+    \x11.RepeatedRevisionR\x04data\"`\n\x03Doc\x12\x0e\n\x02id\x18\x01\x20\
+    \x01(\tR\x02id\x12\x12\n\x04data\x18\x02\x20\x01(\tR\x04data\x12\x15\n\
+    \x06rev_id\x18\x03\x20\x01(\x03R\x05revId\x12\x1e\n\x0bbase_rev_id\x18\
+    \x04\x20\x01(\x03R\tbaseRevId\"S\n\x0fUpdateDocParams\x12\x15\n\x06doc_i\
+    d\x18\x01\x20\x01(\tR\x05docId\x12\x12\n\x04data\x18\x02\x20\x01(\tR\x04\
+    data\x12\x15\n\x06rev_id\x18\x03\x20\x01(\x03R\x05revId\"5\n\x08DocDelta\
+    \x12\x15\n\x06doc_id\x18\x01\x20\x01(\tR\x05docId\x12\x12\n\x04data\x18\
+    \x02\x20\x01(\tR\x04data\"S\n\nNewDocUser\x12\x17\n\x07user_id\x18\x01\
+    \x20\x01(\tR\x06userId\x12\x15\n\x06rev_id\x18\x02\x20\x01(\x03R\x05revI\
+    d\x12\x15\n\x06doc_id\x18\x03\x20\x01(\tR\x05docId\"&\n\rDocIdentifier\
+    \x12\x15\n\x06doc_id\x18\x01\x20\x01(\tR\x05docIdJ\xe6\x07\n\x06\x12\x04\
+    \0\0\x1d\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\t\n\x02\x03\0\x12\x03\x01\
+    \0\x18\n\n\n\x02\x04\0\x12\x04\x03\0\x06\x01\n\n\n\x03\x04\0\x01\x12\x03\
+    \x03\x08\x17\n\x0b\n\x04\x04\0\x02\0\x12\x03\x04\x04\x12\n\x0c\n\x05\x04\
+    \0\x02\0\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x04\
+    \x0b\r\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x04\x10\x11\n\x0b\n\x04\x04\0\
+    \x02\x01\x12\x03\x05\x04\x1e\n\x0c\n\x05\x04\0\x02\x01\x06\x12\x03\x05\
+    \x04\x14\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x05\x15\x19\n\x0c\n\x05\
+    \x04\0\x02\x01\x03\x12\x03\x05\x1c\x1d\n\n\n\x02\x04\x01\x12\x04\x07\0\
+    \x0c\x01\n\n\n\x03\x04\x01\x01\x12\x03\x07\x08\x0b\n\x0b\n\x04\x04\x01\
+    \x02\0\x12\x03\x08\x04\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x08\x04\
+    \n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x08\x0b\r\n\x0c\n\x05\x04\x01\
+    \x02\0\x03\x12\x03\x08\x10\x11\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\t\x04\
+    \x14\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\t\x04\n\n\x0c\n\x05\x04\x01\
+    \x02\x01\x01\x12\x03\t\x0b\x0f\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x03\t\
+    \x12\x13\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\n\x04\x15\n\x0c\n\x05\x04\
+    \x01\x02\x02\x05\x12\x03\n\x04\t\n\x0c\n\x05\x04\x01\x02\x02\x01\x12\x03\
+    \n\n\x10\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\n\x13\x14\n\x0b\n\x04\
+    \x04\x01\x02\x03\x12\x03\x0b\x04\x1a\n\x0c\n\x05\x04\x01\x02\x03\x05\x12\
+    \x03\x0b\x04\t\n\x0c\n\x05\x04\x01\x02\x03\x01\x12\x03\x0b\n\x15\n\x0c\n\
+    \x05\x04\x01\x02\x03\x03\x12\x03\x0b\x18\x19\n\n\n\x02\x04\x02\x12\x04\r\
+    \0\x11\x01\n\n\n\x03\x04\x02\x01\x12\x03\r\x08\x17\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\n\n\x0c\n\x05\
+    \x04\x02\x02\x01\x01\x12\x03\x0f\x0b\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\x15\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\x10\n\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x10\
+    \x13\x14\n\n\n\x02\x04\x03\x12\x04\x12\0\x15\x01\n\n\n\x03\x04\x03\x01\
+    \x12\x03\x12\x08\x10\n\x0b\n\x04\x04\x03\x02\0\x12\x03\x13\x04\x16\n\x0c\
+    \n\x05\x04\x03\x02\0\x05\x12\x03\x13\x04\n\n\x0c\n\x05\x04\x03\x02\0\x01\
+    \x12\x03\x13\x0b\x11\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x13\x14\x15\n\
+    \x0b\n\x04\x04\x03\x02\x01\x12\x03\x14\x04\x14\n\x0c\n\x05\x04\x03\x02\
+    \x01\x05\x12\x03\x14\x04\n\n\x0c\n\x05\x04\x03\x02\x01\x01\x12\x03\x14\
+    \x0b\x0f\n\x0c\n\x05\x04\x03\x02\x01\x03\x12\x03\x14\x12\x13\n\n\n\x02\
+    \x04\x04\x12\x04\x16\0\x1a\x01\n\n\n\x03\x04\x04\x01\x12\x03\x16\x08\x12\
+    \n\x0b\n\x04\x04\x04\x02\0\x12\x03\x17\x04\x17\n\x0c\n\x05\x04\x04\x02\0\
+    \x05\x12\x03\x17\x04\n\n\x0c\n\x05\x04\x04\x02\0\x01\x12\x03\x17\x0b\x12\
+    \n\x0c\n\x05\x04\x04\x02\0\x03\x12\x03\x17\x15\x16\n\x0b\n\x04\x04\x04\
+    \x02\x01\x12\x03\x18\x04\x15\n\x0c\n\x05\x04\x04\x02\x01\x05\x12\x03\x18\
+    \x04\t\n\x0c\n\x05\x04\x04\x02\x01\x01\x12\x03\x18\n\x10\n\x0c\n\x05\x04\
+    \x04\x02\x01\x03\x12\x03\x18\x13\x14\n\x0b\n\x04\x04\x04\x02\x02\x12\x03\
+    \x19\x04\x16\n\x0c\n\x05\x04\x04\x02\x02\x05\x12\x03\x19\x04\n\n\x0c\n\
+    \x05\x04\x04\x02\x02\x01\x12\x03\x19\x0b\x11\n\x0c\n\x05\x04\x04\x02\x02\
+    \x03\x12\x03\x19\x14\x15\n\n\n\x02\x04\x05\x12\x04\x1b\0\x1d\x01\n\n\n\
+    \x03\x04\x05\x01\x12\x03\x1b\x08\x15\n\x0b\n\x04\x04\x05\x02\0\x12\x03\
+    \x1c\x04\x16\n\x0c\n\x05\x04\x05\x02\0\x05\x12\x03\x1c\x04\n\n\x0c\n\x05\
+    \x04\x05\x02\0\x01\x12\x03\x1c\x0b\x11\n\x0c\n\x05\x04\x05\x02\0\x03\x12\
+    \x03\x1c\x14\x15b\x06proto3\
 ";
 
 static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

+ 3 - 0
shared-lib/flowy-collaboration/src/protobuf/model/mod.rs

@@ -4,5 +4,8 @@
 mod ws;
 pub use ws::*;
 
+mod revision;
+pub use revision::*;
+
 mod doc;
 pub use doc::*;

+ 14 - 14
shared-lib/lib-ot/src/protobuf/model/model.rs → shared-lib/flowy-collaboration/src/protobuf/model/revision.rs

@@ -17,7 +17,7 @@
 #![allow(trivial_casts)]
 #![allow(unused_imports)]
 #![allow(unused_results)]
-//! Generated file from `model.proto`
+//! Generated file from `revision.proto`
 
 /// Generated files are compatible only with the same version
 /// of protobuf runtime.
@@ -1057,19 +1057,19 @@ impl ::protobuf::reflect::ProtobufValue for RevState {
 }
 
 static file_descriptor_proto_data: &'static [u8] = b"\
-    \n\x0bmodel.proto\"\xbc\x01\n\x08Revision\x12\x1e\n\x0bbase_rev_id\x18\
-    \x01\x20\x01(\x03R\tbaseRevId\x12\x15\n\x06rev_id\x18\x02\x20\x01(\x03R\
-    \x05revId\x12\x1d\n\ndelta_data\x18\x03\x20\x01(\x0cR\tdeltaData\x12\x10\
-    \n\x03md5\x18\x04\x20\x01(\tR\x03md5\x12\x15\n\x06doc_id\x18\x05\x20\x01\
-    (\tR\x05docId\x12\x18\n\x02ty\x18\x06\x20\x01(\x0e2\x08.RevTypeR\x02ty\
-    \x12\x17\n\x07user_id\x18\x07\x20\x01(\tR\x06userId\"3\n\x10RepeatedRevi\
-    sion\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\t.RevisionR\x05items\"\x1d\
-    \n\x05RevId\x12\x14\n\x05value\x18\x01\x20\x01(\x03R\x05value\"N\n\rRevi\
-    sionRange\x12\x15\n\x06doc_id\x18\x01\x20\x01(\tR\x05docId\x12\x14\n\x05\
-    start\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\x01*#\n\x08RevState\x12\x0e\n\nStateLocal\x10\0\x12\x07\n\x03Ack\
-    \x10\x01J\xe8\x07\n\x06\x12\x04\0\0\x1d\x01\n\x08\n\x01\x0c\x12\x03\0\0\
+    \n\x0erevision.proto\"\xbc\x01\n\x08Revision\x12\x1e\n\x0bbase_rev_id\
+    \x18\x01\x20\x01(\x03R\tbaseRevId\x12\x15\n\x06rev_id\x18\x02\x20\x01(\
+    \x03R\x05revId\x12\x1d\n\ndelta_data\x18\x03\x20\x01(\x0cR\tdeltaData\
+    \x12\x10\n\x03md5\x18\x04\x20\x01(\tR\x03md5\x12\x15\n\x06doc_id\x18\x05\
+    \x20\x01(\tR\x05docId\x12\x18\n\x02ty\x18\x06\x20\x01(\x0e2\x08.RevTypeR\
+    \x02ty\x12\x17\n\x07user_id\x18\x07\x20\x01(\tR\x06userId\"3\n\x10Repeat\
+    edRevision\x12\x1f\n\x05items\x18\x01\x20\x03(\x0b2\t.RevisionR\x05items\
+    \"\x1d\n\x05RevId\x12\x14\n\x05value\x18\x01\x20\x01(\x03R\x05value\"N\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\x06Re\
+    mote\x10\x01*#\n\x08RevState\x12\x0e\n\nStateLocal\x10\0\x12\x07\n\x03Ac\
+    k\x10\x01J\xe8\x07\n\x06\x12\x04\0\0\x1d\x01\n\x08\n\x01\x0c\x12\x03\0\0\
     \x12\n\n\n\x02\x04\0\x12\x04\x02\0\n\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\x1a\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\

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

@@ -1,8 +1,9 @@
 syntax = "proto3";
+import "revision.proto";
 
 message CreateDocParams {
     string id = 1;
-    string data = 2;
+    RepeatedRevision data = 2;
 }
 message Doc {
     string id = 1;

+ 0 - 0
shared-lib/lib-ot/src/protobuf/proto/model.proto → shared-lib/flowy-collaboration/src/protobuf/proto/revision.proto


+ 6 - 6
shared-lib/flowy-derive/src/derive_cache/derive_cache.rs

@@ -37,6 +37,10 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
         | "DocDelta"
         | "NewDocUser"
         | "DocIdentifier"
+        | "Revision"
+        | "RepeatedRevision"
+        | "RevId"
+        | "RevisionRange"
         | "DocumentWSData"
         | "NewDocumentUser"
         | "QueryAppRequest"
@@ -74,10 +78,6 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
         | "ExportData"
         | "WSError"
         | "WSMessage"
-        | "Revision"
-        | "RepeatedRevision"
-        | "RevId"
-        | "RevisionRange"
         => TypeCategory::Protobuf,
         "WorkspaceEvent"
         | "WorkspaceNotification"
@@ -87,14 +87,14 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
         | "NetworkType"
         | "UserEvent"
         | "UserNotification"
+        | "RevType"
+        | "RevState"
         | "DocumentWSDataType"
         | "TrashType"
         | "ViewType"
         | "ExportType"
         | "ErrorCode"
         | "WSModule"
-        | "RevType"
-        | "RevState"
         => TypeCategory::Enum,
 
         "Option" => TypeCategory::Opt,

+ 2 - 2
shared-lib/lib-ot/Cargo.toml

@@ -8,8 +8,8 @@ edition = "2018"
 [dependencies]
 bytecount = "0.6.0"
 serde = { version = "1.0", features = ["derive"] }
-protobuf = {version = "2.18.0"}
-flowy-derive = { path = "../flowy-derive" }
+#protobuf = {version = "2.18.0"}
+#flowy-derive = { path = "../flowy-derive" }
 tokio = {version = "1", features = ["sync"]}
 dashmap = "4.0"
 md5 = "0.7.0"

+ 0 - 3
shared-lib/lib-ot/Flowy.toml

@@ -1,3 +0,0 @@
-
-proto_crates = ["src/revision/model.rs"]
-event_files = []

+ 0 - 2
shared-lib/lib-ot/src/lib.rs

@@ -1,5 +1,3 @@
 pub mod core;
 pub mod errors;
-pub mod protobuf;
-pub mod revision;
 pub mod rich_text;

+ 0 - 4
shared-lib/lib-ot/src/protobuf/document

@@ -1,4 +0,0 @@
-#![cfg_attr(rustfmt, rustfmt::skip)]
-// Auto-generated, do not edit
-mod model;
-pub use model::*;

+ 0 - 4
shared-lib/lib-ot/src/protobuf/mod.rs

@@ -1,4 +0,0 @@
-#![cfg_attr(rustfmt, rustfmt::skip)]
-// Auto-generated, do not edit
-mod model;
-pub use model::*;

+ 0 - 5
shared-lib/lib-ot/src/protobuf/model/document

@@ -1,5 +0,0 @@
-#![cfg_attr(rustfmt, rustfmt::skip)]
-// Auto-generated, do not edit
-
-mod model;
-pub use model::*;

+ 0 - 5
shared-lib/lib-ot/src/protobuf/model/mod.rs

@@ -1,5 +0,0 @@
-#![cfg_attr(rustfmt, rustfmt::skip)]
-// Auto-generated, do not edit
-
-mod model;
-pub use model::*;

+ 0 - 3
shared-lib/lib-ot/src/revision/mod.rs

@@ -1,3 +0,0 @@
-mod model;
-
-pub use model::*;