Jelajahi Sumber

Refactor/crate directory (#1621)

* chore: fix wanrings

* chore: remove protobuf ref in flowy-error-code

* chore: remove protobuf ref in lib-ws

* refactor: remove protobuf trait in flowy http model

* refactor: remove flowy-error-code crate

Co-authored-by: nathan <[email protected]>
Nathan.fooo 2 tahun lalu
induk
melakukan
aa5f052ecf
100 mengubah file dengan 353 tambahan dan 334 penghapusan
  1. 0 1
      frontend/Makefile.toml
  2. 1 1
      frontend/app_flowy/lib/plugins/grid/application/cell/date_cal_bloc.dart
  3. 28 10
      frontend/app_flowy/lib/user/application/sign_in_bloc.dart
  4. 21 9
      frontend/app_flowy/lib/user/application/sign_up_bloc.dart
  5. 1 1
      frontend/app_flowy/lib/user/application/user_listener.dart
  6. 1 1
      frontend/app_flowy/lib/user/presentation/splash_screen.dart
  7. 1 1
      frontend/app_flowy/lib/workspace/application/home/home_bloc.dart
  8. 32 18
      frontend/rust-lib/Cargo.lock
  9. 4 0
      frontend/rust-lib/Cargo.toml
  10. 2 2
      frontend/rust-lib/dart-ffi/Cargo.toml
  11. 2 2
      frontend/rust-lib/dart-notify/Cargo.toml
  12. 0 0
      frontend/rust-lib/flowy-ast/Cargo.toml
  13. 0 0
      frontend/rust-lib/flowy-ast/src/ast.rs
  14. 0 0
      frontend/rust-lib/flowy-ast/src/ctxt.rs
  15. 0 0
      frontend/rust-lib/flowy-ast/src/event_attrs.rs
  16. 0 0
      frontend/rust-lib/flowy-ast/src/lib.rs
  17. 0 0
      frontend/rust-lib/flowy-ast/src/node_attrs.rs
  18. 0 0
      frontend/rust-lib/flowy-ast/src/pb_attrs.rs
  19. 0 0
      frontend/rust-lib/flowy-ast/src/symbol.rs
  20. 0 0
      frontend/rust-lib/flowy-ast/src/ty_ext.rs
  21. 0 0
      frontend/rust-lib/flowy-codegen/Cargo.toml
  22. 0 0
      frontend/rust-lib/flowy-codegen/src/dart_event/ast.rs
  23. 0 0
      frontend/rust-lib/flowy-codegen/src/dart_event/dart_event.rs
  24. 0 0
      frontend/rust-lib/flowy-codegen/src/dart_event/event_template.rs
  25. 0 0
      frontend/rust-lib/flowy-codegen/src/dart_event/event_template.tera
  26. 0 0
      frontend/rust-lib/flowy-codegen/src/dart_event/mod.rs
  27. 0 0
      frontend/rust-lib/flowy-codegen/src/flowy_toml.rs
  28. 0 0
      frontend/rust-lib/flowy-codegen/src/lib.rs
  29. 0 0
      frontend/rust-lib/flowy-codegen/src/protobuf_file/ast.rs
  30. 0 0
      frontend/rust-lib/flowy-codegen/src/protobuf_file/mod.rs
  31. 0 0
      frontend/rust-lib/flowy-codegen/src/protobuf_file/proto_gen.rs
  32. 0 0
      frontend/rust-lib/flowy-codegen/src/protobuf_file/proto_info.rs
  33. 0 0
      frontend/rust-lib/flowy-codegen/src/protobuf_file/template/derive_meta/derive_meta.rs
  34. 0 0
      frontend/rust-lib/flowy-codegen/src/protobuf_file/template/derive_meta/derive_meta.tera
  35. 0 0
      frontend/rust-lib/flowy-codegen/src/protobuf_file/template/derive_meta/mod.rs
  36. 0 0
      frontend/rust-lib/flowy-codegen/src/protobuf_file/template/mod.rs
  37. 0 0
      frontend/rust-lib/flowy-codegen/src/protobuf_file/template/proto_file/enum.tera
  38. 0 0
      frontend/rust-lib/flowy-codegen/src/protobuf_file/template/proto_file/enum_template.rs
  39. 0 0
      frontend/rust-lib/flowy-codegen/src/protobuf_file/template/proto_file/mod.rs
  40. 0 0
      frontend/rust-lib/flowy-codegen/src/protobuf_file/template/proto_file/struct.tera
  41. 0 0
      frontend/rust-lib/flowy-codegen/src/protobuf_file/template/proto_file/struct_template.rs
  42. 0 0
      frontend/rust-lib/flowy-codegen/src/util.rs
  43. 0 0
      frontend/rust-lib/flowy-derive/.gitignore
  44. 1 1
      frontend/rust-lib/flowy-derive/Cargo.toml
  45. 0 0
      frontend/rust-lib/flowy-derive/src/dart_event/mod.rs
  46. 0 0
      frontend/rust-lib/flowy-derive/src/lib.rs
  47. 0 0
      frontend/rust-lib/flowy-derive/src/node/mod.rs
  48. 0 0
      frontend/rust-lib/flowy-derive/src/proto_buf/deserialize.rs
  49. 0 0
      frontend/rust-lib/flowy-derive/src/proto_buf/enum_serde.rs
  50. 0 0
      frontend/rust-lib/flowy-derive/src/proto_buf/mod.rs
  51. 0 0
      frontend/rust-lib/flowy-derive/src/proto_buf/serialize.rs
  52. 0 0
      frontend/rust-lib/flowy-derive/src/proto_buf/util.rs
  53. 0 0
      frontend/rust-lib/flowy-derive/tests/progress.rs
  54. 3 3
      frontend/rust-lib/flowy-document/Cargo.toml
  55. 2 3
      frontend/rust-lib/flowy-document/src/editor/queue.rs
  56. 2 2
      frontend/rust-lib/flowy-document/src/lib.rs
  57. 11 5
      frontend/rust-lib/flowy-document/src/manager.rs
  58. 3 3
      frontend/rust-lib/flowy-document/src/old_editor/editor.rs
  59. 2 3
      frontend/rust-lib/flowy-document/src/old_editor/queue.rs
  60. 6 8
      frontend/rust-lib/flowy-document/src/old_editor/web_socket.rs
  61. 1 1
      frontend/rust-lib/flowy-document/src/services/persistence/rev_sqlite/document_rev_sqlite_v0.rs
  62. 1 1
      frontend/rust-lib/flowy-document/src/services/persistence/rev_sqlite/document_rev_sqlite_v1.rs
  63. 4 5
      frontend/rust-lib/flowy-error/Cargo.toml
  64. 1 1
      frontend/rust-lib/flowy-error/Flowy.toml
  65. 75 64
      frontend/rust-lib/flowy-error/src/code.rs
  66. 4 4
      frontend/rust-lib/flowy-error/src/errors.rs
  67. 2 3
      frontend/rust-lib/flowy-error/src/ext/http_server.rs
  68. 2 1
      frontend/rust-lib/flowy-error/src/lib.rs
  69. 4 4
      frontend/rust-lib/flowy-folder/Cargo.toml
  70. 3 2
      frontend/rust-lib/flowy-folder/src/manager.rs
  71. 1 1
      frontend/rust-lib/flowy-folder/src/services/persistence/rev_sqlite/folder_rev_sqlite.rs
  72. 2 2
      frontend/rust-lib/flowy-folder/src/services/view/controller.rs
  73. 5 5
      frontend/rust-lib/flowy-folder/src/services/web_socket.rs
  74. 0 13
      frontend/rust-lib/flowy-folder/tests/workspace/script.rs
  75. 3 5
      frontend/rust-lib/flowy-grid/Cargo.toml
  76. 2 2
      frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option/select_type_option.rs
  77. 1 1
      frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option/text_tests.rs
  78. 1 1
      frontend/rust-lib/flowy-grid/src/services/persistence/rev_sqlite/grid_block_sqlite_impl.rs
  79. 1 1
      frontend/rust-lib/flowy-grid/src/services/persistence/rev_sqlite/grid_sqlite_impl.rs
  80. 1 1
      frontend/rust-lib/flowy-grid/src/services/persistence/rev_sqlite/grid_view_sqlite_impl.rs
  81. 3 3
      frontend/rust-lib/flowy-net/Cargo.toml
  82. 8 8
      frontend/rust-lib/flowy-net/src/http_server/document.rs
  83. 29 50
      frontend/rust-lib/flowy-net/src/local_server/persistence.rs
  84. 8 24
      frontend/rust-lib/flowy-net/src/local_server/server.rs
  85. 27 1
      frontend/rust-lib/flowy-net/src/request.rs
  86. 2 2
      frontend/rust-lib/flowy-revision/src/cache/disk.rs
  87. 9 14
      frontend/rust-lib/flowy-revision/src/conflict_resolve.rs
  88. 24 34
      frontend/rust-lib/flowy-revision/src/ws_manager.rs
  89. 1 1
      frontend/rust-lib/flowy-revision/tests/revision_test/script.rs
  90. 5 5
      frontend/rust-lib/flowy-sync/Cargo.toml
  91. 0 0
      frontend/rust-lib/flowy-sync/src/client_document/document_pad.rs
  92. 0 0
      frontend/rust-lib/flowy-sync/src/client_document/extensions/delete/default_delete.rs
  93. 0 0
      frontend/rust-lib/flowy-sync/src/client_document/extensions/delete/mod.rs
  94. 0 0
      frontend/rust-lib/flowy-sync/src/client_document/extensions/delete/preserve_line_format_merge.rs
  95. 0 0
      frontend/rust-lib/flowy-sync/src/client_document/extensions/format/format_at_position.rs
  96. 0 0
      frontend/rust-lib/flowy-sync/src/client_document/extensions/format/mod.rs
  97. 0 0
      frontend/rust-lib/flowy-sync/src/client_document/extensions/format/resolve_block_format.rs
  98. 0 0
      frontend/rust-lib/flowy-sync/src/client_document/extensions/format/resolve_inline_format.rs
  99. 0 0
      frontend/rust-lib/flowy-sync/src/client_document/extensions/helper.rs
  100. 0 0
      frontend/rust-lib/flowy-sync/src/client_document/extensions/insert/auto_exit_block.rs

+ 0 - 1
frontend/Makefile.toml

@@ -43,7 +43,6 @@ CRATE_TYPE = "staticlib"
 LIB_EXT = "a"
 APP_ENVIRONMENT = "local"
 FLUTTER_FLOWY_SDK_PATH = "app_flowy/packages/flowy_sdk"
-PROTOBUF_DERIVE_CACHE = "../shared-lib/flowy-derive/src/derive_cache/derive_cache.rs"
 # Test default config
 TEST_CRATE_TYPE = "cdylib"
 TEST_LIB_EXT = "dylib"

+ 1 - 1
frontend/app_flowy/lib/plugins/grid/application/cell/date_cal_bloc.dart

@@ -3,7 +3,7 @@ import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
 import 'package:easy_localization/easy_localization.dart'
     show StringTranslateExtension;
 import 'package:flowy_sdk/log.dart';
-import 'package:flowy_sdk/protobuf/flowy-error-code/code.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/code.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';

+ 28 - 10
frontend/app_flowy/lib/user/application/sign_in_bloc.dart

@@ -1,6 +1,6 @@
 import 'package:app_flowy/user/application/auth_service.dart';
 import 'package:dartz/dartz.dart';
-import 'package:flowy_sdk/protobuf/flowy-error-code/code.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/code.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart' show UserProfilePB;
 import 'package:freezed_annotation/freezed_annotation.dart';
@@ -20,24 +20,34 @@ class SignInBloc extends Bloc<SignInEvent, SignInState> {
           );
         },
         emailChanged: (EmailChanged value) async {
-          emit(state.copyWith(email: value.email, emailError: none(), successOrFail: none()));
+          emit(state.copyWith(
+              email: value.email, emailError: none(), successOrFail: none()));
         },
         passwordChanged: (PasswordChanged value) async {
-          emit(state.copyWith(password: value.password, passwordError: none(), successOrFail: none()));
+          emit(state.copyWith(
+              password: value.password,
+              passwordError: none(),
+              successOrFail: none()));
         },
       );
     });
   }
 
-  Future<void> _performActionOnSignIn(SignInState state, Emitter<SignInState> emit) async {
-    emit(state.copyWith(isSubmitting: true, emailError: none(), passwordError: none(), successOrFail: none()));
+  Future<void> _performActionOnSignIn(
+      SignInState state, Emitter<SignInState> emit) async {
+    emit(state.copyWith(
+        isSubmitting: true,
+        emailError: none(),
+        passwordError: none(),
+        successOrFail: none()));
 
     final result = await authService.signIn(
       email: state.email,
       password: state.password,
     );
     emit(result.fold(
-      (userProfile) => state.copyWith(isSubmitting: false, successOrFail: some(left(userProfile))),
+      (userProfile) => state.copyWith(
+          isSubmitting: false, successOrFail: some(left(userProfile))),
       (error) => stateFromCode(error),
     ));
   }
@@ -45,18 +55,26 @@ class SignInBloc extends Bloc<SignInEvent, SignInState> {
   SignInState stateFromCode(FlowyError error) {
     switch (ErrorCode.valueOf(error.code)!) {
       case ErrorCode.EmailFormatInvalid:
-        return state.copyWith(isSubmitting: false, emailError: some(error.msg), passwordError: none());
+        return state.copyWith(
+            isSubmitting: false,
+            emailError: some(error.msg),
+            passwordError: none());
       case ErrorCode.PasswordFormatInvalid:
-        return state.copyWith(isSubmitting: false, passwordError: some(error.msg), emailError: none());
+        return state.copyWith(
+            isSubmitting: false,
+            passwordError: some(error.msg),
+            emailError: none());
       default:
-        return state.copyWith(isSubmitting: false, successOrFail: some(right(error)));
+        return state.copyWith(
+            isSubmitting: false, successOrFail: some(right(error)));
     }
   }
 }
 
 @freezed
 class SignInEvent with _$SignInEvent {
-  const factory SignInEvent.signedInWithUserEmailAndPassword() = SignedInWithUserEmailAndPassword;
+  const factory SignInEvent.signedInWithUserEmailAndPassword() =
+      SignedInWithUserEmailAndPassword;
   const factory SignInEvent.emailChanged(String email) = EmailChanged;
   const factory SignInEvent.passwordChanged(String password) = PasswordChanged;
 }

+ 21 - 9
frontend/app_flowy/lib/user/application/sign_up_bloc.dart

@@ -1,7 +1,7 @@
 import 'package:app_flowy/user/application/auth_service.dart';
 import 'package:dartz/dartz.dart';
 import 'package:easy_localization/easy_localization.dart';
-import 'package:flowy_sdk/protobuf/flowy-error-code/code.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/code.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart' show UserProfilePB;
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
@@ -17,11 +17,18 @@ class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
       await event.map(signUpWithUserEmailAndPassword: (e) async {
         await _performActionOnSignUp(emit);
       }, emailChanged: (_EmailChanged value) async {
-        emit(state.copyWith(email: value.email, emailError: none(), successOrFail: none()));
+        emit(state.copyWith(
+            email: value.email, emailError: none(), successOrFail: none()));
       }, passwordChanged: (_PasswordChanged value) async {
-        emit(state.copyWith(password: value.password, passwordError: none(), successOrFail: none()));
+        emit(state.copyWith(
+            password: value.password,
+            passwordError: none(),
+            successOrFail: none()));
       }, repeatPasswordChanged: (_RepeatPasswordChanged value) async {
-        emit(state.copyWith(repeatedPassword: value.password, repeatPasswordError: none(), successOrFail: none()));
+        emit(state.copyWith(
+            repeatedPassword: value.password,
+            repeatPasswordError: none(),
+            successOrFail: none()));
       });
     });
   }
@@ -45,7 +52,8 @@ class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
     if (repeatedPassword == null) {
       emit(state.copyWith(
         isSubmitting: false,
-        repeatPasswordError: some(LocaleKeys.signUp_repeatPasswordEmptyError.tr()),
+        repeatPasswordError:
+            some(LocaleKeys.signUp_repeatPasswordEmptyError.tr()),
       ));
       return;
     }
@@ -53,7 +61,8 @@ class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
     if (password != repeatedPassword) {
       emit(state.copyWith(
         isSubmitting: false,
-        repeatPasswordError: some(LocaleKeys.signUp_unmatchedPasswordError.tr()),
+        repeatPasswordError:
+            some(LocaleKeys.signUp_unmatchedPasswordError.tr()),
       ));
       return;
     }
@@ -97,17 +106,20 @@ class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
           successOrFail: none(),
         );
       default:
-        return state.copyWith(isSubmitting: false, successOrFail: some(right(error)));
+        return state.copyWith(
+            isSubmitting: false, successOrFail: some(right(error)));
     }
   }
 }
 
 @freezed
 class SignUpEvent with _$SignUpEvent {
-  const factory SignUpEvent.signUpWithUserEmailAndPassword() = SignUpWithUserEmailAndPassword;
+  const factory SignUpEvent.signUpWithUserEmailAndPassword() =
+      SignUpWithUserEmailAndPassword;
   const factory SignUpEvent.emailChanged(String email) = _EmailChanged;
   const factory SignUpEvent.passwordChanged(String password) = _PasswordChanged;
-  const factory SignUpEvent.repeatPasswordChanged(String password) = _RepeatPasswordChanged;
+  const factory SignUpEvent.repeatPasswordChanged(String password) =
+      _RepeatPasswordChanged;
 }
 
 @freezed

+ 1 - 1
frontend/app_flowy/lib/user/application/user_listener.dart

@@ -2,7 +2,7 @@ import 'dart:async';
 import 'package:app_flowy/core/folder_notification.dart';
 import 'package:app_flowy/core/user_notification.dart';
 import 'package:dartz/dartz.dart';
-import 'package:flowy_sdk/protobuf/flowy-error-code/code.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/code.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/workspace.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'dart:typed_data';

+ 1 - 1
frontend/app_flowy/lib/user/presentation/splash_screen.dart

@@ -1,6 +1,6 @@
 import 'package:flowy_sdk/dispatch/dispatch.dart';
 import 'package:flowy_sdk/log.dart';
-import 'package:flowy_sdk/protobuf/flowy-error-code/code.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/code.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 

+ 1 - 1
frontend/app_flowy/lib/workspace/application/home/home_bloc.dart

@@ -1,7 +1,7 @@
 import 'package:app_flowy/user/application/user_listener.dart';
 import 'package:flowy_infra/time/duration.dart';
 import 'package:flowy_sdk/log.dart';
-import 'package:flowy_sdk/protobuf/flowy-error-code/code.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/code.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-folder/workspace.pb.dart'

+ 32 - 18
frontend/rust-lib/Cargo.lock

@@ -872,10 +872,13 @@ dependencies = [
  "flowy-ast",
  "flowy-codegen",
  "lazy_static",
+ "log",
  "proc-macro2",
  "quote",
  "serde_json",
  "syn",
+ "tokio",
+ "trybuild",
  "walkdir",
 ]
 
@@ -927,11 +930,11 @@ dependencies = [
 name = "flowy-error"
 version = "0.1.0"
 dependencies = [
+ "anyhow",
  "bytes",
  "flowy-codegen",
  "flowy-database",
  "flowy-derive",
- "flowy-error-code",
  "flowy-sync",
  "http-flowy",
  "lib-dispatch",
@@ -940,16 +943,7 @@ dependencies = [
  "protobuf",
  "r2d2",
  "serde_json",
-]
-
-[[package]]
-name = "flowy-error-code"
-version = "0.1.0"
-dependencies = [
- "derive_more",
- "flowy-codegen",
- "flowy-derive",
- "protobuf",
+ "thiserror",
 ]
 
 [[package]]
@@ -1042,11 +1036,10 @@ name = "flowy-http-model"
 version = "0.1.0"
 dependencies = [
  "bytes",
- "flowy-codegen",
- "flowy-derive",
- "lib-infra",
  "md5",
- "protobuf",
+ "serde",
+ "serde_json",
+ "serde_repr",
 ]
 
 [[package]]
@@ -1441,6 +1434,12 @@ version = "0.26.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
 
+[[package]]
+name = "glob"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
+
 [[package]]
 name = "globset"
 version = "0.4.8"
@@ -1470,7 +1469,6 @@ name = "grid-rev-model"
 version = "0.1.0"
 dependencies = [
  "bytes",
- "flowy-error-code",
  "indexmap",
  "nanoid",
  "serde",
@@ -1855,8 +1853,6 @@ version = "0.1.0"
 dependencies = [
  "bytes",
  "dashmap",
- "flowy-codegen",
- "flowy-derive",
  "futures",
  "futures-channel",
  "futures-core",
@@ -1867,6 +1863,9 @@ dependencies = [
  "paste",
  "pin-project",
  "protobuf",
+ "serde",
+ "serde_json",
+ "serde_repr",
  "strum",
  "strum_macros",
  "tokio",
@@ -3521,6 +3520,21 @@ version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
 
+[[package]]
+name = "trybuild"
+version = "1.0.64"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7f408301c7480f9e6294eb779cfc907f54bd901a9660ef24d7f233ed5376485"
+dependencies = [
+ "glob",
+ "once_cell",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "termcolor",
+ "toml",
+]
+
 [[package]]
 name = "tungstenite"
 version = "0.14.0"

+ 4 - 0
frontend/rust-lib/Cargo.toml

@@ -16,6 +16,10 @@ members = [
   "flowy-revision",
   "flowy-grid",
   "flowy-task",
+  "flowy-sync",
+  "flowy-derive",
+  "flowy-ast",
+  "flowy-codegen",
 ]
 
 [profile.dev]

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

@@ -28,7 +28,7 @@ parking_lot = "0.12.1"
 lib-dispatch = { path = "../lib-dispatch" }
 flowy-sdk = { path = "../flowy-sdk" }
 dart-notify = { path = "../dart-notify" }
-flowy-derive = { path = "../../../shared-lib/flowy-derive" }
+flowy-derive = { path = "../flowy-derive" }
 
 [features]
 default = ["flowy-sdk/dart", "dart-notify/dart", "flutter"]
@@ -37,7 +37,7 @@ http_sync = ["flowy-sdk/http_sync", "flowy-sdk/use_bunyan"]
 openssl_vendored = ["flowy-sdk/openssl_vendored"]
 
 [build-dependencies]
-flowy-codegen= { path = "../../../shared-lib/flowy-codegen", features = [
+flowy-codegen = { path = "../flowy-codegen", features = [
     "dart",
 ]}
 

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

@@ -12,11 +12,11 @@ allo-isolate = {version = "^0.1", features = ["catch-unwind",]}
 log = "0.4.14"
 bytes = { version = "1.0" }
 
-flowy-derive = {path = "../../../shared-lib/flowy-derive" }
+flowy-derive = {path = "../flowy-derive" }
 lib-dispatch = {path = "../lib-dispatch" }
 
 [features]
 dart = ["flowy-codegen/dart"]
 
 [build-dependencies]
-flowy-codegen= { path = "../../../shared-lib/flowy-codegen"}
+flowy-codegen = { path = "../flowy-codegen"}

+ 0 - 0
shared-lib/flowy-ast/Cargo.toml → frontend/rust-lib/flowy-ast/Cargo.toml


+ 0 - 0
shared-lib/flowy-ast/src/ast.rs → frontend/rust-lib/flowy-ast/src/ast.rs


+ 0 - 0
shared-lib/flowy-ast/src/ctxt.rs → frontend/rust-lib/flowy-ast/src/ctxt.rs


+ 0 - 0
shared-lib/flowy-ast/src/event_attrs.rs → frontend/rust-lib/flowy-ast/src/event_attrs.rs


+ 0 - 0
shared-lib/flowy-ast/src/lib.rs → frontend/rust-lib/flowy-ast/src/lib.rs


+ 0 - 0
shared-lib/flowy-ast/src/node_attrs.rs → frontend/rust-lib/flowy-ast/src/node_attrs.rs


+ 0 - 0
shared-lib/flowy-ast/src/pb_attrs.rs → frontend/rust-lib/flowy-ast/src/pb_attrs.rs


+ 0 - 0
shared-lib/flowy-ast/src/symbol.rs → frontend/rust-lib/flowy-ast/src/symbol.rs


+ 0 - 0
shared-lib/flowy-ast/src/ty_ext.rs → frontend/rust-lib/flowy-ast/src/ty_ext.rs


+ 0 - 0
shared-lib/flowy-codegen/Cargo.toml → frontend/rust-lib/flowy-codegen/Cargo.toml


+ 0 - 0
shared-lib/flowy-codegen/src/dart_event/ast.rs → frontend/rust-lib/flowy-codegen/src/dart_event/ast.rs


+ 0 - 0
shared-lib/flowy-codegen/src/dart_event/dart_event.rs → frontend/rust-lib/flowy-codegen/src/dart_event/dart_event.rs


+ 0 - 0
shared-lib/flowy-codegen/src/dart_event/event_template.rs → frontend/rust-lib/flowy-codegen/src/dart_event/event_template.rs


+ 0 - 0
shared-lib/flowy-codegen/src/dart_event/event_template.tera → frontend/rust-lib/flowy-codegen/src/dart_event/event_template.tera


+ 0 - 0
shared-lib/flowy-codegen/src/dart_event/mod.rs → frontend/rust-lib/flowy-codegen/src/dart_event/mod.rs


+ 0 - 0
shared-lib/flowy-codegen/src/flowy_toml.rs → frontend/rust-lib/flowy-codegen/src/flowy_toml.rs


+ 0 - 0
shared-lib/flowy-codegen/src/lib.rs → frontend/rust-lib/flowy-codegen/src/lib.rs


+ 0 - 0
shared-lib/flowy-codegen/src/protobuf_file/ast.rs → frontend/rust-lib/flowy-codegen/src/protobuf_file/ast.rs


+ 0 - 0
shared-lib/flowy-codegen/src/protobuf_file/mod.rs → frontend/rust-lib/flowy-codegen/src/protobuf_file/mod.rs


+ 0 - 0
shared-lib/flowy-codegen/src/protobuf_file/proto_gen.rs → frontend/rust-lib/flowy-codegen/src/protobuf_file/proto_gen.rs


+ 0 - 0
shared-lib/flowy-codegen/src/protobuf_file/proto_info.rs → frontend/rust-lib/flowy-codegen/src/protobuf_file/proto_info.rs


+ 0 - 0
shared-lib/flowy-codegen/src/protobuf_file/template/derive_meta/derive_meta.rs → frontend/rust-lib/flowy-codegen/src/protobuf_file/template/derive_meta/derive_meta.rs


+ 0 - 0
shared-lib/flowy-codegen/src/protobuf_file/template/derive_meta/derive_meta.tera → frontend/rust-lib/flowy-codegen/src/protobuf_file/template/derive_meta/derive_meta.tera


+ 0 - 0
shared-lib/flowy-codegen/src/protobuf_file/template/derive_meta/mod.rs → frontend/rust-lib/flowy-codegen/src/protobuf_file/template/derive_meta/mod.rs


+ 0 - 0
shared-lib/flowy-codegen/src/protobuf_file/template/mod.rs → frontend/rust-lib/flowy-codegen/src/protobuf_file/template/mod.rs


+ 0 - 0
shared-lib/flowy-codegen/src/protobuf_file/template/proto_file/enum.tera → frontend/rust-lib/flowy-codegen/src/protobuf_file/template/proto_file/enum.tera


+ 0 - 0
shared-lib/flowy-codegen/src/protobuf_file/template/proto_file/enum_template.rs → frontend/rust-lib/flowy-codegen/src/protobuf_file/template/proto_file/enum_template.rs


+ 0 - 0
shared-lib/flowy-codegen/src/protobuf_file/template/proto_file/mod.rs → frontend/rust-lib/flowy-codegen/src/protobuf_file/template/proto_file/mod.rs


+ 0 - 0
shared-lib/flowy-codegen/src/protobuf_file/template/proto_file/struct.tera → frontend/rust-lib/flowy-codegen/src/protobuf_file/template/proto_file/struct.tera


+ 0 - 0
shared-lib/flowy-codegen/src/protobuf_file/template/proto_file/struct_template.rs → frontend/rust-lib/flowy-codegen/src/protobuf_file/template/proto_file/struct_template.rs


+ 0 - 0
shared-lib/flowy-codegen/src/util.rs → frontend/rust-lib/flowy-codegen/src/util.rs


+ 0 - 0
shared-lib/flowy-derive/.gitignore → frontend/rust-lib/flowy-derive/.gitignore


+ 1 - 1
shared-lib/flowy-derive/Cargo.toml → frontend/rust-lib/flowy-derive/Cargo.toml

@@ -20,7 +20,7 @@ proc-macro2 = "1.0"
 flowy-ast = { path = "../flowy-ast" }
 lazy_static = {version = "1.4.0"}
 dashmap = "5"
-flowy-codegen= { path = "../flowy-codegen"}
+flowy-codegen = { path = "../flowy-codegen"}
 serde_json = "1.0"
 walkdir = "2.3.1"
 

+ 0 - 0
shared-lib/flowy-derive/src/dart_event/mod.rs → frontend/rust-lib/flowy-derive/src/dart_event/mod.rs


+ 0 - 0
shared-lib/flowy-derive/src/lib.rs → frontend/rust-lib/flowy-derive/src/lib.rs


+ 0 - 0
shared-lib/flowy-derive/src/node/mod.rs → frontend/rust-lib/flowy-derive/src/node/mod.rs


+ 0 - 0
shared-lib/flowy-derive/src/proto_buf/deserialize.rs → frontend/rust-lib/flowy-derive/src/proto_buf/deserialize.rs


+ 0 - 0
shared-lib/flowy-derive/src/proto_buf/enum_serde.rs → frontend/rust-lib/flowy-derive/src/proto_buf/enum_serde.rs


+ 0 - 0
shared-lib/flowy-derive/src/proto_buf/mod.rs → frontend/rust-lib/flowy-derive/src/proto_buf/mod.rs


+ 0 - 0
shared-lib/flowy-derive/src/proto_buf/serialize.rs → frontend/rust-lib/flowy-derive/src/proto_buf/serialize.rs


+ 0 - 0
shared-lib/flowy-derive/src/proto_buf/util.rs → frontend/rust-lib/flowy-derive/src/proto_buf/util.rs


+ 0 - 0
shared-lib/flowy-derive/tests/progress.rs → frontend/rust-lib/flowy-derive/tests/progress.rs


+ 3 - 3
frontend/rust-lib/flowy-document/Cargo.toml

@@ -7,9 +7,9 @@ edition = "2018"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-flowy-sync = { path = "../../../shared-lib/flowy-sync"}
+flowy-sync = { path = "../flowy-sync"}
 flowy-http-model = { path = "../../../shared-lib/flowy-http-model"}
-flowy-derive = { path = "../../../shared-lib/flowy-derive" }
+flowy-derive = { path = "../flowy-derive" }
 lib-ot = { path = "../../../shared-lib/lib-ot" }
 lib-ws = { path = "../../../shared-lib/lib-ws" }
 lib-infra = { path = "../../../shared-lib/lib-infra" }
@@ -52,7 +52,7 @@ criterion = "0.3"
 rand = "0.8.5"
 
 [build-dependencies]
-flowy-codegen= { path = "../../../shared-lib/flowy-codegen"}
+flowy-codegen = { path = "../flowy-codegen"}
 
 
 [features]

+ 2 - 3
frontend/rust-lib/flowy-document/src/editor/queue.rs

@@ -3,7 +3,6 @@ use crate::DocumentUser;
 use async_stream::stream;
 use bytes::Bytes;
 use flowy_error::FlowyError;
-use flowy_http_model::revision::RevId;
 use flowy_revision::RevisionManager;
 use futures::stream::StreamExt;
 use lib_ot::core::Transaction;
@@ -76,10 +75,10 @@ impl DocumentQueue {
     }
 
     #[tracing::instrument(level = "trace", skip(self, transaction, md5), err)]
-    async fn save_local_operations(&self, transaction: Transaction, md5: String) -> Result<RevId, FlowyError> {
+    async fn save_local_operations(&self, transaction: Transaction, md5: String) -> Result<i64, FlowyError> {
         let bytes = Bytes::from(transaction.to_bytes()?);
         let rev_id = self.rev_manager.add_local_revision(bytes, md5).await?;
-        Ok(rev_id.into())
+        Ok(rev_id)
     }
 }
 

+ 2 - 2
frontend/rust-lib/flowy-document/src/lib.rs

@@ -16,13 +16,13 @@ pub mod errors {
 pub const TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS: u64 = 1000;
 
 use crate::errors::FlowyError;
-use flowy_http_model::document::{CreateDocumentParams, DocumentIdPB, DocumentPayloadPB, ResetDocumentParams};
+use flowy_http_model::document::{CreateDocumentParams, DocumentId, DocumentPayload, ResetDocumentParams};
 use lib_infra::future::FutureResult;
 
 pub trait DocumentCloudService: Send + Sync {
     fn create_document(&self, token: &str, params: CreateDocumentParams) -> FutureResult<(), FlowyError>;
 
-    fn fetch_document(&self, token: &str, params: DocumentIdPB) -> FutureResult<Option<DocumentPayloadPB>, FlowyError>;
+    fn fetch_document(&self, token: &str, params: DocumentId) -> FutureResult<Option<DocumentPayload>, FlowyError>;
 
     fn update_document_content(&self, token: &str, params: ResetDocumentParams) -> FutureResult<(), FlowyError>;
 }

+ 11 - 5
frontend/rust-lib/flowy-document/src/manager.rs

@@ -8,7 +8,8 @@ use bytes::Bytes;
 use flowy_database::ConnectionPool;
 use flowy_error::FlowyResult;
 use flowy_http_model::util::md5;
-use flowy_http_model::{document::DocumentIdPB, revision::Revision, ws_data::ServerRevisionWSData};
+use flowy_http_model::ws_data::ServerRevisionWSData;
+use flowy_http_model::{document::DocumentId, revision::Revision};
 use flowy_revision::{
     PhantomSnapshotPersistence, RevisionCloudService, RevisionManager, RevisionPersistence,
     RevisionPersistenceConfiguration, RevisionWebSocket,
@@ -19,7 +20,8 @@ use lib_infra::future::FutureResult;
 use lib_infra::ref_map::{RefCountHashMap, RefCountValue};
 use lib_ws::WSConnectState;
 use std::any::Any;
-use std::{convert::TryInto, sync::Arc};
+use std::convert::TryFrom;
+use std::sync::Arc;
 use tokio::sync::RwLock;
 
 pub trait DocumentUser: Send + Sync {
@@ -150,10 +152,14 @@ impl DocumentManager {
     }
 
     pub async fn receive_ws_data(&self, data: Bytes) {
-        let result: Result<ServerRevisionWSData, protobuf::ProtobufError> = data.try_into();
+        let result: Result<ServerRevisionWSData, serde_json::Error> = ServerRevisionWSData::try_from(data);
         match result {
             Ok(data) => match self.editor_map.read().await.get(&data.object_id) {
-                None => tracing::error!("Can't find any source handler for {:?}-{:?}", data.object_id, data.ty),
+                None => tracing::error!(
+                    "Can't find any source handler for {:?}-{:?}",
+                    data.object_id,
+                    data.payload
+                ),
                 Some(handler) => match handler.0.receive_ws_data(data).await {
                     Ok(_) => {}
                     Err(e) => tracing::error!("{}", e),
@@ -294,7 +300,7 @@ struct DocumentRevisionCloudService {
 impl RevisionCloudService for DocumentRevisionCloudService {
     #[tracing::instrument(level = "trace", skip(self))]
     fn fetch_object(&self, user_id: &str, object_id: &str) -> FutureResult<Vec<Revision>, FlowyError> {
-        let params: DocumentIdPB = object_id.to_string().into();
+        let params: DocumentId = object_id.to_string().into();
         let server = self.server.clone();
         let token = self.token.clone();
 

+ 3 - 3
frontend/rust-lib/flowy-document/src/old_editor/editor.rs

@@ -5,7 +5,7 @@ use crate::{errors::FlowyError, DocumentEditor, DocumentUser};
 use bytes::Bytes;
 use flowy_database::ConnectionPool;
 use flowy_error::{internal_error, FlowyResult};
-use flowy_http_model::document::DocumentPayloadPB;
+use flowy_http_model::document::DocumentPayload;
 use flowy_http_model::revision::Revision;
 use flowy_http_model::ws_data::ServerRevisionWSData;
 use flowy_revision::{
@@ -246,14 +246,14 @@ impl DeltaDocumentEditor {
 
 pub struct DeltaDocumentRevisionSerde();
 impl RevisionObjectDeserializer for DeltaDocumentRevisionSerde {
-    type Output = DocumentPayloadPB;
+    type Output = DocumentPayload;
 
     fn deserialize_revisions(object_id: &str, revisions: Vec<Revision>) -> FlowyResult<Self::Output> {
         let (base_rev_id, rev_id) = revisions.last().unwrap().pair_rev_id();
         let mut delta = make_operations_from_revisions(revisions)?;
         correct_delta(&mut delta);
 
-        Result::<DocumentPayloadPB, FlowyError>::Ok(DocumentPayloadPB {
+        Result::<DocumentPayload, FlowyError>::Ok(DocumentPayload {
             doc_id: object_id.to_owned(),
             data: delta.json_bytes().to_vec(),
             rev_id,

+ 2 - 3
frontend/rust-lib/flowy-document/src/old_editor/queue.rs

@@ -3,7 +3,6 @@ use crate::DocumentUser;
 use async_stream::stream;
 use flowy_database::ConnectionPool;
 use flowy_error::FlowyError;
-use flowy_http_model::revision::RevId;
 use flowy_revision::{RevisionMD5, RevisionManager, TransformOperations};
 use flowy_sync::{
     client_document::{history::UndoResult, ClientDocument},
@@ -176,10 +175,10 @@ impl EditDocumentQueue {
         Ok(())
     }
 
-    async fn save_local_operations(&self, operations: DeltaTextOperations, md5: String) -> Result<RevId, FlowyError> {
+    async fn save_local_operations(&self, operations: DeltaTextOperations, md5: String) -> Result<i64, FlowyError> {
         let bytes = operations.json_bytes();
         let rev_id = self.rev_manager.add_local_revision(bytes, md5).await?;
-        Ok(rev_id.into())
+        Ok(rev_id)
     }
 }
 

+ 6 - 8
frontend/rust-lib/flowy-document/src/old_editor/web_socket.rs

@@ -3,10 +3,8 @@ use crate::TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS;
 use bytes::Bytes;
 use flowy_database::ConnectionPool;
 use flowy_error::{internal_error, FlowyError, FlowyResult};
-use flowy_http_model::{
-    revision::{Revision, RevisionRange},
-    ws_data::{ClientRevisionWSData, NewDocumentUser, ServerRevisionWSDataType},
-};
+use flowy_http_model::revision::{Revision, RevisionRange};
+use flowy_http_model::ws_data::{ClientRevisionWSData, NewDocumentUser};
 use flowy_revision::*;
 use flowy_sync::errors::CollaborateResult;
 use flowy_sync::util::make_operations_from_revisions;
@@ -96,14 +94,14 @@ impl DocumentRevisionWSDataStream {
 }
 
 impl RevisionWSDataStream for DocumentRevisionWSDataStream {
-    fn receive_push_revision(&self, bytes: Bytes) -> BoxResultFuture<(), FlowyError> {
+    fn receive_push_revision(&self, revisions: Vec<Revision>) -> BoxResultFuture<(), FlowyError> {
         let resolver = self.conflict_controller.clone();
-        Box::pin(async move { resolver.receive_bytes(bytes).await })
+        Box::pin(async move { resolver.receive_revisions(revisions).await })
     }
 
-    fn receive_ack(&self, id: String, ty: ServerRevisionWSDataType) -> BoxResultFuture<(), FlowyError> {
+    fn receive_ack(&self, rev_id: i64) -> BoxResultFuture<(), FlowyError> {
         let resolver = self.conflict_controller.clone();
-        Box::pin(async move { resolver.ack_revision(id, ty).await })
+        Box::pin(async move { resolver.ack_revision(rev_id).await })
     }
 
     fn receive_new_user_connect(&self, _new_user: NewDocumentUser) -> BoxResultFuture<(), FlowyError> {

+ 1 - 1
frontend/rust-lib/flowy-document/src/services/persistence/rev_sqlite/document_rev_sqlite_v0.rs

@@ -126,7 +126,7 @@ impl DeltaRevisionSql {
     fn update(changeset: RevisionChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> {
         let state: TextRevisionState = changeset.state.clone().into();
         let filter = dsl::rev_table
-            .filter(dsl::rev_id.eq(changeset.rev_id.as_ref()))
+            .filter(dsl::rev_id.eq(changeset.rev_id))
             .filter(dsl::doc_id.eq(changeset.object_id));
         let _ = update(filter).set(dsl::state.eq(state)).execute(conn)?;
         tracing::debug!(

+ 1 - 1
frontend/rust-lib/flowy-document/src/services/persistence/rev_sqlite/document_rev_sqlite_v1.rs

@@ -126,7 +126,7 @@ impl DocumentRevisionSql {
     fn update(changeset: RevisionChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> {
         let state: DocumentRevisionState = changeset.state.clone().into();
         let filter = dsl::document_rev_table
-            .filter(dsl::rev_id.eq(changeset.rev_id.as_ref()))
+            .filter(dsl::rev_id.eq(changeset.rev_id))
             .filter(dsl::document_id.eq(changeset.object_id));
         let _ = update(filter).set(dsl::state.eq(state)).execute(conn)?;
         tracing::debug!(

+ 4 - 5
frontend/rust-lib/flowy-error/Cargo.toml

@@ -6,8 +6,7 @@ edition = "2018"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-flowy-derive = { path = "../../../shared-lib/flowy-derive" }
-flowy-error-code = { path = "../../../shared-lib/flowy-error-code"}
+flowy-derive = { path = "../flowy-derive" }
 lib-dispatch = { path = "../lib-dispatch" }
 protobuf = {version = "2.20.0"}
 bytes = "1.0"
@@ -15,7 +14,7 @@ anyhow = "1.0"
 thiserror = "1.0"
 
 
-flowy-sync = { path = "../../../shared-lib/flowy-sync", optional = true}
+flowy-sync = { path = "../flowy-sync", optional = true}
 lib-ot = { path = "../../../shared-lib/lib-ot", optional = true}
 serde_json = {version = "1.0", optional = true}
 http-flowy = { git = "https://github.com/AppFlowy-IO/AppFlowy-Server", optional = true}
@@ -29,7 +28,7 @@ ot = ["lib-ot"]
 serde = ["serde_json"]
 http_server = ["http-flowy"]
 db = ["flowy-database", "lib-sqlite", "r2d2"]
-dart = ["flowy-error-code/dart", "flowy-codegen/dart"]
+dart = ["flowy-codegen/dart"]
 
 [build-dependencies]
-flowy-codegen= { path = "../../../shared-lib/flowy-codegen"}
+flowy-codegen = { path = "../flowy-codegen"}

+ 1 - 1
frontend/rust-lib/flowy-error/Flowy.toml

@@ -1,3 +1,3 @@
 
 # Check out the FlowyConfig (located in flowy_toml.rs) for more details.
-proto_input = ["src/errors.rs",]
+proto_input = ["src/errors.rs","src/code.rs"]

+ 75 - 64
shared-lib/flowy-error-code/src/code.rs → frontend/rust-lib/flowy-error/src/code.rs

@@ -1,155 +1,166 @@
-use crate::protobuf::ErrorCode as ProtoBufErrorCode;
 use flowy_derive::ProtoBuf_Enum;
-use protobuf::ProtobufEnum;
-use std::convert::{TryFrom, TryInto};
 use thiserror::Error;
 
-#[derive(Debug, Clone, ProtoBuf_Enum, PartialEq, Eq, Error)]
+#[derive(Debug, Clone, PartialEq, Eq, Error, ProtoBuf_Enum)]
 pub enum ErrorCode {
     #[error("Internal error")]
     Internal = 0,
 
-    #[error("UserUnauthorized")]
+    #[error("Unauthorized user")]
     UserUnauthorized = 2,
 
-    #[error("RecordNotFound")]
+    #[error("Record not found")]
     RecordNotFound = 3,
 
     #[error("User id is empty")]
     UserIdIsEmpty = 4,
 
     #[error("Workspace name can not be empty or whitespace")]
-    WorkspaceNameInvalid = 100,
+    WorkspaceNameInvalid = 5,
 
     #[error("Workspace id can not be empty or whitespace")]
-    WorkspaceIdInvalid = 101,
+    WorkspaceIdInvalid = 6,
 
     #[error("Color style of the App is invalid")]
-    AppColorStyleInvalid = 102,
+    AppColorStyleInvalid = 7,
 
     #[error("Workspace desc is invalid")]
-    WorkspaceDescTooLong = 103,
+    WorkspaceDescTooLong = 8,
 
     #[error("Workspace description too long")]
-    WorkspaceNameTooLong = 104,
+    WorkspaceNameTooLong = 9,
 
     #[error("App id can not be empty or whitespace")]
-    AppIdInvalid = 110,
+    AppIdInvalid = 10,
 
     #[error("App name can not be empty or whitespace")]
-    AppNameInvalid = 111,
+    AppNameInvalid = 11,
 
     #[error("View name can not be empty or whitespace")]
-    ViewNameInvalid = 120,
+    ViewNameInvalid = 12,
 
     #[error("Thumbnail of the view is invalid")]
-    ViewThumbnailInvalid = 121,
+    ViewThumbnailInvalid = 13,
 
     #[error("View id can not be empty or whitespace")]
-    ViewIdInvalid = 122,
+    ViewIdInvalid = 14,
 
     #[error("View desc too long")]
-    ViewDescTooLong = 123,
+    ViewDescTooLong = 15,
 
     #[error("View data is invalid")]
-    ViewDataInvalid = 124,
+    ViewDataInvalid = 16,
 
     #[error("View name too long")]
-    ViewNameTooLong = 125,
+    ViewNameTooLong = 17,
 
-    #[error("Connection error")]
-    ConnectError = 200,
+    #[error("Http server connection error")]
+    HttpServerConnectError = 18,
 
     #[error("Email can not be empty or whitespace")]
-    EmailIsEmpty = 300,
+    EmailIsEmpty = 19,
+
     #[error("Email format is not valid")]
-    EmailFormatInvalid = 301,
+    EmailFormatInvalid = 20,
+
     #[error("Email already exists")]
-    EmailAlreadyExists = 302,
+    EmailAlreadyExists = 21,
+
     #[error("Password can not be empty or whitespace")]
-    PasswordIsEmpty = 303,
+    PasswordIsEmpty = 22,
+
     #[error("Password format too long")]
-    PasswordTooLong = 304,
+    PasswordTooLong = 23,
+
     #[error("Password contains forbidden characters.")]
-    PasswordContainsForbidCharacters = 305,
+    PasswordContainsForbidCharacters = 24,
+
     #[error("Password should contain a minimum of 6 characters with 1 special 1 letter and 1 numeric")]
-    PasswordFormatInvalid = 306,
+    PasswordFormatInvalid = 25,
+
     #[error("Password not match")]
-    PasswordNotMatch = 307,
+    PasswordNotMatch = 26,
+
     #[error("User name is too long")]
-    UserNameTooLong = 308,
+    UserNameTooLong = 27,
+
     #[error("User name contain forbidden characters")]
-    UserNameContainForbiddenCharacters = 309,
+    UserNameContainForbiddenCharacters = 28,
+
     #[error("User name can not be empty or whitespace")]
-    UserNameIsEmpty = 310,
+    UserNameIsEmpty = 29,
+
     #[error("user id is empty or whitespace")]
-    UserIdInvalid = 311,
+    UserIdInvalid = 30,
     #[error("User not exist")]
-    UserNotExist = 312,
+    UserNotExist = 31,
+
     #[error("Text is too long")]
-    TextTooLong = 400,
+    TextTooLong = 32,
 
     #[error("Grid id is empty")]
-    GridIdIsEmpty = 410,
+    GridIdIsEmpty = 33,
+
     #[error("Grid view id is empty")]
-    GridViewIdIsEmpty = 411,
+    GridViewIdIsEmpty = 34,
 
     #[error("Grid block id is empty")]
-    BlockIdIsEmpty = 420,
+    BlockIdIsEmpty = 35,
+
     #[error("Row id is empty")]
-    RowIdIsEmpty = 430,
+    RowIdIsEmpty = 36,
+
     #[error("Select option id is empty")]
-    OptionIdIsEmpty = 431,
+    OptionIdIsEmpty = 37,
+
     #[error("Field id is empty")]
-    FieldIdIsEmpty = 440,
+    FieldIdIsEmpty = 38,
+
     #[error("Field doesn't exist")]
-    FieldDoesNotExist = 441,
+    FieldDoesNotExist = 39,
+
     #[error("The name of the option should not be empty")]
-    SelectOptionNameIsEmpty = 442,
+    SelectOptionNameIsEmpty = 40,
+
     #[error("Field not exists")]
-    FieldNotExists = 443,
+    FieldNotExists = 41,
+
     #[error("The operation in this field is invalid")]
-    FieldInvalidOperation = 444,
+    FieldInvalidOperation = 42,
+
     #[error("Filter id is empty")]
-    FilterIdIsEmpty = 445,
+    FilterIdIsEmpty = 43,
+
     #[error("Field is not exist")]
-    FieldRecordNotFound = 446,
+    FieldRecordNotFound = 44,
 
     #[error("Field's type-option data should not be empty")]
-    TypeOptionDataIsEmpty = 450,
+    TypeOptionDataIsEmpty = 45,
 
     #[error("Group id is empty")]
-    GroupIdIsEmpty = 460,
+    GroupIdIsEmpty = 46,
 
     #[error("Invalid date time format")]
-    InvalidDateTimeFormat = 500,
+    InvalidDateTimeFormat = 47,
 
     #[error("The input string is empty or contains invalid characters")]
-    UnexpectedEmptyString = 999,
+    UnexpectedEmptyString = 48,
 
     #[error("Invalid data")]
-    InvalidData = 1000,
+    InvalidData = 49,
 
     #[error("Serde")]
-    Serde = 1001,
+    Serde = 50,
 
     #[error("Protobuf serde")]
-    ProtobufSerde = 1002,
+    ProtobufSerde = 51,
 
     #[error("Out of bounds")]
-    OutOfBounds = 10001,
+    OutOfBounds = 52,
 }
 
 impl ErrorCode {
     pub fn value(&self) -> i32 {
-        let code: ProtoBufErrorCode = self.clone().try_into().unwrap();
-        code.value()
-    }
-
-    pub fn from_i32(value: i32) -> Self {
-        match ProtoBufErrorCode::from_i32(value) {
-            None => ErrorCode::Internal,
-            Some(code) => ErrorCode::try_from(&code).unwrap(),
-        }
+        self.clone() as i32
     }
 }

+ 4 - 4
frontend/rust-lib/flowy-error/src/errors.rs

@@ -1,7 +1,7 @@
+use crate::ErrorCode;
 use anyhow::Result;
 use bytes::Bytes;
 use flowy_derive::ProtoBuf;
-use flowy_error_code::ErrorCode;
 use lib_dispatch::prelude::{AFPluginEventResponse, ResponseBuilder};
 use std::{convert::TryInto, fmt::Debug};
 use thiserror::Error;
@@ -30,7 +30,7 @@ macro_rules! static_flowy_error {
 impl FlowyError {
     pub fn new(code: ErrorCode, msg: &str) -> Self {
         Self {
-            code: code.value(),
+            code: code.value() as i32,
             msg: msg.to_owned(),
         }
     }
@@ -53,7 +53,7 @@ impl FlowyError {
     static_flowy_error!(view_desc, ErrorCode::ViewDescTooLong);
     static_flowy_error!(view_data, ErrorCode::ViewDataInvalid);
     static_flowy_error!(unauthorized, ErrorCode::UserUnauthorized);
-    static_flowy_error!(connection, ErrorCode::ConnectError);
+    static_flowy_error!(connection, ErrorCode::HttpServerConnectError);
     static_flowy_error!(email_empty, ErrorCode::EmailIsEmpty);
     static_flowy_error!(email_format, ErrorCode::EmailFormatInvalid);
     static_flowy_error!(email_exist, ErrorCode::EmailAlreadyExists);
@@ -77,7 +77,7 @@ impl FlowyError {
 impl std::convert::From<ErrorCode> for FlowyError {
     fn from(code: ErrorCode) -> Self {
         FlowyError {
-            code: code.value(),
+            code: code.value() as i32,
             msg: format!("{}", code),
         }
     }

+ 2 - 3
frontend/rust-lib/flowy-error/src/ext/http_server.rs

@@ -1,5 +1,4 @@
-use crate::FlowyError;
-use flowy_error_code::ErrorCode;
+use crate::{ErrorCode, FlowyError};
 use http_flowy::errors::{ErrorCode as ServerErrorCode, ServerError};
 
 impl std::convert::From<ServerError> for FlowyError {
@@ -15,7 +14,7 @@ fn server_error_to_flowy_error(code: ServerErrorCode) -> ErrorCode {
         ServerErrorCode::PasswordNotMatch => ErrorCode::PasswordNotMatch,
         ServerErrorCode::RecordNotFound => ErrorCode::RecordNotFound,
         ServerErrorCode::ConnectRefused | ServerErrorCode::ConnectTimeout | ServerErrorCode::ConnectClose => {
-            ErrorCode::ConnectError
+            ErrorCode::HttpServerConnectError
         }
         _ => ErrorCode::Internal,
     }

+ 2 - 1
frontend/rust-lib/flowy-error/src/lib.rs

@@ -1,6 +1,7 @@
+mod code;
 mod errors;
 mod ext;
 pub mod protobuf;
 
+pub use code::*;
 pub use errors::*;
-pub use flowy_error_code::ErrorCode;

+ 4 - 4
frontend/rust-lib/flowy-folder/Cargo.toml

@@ -7,9 +7,9 @@ edition = "2018"
 
 [dependencies]
 folder-rev-model = { path = "../../../shared-lib/folder-rev-model" }
-flowy-sync = { path = "../../../shared-lib/flowy-sync" }
+flowy-sync = { path = "../flowy-sync"}
 flowy-http-model = { path = "../../../shared-lib/flowy-http-model" }
-flowy-derive = { path = "../../../shared-lib/flowy-derive" }
+flowy-derive = { path = "../flowy-derive" }
 lib-ot = { path = "../../../shared-lib/lib-ot" }
 lib-infra = { path = "../../../shared-lib/lib-infra" }
 
@@ -35,14 +35,14 @@ serde = { version = "1.0", features = ["derive"] }
 tracing = { version = "0.1", features = ["log"] }
 bytes = { version = "1.0" }
 unicode-segmentation = "1.8"
+serde_json = "1.0"
 
 [dev-dependencies]
-serde_json = "1.0"
 flowy-folder = { path = "../flowy-folder", features = ["flowy_unit_test"]}
 flowy-test = { path = "../flowy-test" }
 
 [build-dependencies]
-flowy-codegen= { path = "../../../shared-lib/flowy-codegen"}
+flowy-codegen = { path = "../flowy-codegen"}
 
 
 [features]

+ 3 - 2
frontend/rust-lib/flowy-folder/src/manager.rs

@@ -26,7 +26,8 @@ use crate::services::clear_current_workspace;
 use crate::services::persistence::rev_sqlite::SQLiteFolderRevisionPersistence;
 use flowy_http_model::ws_data::ServerRevisionWSData;
 use flowy_sync::client_folder::FolderPad;
-use std::{collections::HashMap, convert::TryInto, fmt::Formatter, sync::Arc};
+use std::convert::TryFrom;
+use std::{collections::HashMap, fmt::Formatter, sync::Arc};
 use tokio::sync::RwLock as TokioRwLock;
 lazy_static! {
     static ref INIT_FOLDER_FLAG: TokioRwLock<HashMap<String, bool>> = TokioRwLock::new(HashMap::new());
@@ -139,7 +140,7 @@ impl FolderManager {
     // }
 
     pub async fn did_receive_ws_data(&self, data: Bytes) {
-        let result: Result<ServerRevisionWSData, protobuf::ProtobufError> = data.try_into();
+        let result = ServerRevisionWSData::try_from(data);
         match result {
             Ok(data) => match self.folder_editor.read().await.clone() {
                 None => {}

+ 1 - 1
frontend/rust-lib/flowy-folder/src/services/persistence/rev_sqlite/folder_rev_sqlite.rs

@@ -124,7 +124,7 @@ impl FolderRevisionSql {
     fn update(changeset: RevisionChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> {
         let state: TextRevisionState = changeset.state.clone().into();
         let filter = dsl::rev_table
-            .filter(dsl::rev_id.eq(changeset.rev_id.as_ref()))
+            .filter(dsl::rev_id.eq(changeset.rev_id))
             .filter(dsl::doc_id.eq(changeset.object_id));
         let _ = update(filter).set(dsl::state.eq(state)).execute(conn)?;
         tracing::debug!(

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

@@ -16,7 +16,7 @@ use crate::{
 };
 use bytes::Bytes;
 use flowy_database::kv::KV;
-use flowy_http_model::document::DocumentIdPB;
+use flowy_http_model::document::DocumentId;
 use folder_rev_model::{gen_view_id, ViewRevision};
 use futures::{FutureExt, StreamExt};
 use std::{collections::HashSet, sync::Arc};
@@ -201,7 +201,7 @@ impl ViewController {
     }
 
     #[tracing::instrument(level = "debug", skip(self,params), fields(doc_id = %params.value), err)]
-    pub(crate) async fn move_view_to_trash(&self, params: DocumentIdPB) -> Result<(), FlowyError> {
+    pub(crate) async fn move_view_to_trash(&self, params: DocumentId) -> Result<(), FlowyError> {
         let view_id = params.value;
         if let Some(latest_view_id) = KV::get_str(LATEST_VIEW_ID) {
             if latest_view_id == view_id {

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

@@ -3,7 +3,7 @@ use bytes::Bytes;
 use flowy_database::ConnectionPool;
 use flowy_error::{FlowyError, FlowyResult};
 use flowy_http_model::revision::{Revision, RevisionRange};
-use flowy_http_model::ws_data::{ClientRevisionWSData, NewDocumentUser, ServerRevisionWSDataType};
+use flowy_http_model::ws_data::{ClientRevisionWSData, NewDocumentUser};
 use flowy_revision::*;
 use flowy_sync::client_folder::FolderPad;
 use flowy_sync::server_folder::FolderOperations;
@@ -130,14 +130,14 @@ impl FolderRevisionWSDataStream {
 }
 
 impl RevisionWSDataStream for FolderRevisionWSDataStream {
-    fn receive_push_revision(&self, bytes: Bytes) -> BoxResultFuture<(), FlowyError> {
+    fn receive_push_revision(&self, revisions: Vec<Revision>) -> BoxResultFuture<(), FlowyError> {
         let resolver = self.conflict_controller.clone();
-        Box::pin(async move { resolver.receive_bytes(bytes).await })
+        Box::pin(async move { resolver.receive_revisions(revisions).await })
     }
 
-    fn receive_ack(&self, id: String, ty: ServerRevisionWSDataType) -> BoxResultFuture<(), FlowyError> {
+    fn receive_ack(&self, rev_id: i64) -> BoxResultFuture<(), FlowyError> {
         let resolver = self.conflict_controller.clone();
-        Box::pin(async move { resolver.ack_revision(id, ty).await })
+        Box::pin(async move { resolver.ack_revision(rev_id).await })
     }
 
     fn receive_new_user_connect(&self, _new_user: NewDocumentUser) -> BoxResultFuture<(), FlowyError> {

+ 0 - 13
frontend/rust-lib/flowy-folder/tests/workspace/script.rs

@@ -15,8 +15,6 @@ use flowy_folder::entities::{
 };
 use flowy_folder::event_map::FolderEvent::*;
 use flowy_folder::{errors::ErrorCode, services::folder_editor::FolderEditor};
-
-use flowy_http_model::document::DocumentPayloadPB;
 use flowy_revision::disk::RevisionState;
 use flowy_revision::REVISION_WRITE_INTERVAL_IN_MILLIS;
 use flowy_test::{event_builder::*, FlowySDKTest};
@@ -413,17 +411,6 @@ pub async fn delete_view(sdk: &FlowySDKTest, view_ids: Vec<String>) {
         .await;
 }
 
-#[allow(dead_code)]
-pub async fn set_latest_view(sdk: &FlowySDKTest, view_id: &str) -> DocumentPayloadPB {
-    let view_id: ViewIdPB = view_id.into();
-    FolderEventBuilder::new(sdk.clone())
-        .event(SetLatestView)
-        .payload(view_id)
-        .async_send()
-        .await
-        .parse::<DocumentPayloadPB>()
-}
-
 pub async fn read_trash(sdk: &FlowySDKTest) -> RepeatedTrashPB {
     FolderEventBuilder::new(sdk.clone())
         .event(ReadTrash)

+ 3 - 5
frontend/rust-lib/flowy-grid/Cargo.toml

@@ -11,11 +11,11 @@ dart-notify = { path = "../dart-notify" }
 flowy-revision = { path = "../flowy-revision" }
 flowy-task= { path = "../flowy-task" }
 flowy-error = { path = "../flowy-error", features = ["db"]}
-flowy-derive = { path = "../../../shared-lib/flowy-derive" }
+flowy-derive = { path = "../flowy-derive" }
 lib-ot = { path = "../../../shared-lib/lib-ot" }
 lib-infra = { path = "../../../shared-lib/lib-infra" }
 grid-rev-model = { path = "../../../shared-lib/grid-rev-model" }
-flowy-sync = { path = "../../../shared-lib/flowy-sync" }
+flowy-sync = { path = "../flowy-sync"}
 flowy-http-model = { path = "../../../shared-lib/flowy-http-model" }
 flowy-database = { path = "../flowy-database" }
 anyhow = "1.0"
@@ -52,9 +52,7 @@ flowy-test = { path = "../flowy-test" }
 flowy-grid = { path = "../flowy-grid", features = ["flowy_unit_test"]}
 
 [build-dependencies]
-flowy-codegen= { path = "../../../shared-lib/flowy-codegen"}
-
-
+flowy-codegen = { path = "../flowy-codegen"}
 
 [features]
 default = []

+ 2 - 2
frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option/select_type_option.rs

@@ -7,8 +7,8 @@ use crate::services::cell::{
 
 use crate::services::field::selection_type_option::type_option_transform::SelectOptionTypeOptionTransformHelper;
 use crate::services::field::{
-    CheckboxCellData, ChecklistTypeOptionPB, MultiSelectTypeOptionPB, SingleSelectTypeOptionPB, StrCellData,
-    TypeOption, TypeOptionCellData, TypeOptionTransform,
+    CheckboxCellData, ChecklistTypeOptionPB, MultiSelectTypeOptionPB, SingleSelectTypeOptionPB, TypeOption,
+    TypeOptionCellData, TypeOptionTransform,
 };
 use bytes::Bytes;
 use flowy_derive::{ProtoBuf, ProtoBuf_Enum};

+ 1 - 1
frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option/text_tests.rs

@@ -2,7 +2,7 @@
 mod tests {
     use crate::entities::FieldType;
     use crate::services::cell::stringify_cell_data;
-    use crate::services::cell::CellDataDecoder;
+
     use crate::services::field::FieldBuilder;
     use crate::services::field::*;
 

+ 1 - 1
frontend/rust-lib/flowy-grid/src/services/persistence/rev_sqlite/grid_block_sqlite_impl.rs

@@ -124,7 +124,7 @@ impl GridMetaRevisionSql {
     fn update(changeset: RevisionChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> {
         let state: GridBlockRevisionState = changeset.state.clone().into();
         let filter = dsl::grid_meta_rev_table
-            .filter(dsl::rev_id.eq(changeset.rev_id.as_ref()))
+            .filter(dsl::rev_id.eq(changeset.rev_id))
             .filter(dsl::object_id.eq(changeset.object_id));
         let _ = update(filter).set(dsl::state.eq(state)).execute(conn)?;
         tracing::debug!(

+ 1 - 1
frontend/rust-lib/flowy-grid/src/services/persistence/rev_sqlite/grid_sqlite_impl.rs

@@ -123,7 +123,7 @@ impl GridRevisionSql {
     fn update(changeset: RevisionChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> {
         let state: GridRevisionState = changeset.state.clone().into();
         let filter = dsl::grid_rev_table
-            .filter(dsl::rev_id.eq(changeset.rev_id.as_ref()))
+            .filter(dsl::rev_id.eq(changeset.rev_id))
             .filter(dsl::object_id.eq(changeset.object_id));
         let _ = update(filter).set(dsl::state.eq(state)).execute(conn)?;
         tracing::debug!(

+ 1 - 1
frontend/rust-lib/flowy-grid/src/services/persistence/rev_sqlite/grid_view_sqlite_impl.rs

@@ -123,7 +123,7 @@ impl GridViewRevisionSql {
     fn update(changeset: RevisionChangeset, conn: &SqliteConnection) -> Result<(), FlowyError> {
         let state: GridViewRevisionState = changeset.state.clone().into();
         let filter = dsl::grid_view_rev_table
-            .filter(dsl::rev_id.eq(changeset.rev_id.as_ref()))
+            .filter(dsl::rev_id.eq(changeset.rev_id))
             .filter(dsl::object_id.eq(changeset.object_id));
         let _ = update(filter).set(dsl::state.eq(state)).execute(conn)?;
         tracing::debug!(

+ 3 - 3
frontend/rust-lib/flowy-net/Cargo.toml

@@ -8,8 +8,8 @@ edition = "2018"
 [dependencies]
 lib-dispatch = { path = "../lib-dispatch" }
 flowy-error = { path = "../flowy-error", features = ["collaboration", "http_server"] }
-flowy-derive = { path = "../../../shared-lib/flowy-derive" }
-flowy-sync = { path = "../../../shared-lib/flowy-sync"}
+flowy-derive = { path = "../flowy-derive" }
+flowy-sync = { path = "../flowy-sync"}
 flowy-http-model = { path = "../../../shared-lib/flowy-http-model"}
 folder-rev-model = { path = "../../../shared-lib/folder-rev-model"}
 flowy-folder = { path = "../flowy-folder" }
@@ -48,4 +48,4 @@ dart = [
 ]
 
 [build-dependencies]
-flowy-codegen = { path = "../../../shared-lib/flowy-codegen"}
+flowy-codegen = { path = "../flowy-codegen"}

+ 8 - 8
frontend/rust-lib/flowy-net/src/http_server/document.rs

@@ -4,7 +4,7 @@ use crate::{
 };
 use flowy_document::DocumentCloudService;
 use flowy_error::FlowyError;
-use flowy_http_model::document::{CreateDocumentParams, DocumentIdPB, DocumentPayloadPB, ResetDocumentParams};
+use flowy_http_model::document::{CreateDocumentParams, DocumentId, DocumentPayload, ResetDocumentParams};
 use http_flowy::response::FlowyResponse;
 use lazy_static::lazy_static;
 use lib_infra::future::FutureResult;
@@ -27,7 +27,7 @@ impl DocumentCloudService for DocumentCloudServiceImpl {
         FutureResult::new(async move { create_document_request(&token, params, &url).await })
     }
 
-    fn fetch_document(&self, token: &str, params: DocumentIdPB) -> FutureResult<Option<DocumentPayloadPB>, FlowyError> {
+    fn fetch_document(&self, token: &str, params: DocumentId) -> FutureResult<Option<DocumentPayload>, FlowyError> {
         let token = token.to_owned();
         let url = self.config.doc_url();
         FutureResult::new(async move { read_document_request(&token, params, &url).await })
@@ -44,7 +44,7 @@ pub async fn create_document_request(token: &str, params: CreateDocumentParams,
     let _ = request_builder()
         .post(url)
         .header(HEADER_TOKEN, token)
-        .protobuf(params)?
+        .json(params)?
         .send()
         .await?;
     Ok(())
@@ -52,14 +52,14 @@ pub async fn create_document_request(token: &str, params: CreateDocumentParams,
 
 pub async fn read_document_request(
     token: &str,
-    params: DocumentIdPB,
+    params: DocumentId,
     url: &str,
-) -> Result<Option<DocumentPayloadPB>, FlowyError> {
+) -> Result<Option<DocumentPayload>, FlowyError> {
     let doc = request_builder()
         .get(url)
         .header(HEADER_TOKEN, token)
-        .protobuf(params)?
-        .option_response()
+        .json(params)?
+        .option_json_response()
         .await?;
 
     Ok(doc)
@@ -69,7 +69,7 @@ pub async fn reset_doc_request(token: &str, params: ResetDocumentParams, url: &s
     let _ = request_builder()
         .patch(url)
         .header(HEADER_TOKEN, token)
-        .protobuf(params)?
+        .json(params)?
         .send()
         .await?;
     Ok(())

+ 29 - 50
frontend/rust-lib/flowy-net/src/local_server/persistence.rs

@@ -1,6 +1,6 @@
-use flowy_http_model::document::DocumentPayloadPB;
+use flowy_http_model::document::DocumentPayload;
 use flowy_http_model::folder::FolderInfo;
-use flowy_http_model::revision::{RepeatedRevision, Revision};
+use flowy_http_model::revision::Revision;
 use flowy_sync::{
     errors::CollaborateError,
     server_document::*,
@@ -16,18 +16,14 @@ use std::{
 // For the moment, we use memory to cache the data, it will be implemented with
 // other storage. Like the Firestore,Dropbox.etc.
 pub trait RevisionCloudStorage: Send + Sync {
-    fn set_revisions(&self, repeated_revision: RepeatedRevision) -> BoxResultFuture<(), CollaborateError>;
+    fn set_revisions(&self, revisions: Vec<Revision>) -> BoxResultFuture<(), CollaborateError>;
     fn get_revisions(
         &self,
         object_id: &str,
         rev_ids: Option<Vec<i64>>,
-    ) -> BoxResultFuture<RepeatedRevision, CollaborateError>;
+    ) -> BoxResultFuture<Vec<Revision>, CollaborateError>;
 
-    fn reset_object(
-        &self,
-        object_id: &str,
-        repeated_revision: RepeatedRevision,
-    ) -> BoxResultFuture<(), CollaborateError>;
+    fn reset_object(&self, object_id: &str, revisions: Vec<Revision>) -> BoxResultFuture<(), CollaborateError>;
 }
 
 pub(crate) struct LocalDocumentCloudPersistence {
@@ -53,8 +49,8 @@ impl FolderCloudPersistence for LocalDocumentCloudPersistence {
         let storage = self.storage.clone();
         let folder_id = folder_id.to_owned();
         Box::pin(async move {
-            let repeated_revision = storage.get_revisions(&folder_id, None).await?;
-            match make_folder_from_revisions_pb(&folder_id, repeated_revision)? {
+            let revisions = storage.get_revisions(&folder_id, None).await?;
+            match make_folder_from_revisions_pb(&folder_id, revisions)? {
                 Some(folder_info) => Ok(folder_info),
                 None => Err(CollaborateError::record_not_found()),
             }
@@ -65,20 +61,20 @@ impl FolderCloudPersistence for LocalDocumentCloudPersistence {
         &self,
         _user_id: &str,
         folder_id: &str,
-        repeated_revision: RepeatedRevision,
+        revisions: Vec<Revision>,
     ) -> BoxResultFuture<Option<FolderInfo>, CollaborateError> {
         let folder_id = folder_id.to_owned();
         let storage = self.storage.clone();
         Box::pin(async move {
-            let _ = storage.set_revisions(repeated_revision.clone()).await?;
-            make_folder_from_revisions_pb(&folder_id, repeated_revision)
+            let _ = storage.set_revisions(revisions.clone()).await?;
+            make_folder_from_revisions_pb(&folder_id, revisions)
         })
     }
 
-    fn save_folder_revisions(&self, repeated_revision: RepeatedRevision) -> BoxResultFuture<(), CollaborateError> {
+    fn save_folder_revisions(&self, revisions: Vec<Revision>) -> BoxResultFuture<(), CollaborateError> {
         let storage = self.storage.clone();
         Box::pin(async move {
-            let _ = storage.set_revisions(repeated_revision).await?;
+            let _ = storage.set_revisions(revisions).await?;
             Ok(())
         })
     }
@@ -90,28 +86,21 @@ impl FolderCloudPersistence for LocalDocumentCloudPersistence {
     ) -> BoxResultFuture<Vec<Revision>, CollaborateError> {
         let folder_id = folder_id.to_owned();
         let storage = self.storage.clone();
-        Box::pin(async move {
-            let repeated_revision = storage.get_revisions(&folder_id, rev_ids).await?;
-            Ok(repeated_revision.into_inner())
-        })
+        Box::pin(async move { storage.get_revisions(&folder_id, rev_ids).await })
     }
 
-    fn reset_folder(
-        &self,
-        folder_id: &str,
-        repeated_revision: RepeatedRevision,
-    ) -> BoxResultFuture<(), CollaborateError> {
+    fn reset_folder(&self, folder_id: &str, revisions: Vec<Revision>) -> BoxResultFuture<(), CollaborateError> {
         let storage = self.storage.clone();
         let folder_id = folder_id.to_owned();
         Box::pin(async move {
-            let _ = storage.reset_object(&folder_id, repeated_revision).await?;
+            let _ = storage.reset_object(&folder_id, revisions).await?;
             Ok(())
         })
     }
 }
 
 impl DocumentCloudPersistence for LocalDocumentCloudPersistence {
-    fn read_document(&self, doc_id: &str) -> BoxResultFuture<DocumentPayloadPB, CollaborateError> {
+    fn read_document(&self, doc_id: &str) -> BoxResultFuture<DocumentPayload, CollaborateError> {
         let storage = self.storage.clone();
         let doc_id = doc_id.to_owned();
         Box::pin(async move {
@@ -126,13 +115,13 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence {
     fn create_document(
         &self,
         doc_id: &str,
-        repeated_revision: RepeatedRevision,
-    ) -> BoxResultFuture<Option<DocumentPayloadPB>, CollaborateError> {
+        revisions: Vec<Revision>,
+    ) -> BoxResultFuture<Option<DocumentPayload>, CollaborateError> {
         let doc_id = doc_id.to_owned();
         let storage = self.storage.clone();
         Box::pin(async move {
-            let _ = storage.set_revisions(repeated_revision.clone()).await?;
-            make_document_from_revision_pbs(&doc_id, repeated_revision)
+            let _ = storage.set_revisions(revisions.clone()).await?;
+            make_document_from_revision_pbs(&doc_id, revisions)
         })
     }
 
@@ -143,21 +132,18 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence {
     ) -> BoxResultFuture<Vec<Revision>, CollaborateError> {
         let doc_id = doc_id.to_owned();
         let storage = self.storage.clone();
-        Box::pin(async move {
-            let repeated_revision = storage.get_revisions(&doc_id, rev_ids).await?;
-            Ok(repeated_revision.into_inner())
-        })
+        Box::pin(async move { storage.get_revisions(&doc_id, rev_ids).await })
     }
 
-    fn save_document_revisions(&self, repeated_revision: RepeatedRevision) -> BoxResultFuture<(), CollaborateError> {
+    fn save_document_revisions(&self, revisions: Vec<Revision>) -> BoxResultFuture<(), CollaborateError> {
         let storage = self.storage.clone();
         Box::pin(async move {
-            let _ = storage.set_revisions(repeated_revision).await?;
+            let _ = storage.set_revisions(revisions).await?;
             Ok(())
         })
     }
 
-    fn reset_document(&self, doc_id: &str, revisions: RepeatedRevision) -> BoxResultFuture<(), CollaborateError> {
+    fn reset_document(&self, doc_id: &str, revisions: Vec<Revision>) -> BoxResultFuture<(), CollaborateError> {
         let storage = self.storage.clone();
         let doc_id = doc_id.to_owned();
         Box::pin(async move {
@@ -170,26 +156,19 @@ impl DocumentCloudPersistence for LocalDocumentCloudPersistence {
 #[derive(Default)]
 struct MemoryDocumentCloudStorage {}
 impl RevisionCloudStorage for MemoryDocumentCloudStorage {
-    fn set_revisions(&self, _repeated_revision: RepeatedRevision) -> BoxResultFuture<(), CollaborateError> {
+    fn set_revisions(&self, _revisions: Vec<Revision>) -> BoxResultFuture<(), CollaborateError> {
         Box::pin(async move { Ok(()) })
     }
 
     fn get_revisions(
         &self,
-        _doc_id: &str,
+        _object_id: &str,
         _rev_ids: Option<Vec<i64>>,
-    ) -> BoxResultFuture<RepeatedRevision, CollaborateError> {
-        Box::pin(async move {
-            let repeated_revisions = RepeatedRevision::default();
-            Ok(repeated_revisions)
-        })
+    ) -> BoxResultFuture<Vec<Revision>, CollaborateError> {
+        Box::pin(async move { Ok(vec![]) })
     }
 
-    fn reset_object(
-        &self,
-        _doc_id: &str,
-        _repeated_revision: RepeatedRevision,
-    ) -> BoxResultFuture<(), CollaborateError> {
+    fn reset_object(&self, _object_id: &str, _revisions: Vec<Revision>) -> BoxResultFuture<(), CollaborateError> {
         Box::pin(async move { Ok(()) })
     }
 }

+ 8 - 24
frontend/rust-lib/flowy-net/src/local_server/server.rs

@@ -131,7 +131,7 @@ impl LocalWebSocketRunner {
         tracing::trace!(
             "[LocalFolderServer] receive: {}:{}-{:?} ",
             client_data.object_id,
-            client_data.id(),
+            client_data.rev_id,
             client_data.ty,
         );
         let client_ws_sender = self.client_ws_sender.clone();
@@ -141,19 +141,12 @@ impl LocalWebSocketRunner {
             channel: WSChannel::Folder,
         });
         let ty = client_data.ty.clone();
-        let document_client_data: ClientRevisionWSDataPB = client_data.try_into().unwrap();
         match ty {
             ClientRevisionWSDataType::ClientPushRev => {
-                let _ = self
-                    .folder_manager
-                    .handle_client_revisions(user, document_client_data)
-                    .await?;
+                let _ = self.folder_manager.handle_client_revisions(user, client_data).await?;
             }
             ClientRevisionWSDataType::ClientPing => {
-                let _ = self
-                    .folder_manager
-                    .handle_client_ping(user, document_client_data)
-                    .await?;
+                let _ = self.folder_manager.handle_client_ping(user, client_data).await?;
             }
         }
         Ok(())
@@ -167,7 +160,7 @@ impl LocalWebSocketRunner {
         tracing::trace!(
             "[LocalDocumentServer] receive: {}:{}-{:?} ",
             client_data.object_id,
-            client_data.id(),
+            client_data.rev_id,
             client_data.ty,
         );
         let client_ws_sender = self.client_ws_sender.clone();
@@ -177,16 +170,12 @@ impl LocalWebSocketRunner {
             channel: WSChannel::Document,
         });
         let ty = client_data.ty.clone();
-        let document_client_data: ClientRevisionWSDataPB = client_data.try_into().unwrap();
         match ty {
             ClientRevisionWSDataType::ClientPushRev => {
-                let _ = self
-                    .doc_manager
-                    .handle_client_revisions(user, document_client_data)
-                    .await?;
+                let _ = self.doc_manager.handle_client_revisions(user, client_data).await?;
             }
             ClientRevisionWSDataType::ClientPing => {
-                let _ = self.doc_manager.handle_client_ping(user, document_client_data).await?;
+                let _ = self.doc_manager.handle_client_ping(user, client_data).await?;
             }
         }
         Ok(())
@@ -253,8 +242,7 @@ use flowy_folder::entities::{
     view::{CreateViewParams, RepeatedViewIdPB, UpdateViewParams, ViewIdPB},
     workspace::{CreateWorkspaceParams, UpdateWorkspaceParams, WorkspaceIdPB},
 };
-use flowy_http_model::document::{CreateDocumentParams, DocumentIdPB, DocumentPayloadPB, ResetDocumentParams};
-use flowy_http_model::protobuf::ClientRevisionWSData as ClientRevisionWSDataPB;
+use flowy_http_model::document::{CreateDocumentParams, DocumentId, DocumentPayload, ResetDocumentParams};
 use flowy_http_model::ws_data::{ClientRevisionWSData, ClientRevisionWSDataType};
 use flowy_user::entities::{
     SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserProfileParams, UserProfilePB,
@@ -414,11 +402,7 @@ impl DocumentCloudService for LocalServer {
         FutureResult::new(async { Ok(()) })
     }
 
-    fn fetch_document(
-        &self,
-        _token: &str,
-        _params: DocumentIdPB,
-    ) -> FutureResult<Option<DocumentPayloadPB>, FlowyError> {
+    fn fetch_document(&self, _token: &str, _params: DocumentId) -> FutureResult<Option<DocumentPayload>, FlowyError> {
         FutureResult::new(async { Ok(None) })
     }
 

+ 27 - 1
frontend/rust-lib/flowy-net/src/request.rs

@@ -88,6 +88,14 @@ impl HttpRequestBuilder {
         self.bytes(body)
     }
 
+    pub fn json<T>(self, body: T) -> Result<Self, ServerError>
+    where
+        T: serde::Serialize,
+    {
+        let bytes = Bytes::from(serde_json::to_vec(&body)?);
+        self.bytes(bytes)
+    }
+
     pub fn bytes(mut self, body: Bytes) -> Result<Self, ServerError> {
         self.body = Some(body);
         Ok(self)
@@ -109,7 +117,8 @@ impl HttpRequestBuilder {
         }
     }
 
-    pub async fn option_response<T>(self) -> Result<Option<T>, ServerError>
+    #[allow(dead_code)]
+    pub async fn option_protobuf_response<T>(self) -> Result<Option<T>, ServerError>
     where
         T: TryFrom<Bytes, Error = ProtobufError>,
     {
@@ -126,6 +135,23 @@ impl HttpRequestBuilder {
         }
     }
 
+    pub async fn option_json_response<T>(self) -> Result<Option<T>, ServerError>
+    where
+        T: serde::de::DeserializeOwned + 'static,
+    {
+        let result = self.inner_send().await;
+        match result {
+            Ok(builder) => match builder.response {
+                None => Err(unexpected_empty_payload(&builder.url)),
+                Some(data) => Ok(Some(serde_json::from_slice(&data)?)),
+            },
+            Err(error) => match error.is_record_not_found() {
+                true => Ok(None),
+                false => Err(error),
+            },
+        }
+    }
+
     fn token(&self) -> Option<String> {
         match self.headers.get(HEADER_TOKEN) {
             None => None,

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

@@ -1,5 +1,5 @@
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_http_model::revision::{RevId, Revision, RevisionRange};
+use flowy_http_model::revision::{Revision, RevisionRange};
 use std::fmt::Debug;
 use std::sync::Arc;
 
@@ -106,7 +106,7 @@ impl SyncRecord {
 
 pub struct RevisionChangeset {
     pub object_id: String,
-    pub rev_id: RevId,
+    pub rev_id: i64,
     pub state: RevisionState,
 }
 

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

@@ -1,12 +1,9 @@
 use crate::{RevisionMD5, RevisionManager};
 use bytes::Bytes;
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_http_model::{
-    revision::{RepeatedRevision, Revision, RevisionRange},
-    ws_data::ServerRevisionWSDataType,
-};
+use flowy_http_model::revision::{Revision, RevisionRange};
 use lib_infra::future::BoxResultFuture;
-use std::{convert::TryFrom, sync::Arc};
+use std::sync::Arc;
 
 pub struct TransformOperations<Operations> {
     pub client_operations: Operations,
@@ -36,7 +33,7 @@ where
 
 pub trait ConflictRevisionSink: Send + Sync + 'static {
     fn send(&self, revisions: Vec<Revision>) -> BoxResultFuture<(), FlowyError>;
-    fn ack(&self, rev_id: String, ty: ServerRevisionWSDataType) -> BoxResultFuture<(), FlowyError>;
+    fn ack(&self, rev_id: i64) -> BoxResultFuture<(), FlowyError>;
 }
 
 pub struct ConflictController<Operations, Connection>
@@ -75,13 +72,12 @@ where
     Operations: OperationsSerializer + OperationsDeserializer<Operations> + Clone + Send + Sync,
     Connection: Send + Sync + 'static,
 {
-    pub async fn receive_bytes(&self, bytes: Bytes) -> FlowyResult<()> {
-        let repeated_revision = RepeatedRevision::try_from(bytes)?;
-        if repeated_revision.is_empty() {
+    pub async fn receive_revisions(&self, revisions: Vec<Revision>) -> FlowyResult<()> {
+        if revisions.is_empty() {
             return Ok(());
         }
 
-        match self.handle_revision(repeated_revision).await? {
+        match self.handle_revision(revisions).await? {
             None => {}
             Some(server_revision) => {
                 self.rev_sink.send(vec![server_revision]).await?;
@@ -90,8 +86,8 @@ where
         Ok(())
     }
 
-    pub async fn ack_revision(&self, rev_id: String, ty: ServerRevisionWSDataType) -> FlowyResult<()> {
-        let _ = self.rev_sink.ack(rev_id, ty).await?;
+    pub async fn ack_revision(&self, rev_id: i64) -> FlowyResult<()> {
+        let _ = self.rev_sink.ack(rev_id).await?;
         Ok(())
     }
 
@@ -101,8 +97,7 @@ where
         Ok(())
     }
 
-    async fn handle_revision(&self, repeated_revision: RepeatedRevision) -> FlowyResult<Option<Revision>> {
-        let mut revisions = repeated_revision.into_inner();
+    async fn handle_revision(&self, mut revisions: Vec<Revision>) -> FlowyResult<Option<Revision>> {
         let first_revision = revisions.first().unwrap();
         if let Some(local_revision) = self.rev_manager.get_revision(first_revision.rev_id).await {
             if local_revision.md5 == first_revision.md5 {

+ 24 - 34
frontend/rust-lib/flowy-revision/src/ws_manager.rs

@@ -1,15 +1,13 @@
 use crate::ConflictRevisionSink;
 use async_stream::stream;
-use bytes::Bytes;
+
 use flowy_error::{FlowyError, FlowyResult};
-use flowy_http_model::{
-    revision::{RevId, Revision, RevisionRange},
-    ws_data::{ClientRevisionWSData, NewDocumentUser, ServerRevisionWSData, ServerRevisionWSDataType},
-};
+use flowy_http_model::revision::{Revision, RevisionRange};
+use flowy_http_model::ws_data::{ClientRevisionWSData, NewDocumentUser, ServerRevisionWSData, WSRevisionPayload};
 use futures_util::{future::BoxFuture, stream::StreamExt};
 use lib_infra::future::{BoxResultFuture, FutureResult};
 use lib_ws::WSConnectState;
-use std::{collections::VecDeque, convert::TryFrom, fmt::Formatter, sync::Arc};
+use std::{collections::VecDeque, fmt::Formatter, sync::Arc};
 use tokio::{
     sync::{
         broadcast, mpsc,
@@ -21,8 +19,8 @@ use tokio::{
 
 // The consumer consumes the messages pushed by the web socket.
 pub trait RevisionWSDataStream: Send + Sync {
-    fn receive_push_revision(&self, bytes: Bytes) -> BoxResultFuture<(), FlowyError>;
-    fn receive_ack(&self, id: String, ty: ServerRevisionWSDataType) -> BoxResultFuture<(), FlowyError>;
+    fn receive_push_revision(&self, revisions: Vec<Revision>) -> BoxResultFuture<(), FlowyError>;
+    fn receive_ack(&self, rev_id: i64) -> BoxResultFuture<(), FlowyError>;
     fn receive_new_user_connect(&self, new_user: NewDocumentUser) -> BoxResultFuture<(), FlowyError>;
     fn pull_revisions_in_range(&self, range: RevisionRange) -> BoxResultFuture<(), FlowyError>;
 }
@@ -214,26 +212,22 @@ impl RevisionWSStream {
     }
 
     async fn handle_message(&self, msg: ServerRevisionWSData) -> FlowyResult<()> {
-        let ServerRevisionWSData { object_id, ty, data } = msg;
-        let bytes = Bytes::from(data);
-        match ty {
-            ServerRevisionWSDataType::ServerPushRev => {
-                tracing::trace!("[{}]: new push revision: {}:{:?}", self, object_id, ty);
-                let _ = self.consumer.receive_push_revision(bytes).await?;
+        let ServerRevisionWSData { object_id, payload } = msg;
+        match payload {
+            WSRevisionPayload::ServerPushRev { revisions } => {
+                tracing::trace!("[{}]: new push revision: {}", self, object_id);
+                let _ = self.consumer.receive_push_revision(revisions).await?;
             }
-            ServerRevisionWSDataType::ServerPullRev => {
-                let range = RevisionRange::try_from(bytes)?;
-                tracing::trace!("[{}]: new pull: {}:{}-{:?}", self, object_id, range, ty);
+            WSRevisionPayload::ServerPullRev { range } => {
+                tracing::trace!("[{}]: new pull: {}:{:?}", self, object_id, range);
                 let _ = self.consumer.pull_revisions_in_range(range).await?;
             }
-            ServerRevisionWSDataType::ServerAck => {
-                let rev_id = RevId::try_from(bytes).unwrap().value;
-                tracing::trace!("[{}]: new ack: {}:{}-{:?}", self, object_id, rev_id, ty);
-                let _ = self.consumer.receive_ack(rev_id.to_string(), ty).await;
+            WSRevisionPayload::ServerAck { rev_id } => {
+                tracing::trace!("[{}]: new ack: {}:{}", self, object_id, rev_id);
+                let _ = self.consumer.receive_ack(rev_id).await;
             }
-            ServerRevisionWSDataType::UserConnect => {
-                let new_user = NewDocumentUser::try_from(bytes)?;
-                let _ = self.consumer.receive_new_user_connect(new_user).await;
+            WSRevisionPayload::UserConnect { user } => {
+                let _ = self.consumer.receive_new_user_connect(user).await;
             }
         }
         Ok(())
@@ -309,7 +303,7 @@ impl RevisionWSSink {
                 Ok(())
             }
             Some(data) => {
-                tracing::trace!("[{}]: send {}:{}-{:?}", self, data.object_id, data.id(), data.ty);
+                tracing::trace!("[{}]: send {}:{}-{:?}", self, data.object_id, data.rev_id, data.ty);
                 self.rev_web_socket.send(data).await
             }
         }
@@ -397,18 +391,17 @@ impl WSDataProvider {
         data
     }
 
-    pub async fn ack_data(&self, id: String, _ty: ServerRevisionWSDataType) -> FlowyResult<()> {
+    pub async fn ack_data(&self, rev_id: i64) -> FlowyResult<()> {
         let source = self.current_source.read().await.clone();
         match source {
             Source::Custom => {
                 let should_pop = match self.rev_ws_data_list.read().await.front() {
                     None => false,
                     Some(val) => {
-                        let expected_id = val.id();
-                        if expected_id == id {
+                        if val.rev_id == rev_id {
                             true
                         } else {
-                            tracing::error!("The front element's {} is not equal to the {}", expected_id, id);
+                            tracing::error!("The front element's {} is not equal to the {}", val.rev_id, rev_id);
                             false
                         }
                     }
@@ -419,9 +412,6 @@ impl WSDataProvider {
                 Ok(())
             }
             Source::Revision => {
-                let rev_id = id.parse::<i64>().map_err(|e| {
-                    FlowyError::internal().context(format!("Parse {} rev_id from {} failed. {}", self.object_id, id, e))
-                })?;
                 let _ = self.data_source.ack_revision(rev_id).await?;
                 Ok::<(), FlowyError>(())
             }
@@ -439,8 +429,8 @@ impl ConflictRevisionSink for Arc<WSDataProvider> {
         })
     }
 
-    fn ack(&self, rev_id: String, ty: ServerRevisionWSDataType) -> BoxResultFuture<(), FlowyError> {
+    fn ack(&self, rev_id: i64) -> BoxResultFuture<(), FlowyError> {
         let sink = self.clone();
-        Box::pin(async move { sink.ack_data(rev_id, ty).await })
+        Box::pin(async move { sink.ack_data(rev_id).await })
     }
 }

+ 1 - 1
frontend/rust-lib/flowy-revision/tests/revision_test/script.rs

@@ -205,7 +205,7 @@ impl RevisionDiskCache<RevisionConnectionMock> for RevisionDiskCacheMock {
                 .records
                 .write()
                 .iter_mut()
-                .find(|record| record.revision.rev_id == *changeset.rev_id.as_ref())
+                .find(|record| record.revision.rev_id == changeset.rev_id)
             {
                 record.state = changeset.state;
             }

+ 5 - 5
shared-lib/flowy-sync/Cargo.toml → frontend/rust-lib/flowy-sync/Cargo.toml

@@ -6,12 +6,12 @@ edition = "2018"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-lib-ot = { path = "../lib-ot" }
-lib-infra = { path = "../lib-infra" }
+lib-ot = { path = "../../../shared-lib/lib-ot" }
+lib-infra = { path = "../../../shared-lib/lib-infra" }
 flowy-derive = { path = "../flowy-derive" }
-folder-rev-model = { path = "../folder-rev-model" }
-grid-rev-model = { path = "../grid-rev-model" }
-flowy-http-model= { path = "../flowy-http-model" }
+folder-rev-model = { path = "../../../shared-lib/folder-rev-model" }
+grid-rev-model = { path = "../../../shared-lib/grid-rev-model" }
+flowy-http-model = { path = "../../../shared-lib/flowy-http-model" }
 protobuf = {version = "2.18.0"}
 bytes = "1.0"
 log = "0.4.14"

+ 0 - 0
shared-lib/flowy-sync/src/client_document/document_pad.rs → frontend/rust-lib/flowy-sync/src/client_document/document_pad.rs


+ 0 - 0
shared-lib/flowy-sync/src/client_document/extensions/delete/default_delete.rs → frontend/rust-lib/flowy-sync/src/client_document/extensions/delete/default_delete.rs


+ 0 - 0
shared-lib/flowy-sync/src/client_document/extensions/delete/mod.rs → frontend/rust-lib/flowy-sync/src/client_document/extensions/delete/mod.rs


+ 0 - 0
shared-lib/flowy-sync/src/client_document/extensions/delete/preserve_line_format_merge.rs → frontend/rust-lib/flowy-sync/src/client_document/extensions/delete/preserve_line_format_merge.rs


+ 0 - 0
shared-lib/flowy-sync/src/client_document/extensions/format/format_at_position.rs → frontend/rust-lib/flowy-sync/src/client_document/extensions/format/format_at_position.rs


+ 0 - 0
shared-lib/flowy-sync/src/client_document/extensions/format/mod.rs → frontend/rust-lib/flowy-sync/src/client_document/extensions/format/mod.rs


+ 0 - 0
shared-lib/flowy-sync/src/client_document/extensions/format/resolve_block_format.rs → frontend/rust-lib/flowy-sync/src/client_document/extensions/format/resolve_block_format.rs


+ 0 - 0
shared-lib/flowy-sync/src/client_document/extensions/format/resolve_inline_format.rs → frontend/rust-lib/flowy-sync/src/client_document/extensions/format/resolve_inline_format.rs


+ 0 - 0
shared-lib/flowy-sync/src/client_document/extensions/helper.rs → frontend/rust-lib/flowy-sync/src/client_document/extensions/helper.rs


+ 0 - 0
shared-lib/flowy-sync/src/client_document/extensions/insert/auto_exit_block.rs → frontend/rust-lib/flowy-sync/src/client_document/extensions/insert/auto_exit_block.rs


Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini