appflowy 3 лет назад
Родитель
Сommit
e55b79d3e6
100 измененных файлов с 998 добавлено и 1264 удалено
  1. 1 1
      .gitignore
  2. 148 82
      backend/Cargo.lock
  3. 6 4
      backend/Cargo.toml
  4. 9 8
      backend/src/application.rs
  5. 8 8
      backend/src/context.rs
  6. 1 1
      backend/src/entities/doc.rs
  7. 1 1
      backend/src/entities/token.rs
  8. 1 1
      backend/src/entities/workspace.rs
  9. 2 1
      backend/src/lib.rs
  10. 1 1
      backend/src/middleware/auth_middleware.rs
  11. 0 122
      backend/src/service/doc/edit/edit_actor.rs
  12. 0 259
      backend/src/service/doc/edit/editor.rs
  13. 0 5
      backend/src/service/doc/edit/mod.rs
  14. 0 153
      backend/src/service/doc/manager.rs
  15. 0 142
      backend/src/service/doc/ws_actor.rs
  16. 0 45
      backend/src/service/ws/router.rs
  17. 3 3
      backend/src/services/app/app.rs
  18. 0 0
      backend/src/services/app/mod.rs
  19. 3 3
      backend/src/services/app/router.rs
  20. 1 1
      backend/src/services/app/sql_builder.rs
  21. 19 3
      backend/src/services/doc/crud.rs
  22. 65 0
      backend/src/services/doc/editor.rs
  23. 132 0
      backend/src/services/doc/manager.rs
  24. 2 1
      backend/src/services/doc/mod.rs
  25. 4 16
      backend/src/services/doc/router.rs
  26. 132 0
      backend/src/services/doc/ws_actor.rs
  27. 0 0
      backend/src/services/log.rs
  28. 0 1
      backend/src/services/mod.rs
  29. 0 0
      backend/src/services/trash/mod.rs
  30. 2 2
      backend/src/services/trash/router.rs
  31. 2 2
      backend/src/services/trash/trash.rs
  32. 2 4
      backend/src/services/user/auth.rs
  33. 0 0
      backend/src/services/user/logged_user.rs
  34. 0 0
      backend/src/services/user/mod.rs
  35. 2 2
      backend/src/services/user/router.rs
  36. 7 6
      backend/src/services/user/user_default.rs
  37. 0 0
      backend/src/services/user/utils.rs
  38. 0 0
      backend/src/services/util.rs
  39. 0 0
      backend/src/services/view/mod.rs
  40. 4 4
      backend/src/services/view/router.rs
  41. 1 1
      backend/src/services/view/sql_builder.rs
  42. 5 5
      backend/src/services/view/view.rs
  43. 0 0
      backend/src/services/workspace/mod.rs
  44. 2 2
      backend/src/services/workspace/router.rs
  45. 1 1
      backend/src/services/workspace/sql_builder.rs
  46. 2 2
      backend/src/services/workspace/workspace.rs
  47. 6 7
      backend/src/web_socket/biz_handler.rs
  48. 1 1
      backend/src/web_socket/entities/connect.rs
  49. 6 6
      backend/src/web_socket/entities/message.rs
  50. 0 0
      backend/src/web_socket/entities/mod.rs
  51. 0 0
      backend/src/web_socket/mod.rs
  52. 63 0
      backend/src/web_socket/router.rs
  53. 9 11
      backend/src/web_socket/ws_client.rs
  54. 1 1
      backend/src/web_socket/ws_server.rs
  55. 1 1
      backend/tests/api/auth.rs
  56. 2 2
      backend/tests/api/doc.rs
  57. 1 1
      backend/tests/api/workspace.rs
  58. 35 28
      backend/tests/document/edit_script.rs
  59. 6 6
      backend/tests/document/edit_test.rs
  60. 2 2
      backend/tests/document/mod.rs
  61. 4 4
      backend/tests/util/helper.rs
  62. 2 2
      frontend/app_flowy/ios/Runner.xcodeproj/project.pbxproj
  63. 1 1
      frontend/app_flowy/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
  64. 4 4
      frontend/app_flowy/lib/user/application/sign_in_bloc.dart
  65. 9 9
      frontend/app_flowy/lib/user/application/sign_in_bloc.freezed.dart
  66. 4 4
      frontend/app_flowy/lib/user/application/sign_up_bloc.dart
  67. 9 9
      frontend/app_flowy/lib/user/application/sign_up_bloc.freezed.dart
  68. 3 3
      frontend/app_flowy/lib/user/domain/auth_state.dart
  69. 18 18
      frontend/app_flowy/lib/user/domain/auth_state.freezed.dart
  70. 6 6
      frontend/app_flowy/lib/user/domain/i_auth.dart
  71. 2 2
      frontend/app_flowy/lib/user/domain/i_splash.dart
  72. 3 6
      frontend/app_flowy/lib/user/infrastructure/deps_resolver.dart
  73. 6 6
      frontend/app_flowy/lib/user/infrastructure/i_auth_impl.dart
  74. 4 4
      frontend/app_flowy/lib/user/infrastructure/i_splash_impl.dart
  75. 2 2
      frontend/app_flowy/lib/user/infrastructure/network_monitor.dart
  76. 5 5
      frontend/app_flowy/lib/user/infrastructure/repos/auth_repo.dart
  77. 3 3
      frontend/app_flowy/lib/user/presentation/sign_in_screen.dart
  78. 3 3
      frontend/app_flowy/lib/user/presentation/sign_up_screen.dart
  79. 3 4
      frontend/app_flowy/lib/user/presentation/skip_log_in_screen.dart
  80. 1 1
      frontend/app_flowy/lib/user/presentation/splash_screen.dart
  81. 1 1
      frontend/app_flowy/lib/user/presentation/welcome_screen.dart
  82. 5 5
      frontend/app_flowy/lib/workspace/application/app/app_bloc.dart
  83. 9 9
      frontend/app_flowy/lib/workspace/application/app/app_bloc.freezed.dart
  84. 4 4
      frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart
  85. 15 15
      frontend/app_flowy/lib/workspace/application/doc/doc_bloc.freezed.dart
  86. 4 4
      frontend/app_flowy/lib/workspace/application/doc/share_bloc.dart
  87. 18 18
      frontend/app_flowy/lib/workspace/application/doc/share_bloc.freezed.dart
  88. 1 3
      frontend/app_flowy/lib/workspace/application/edit_pannel/edit_pannel_bloc.dart
  89. 3 2
      frontend/app_flowy/lib/workspace/application/home/home_listen_bloc.dart
  90. 5 6
      frontend/app_flowy/lib/workspace/application/menu/menu_bloc.dart
  91. 33 33
      frontend/app_flowy/lib/workspace/application/menu/menu_bloc.freezed.dart
  92. 4 5
      frontend/app_flowy/lib/workspace/application/menu/menu_user_bloc.dart
  93. 5 5
      frontend/app_flowy/lib/workspace/application/trash/trash_bloc.dart
  94. 9 9
      frontend/app_flowy/lib/workspace/application/trash/trash_bloc.freezed.dart
  95. 5 5
      frontend/app_flowy/lib/workspace/application/view/view_bloc.dart
  96. 36 36
      frontend/app_flowy/lib/workspace/application/view/view_bloc.freezed.dart
  97. 5 5
      frontend/app_flowy/lib/workspace/application/workspace/welcome_bloc.dart
  98. 30 30
      frontend/app_flowy/lib/workspace/application/workspace/welcome_bloc.freezed.dart
  99. 7 9
      frontend/app_flowy/lib/workspace/domain/i_app.dart
  100. 5 5
      frontend/app_flowy/lib/workspace/domain/i_doc.dart

+ 1 - 1
.gitignore

@@ -13,5 +13,5 @@ Cargo.lock
 **/target/
 **/*.db
 .idea/
-/flowy-test/
+**/temp/**
 .ruby-version

+ 148 - 82
backend/Cargo.lock

@@ -455,18 +455,20 @@ dependencies = [
  "config",
  "dashmap",
  "derive_more",
+ "flowy-collaboration",
+ "flowy-core-data-model",
  "flowy-document",
- "flowy-document-infra",
+ "flowy-net",
  "flowy-sdk",
  "flowy-test",
  "flowy-user",
- "flowy-user-infra",
- "flowy-workspace-infra",
+ "flowy-user-data-model",
  "futures",
  "futures-core",
  "futures-util",
  "jsonwebtoken",
  "lazy_static",
+ "lib-infra",
  "lib-ot",
  "lib-ws",
  "linkify",
@@ -505,8 +507,9 @@ dependencies = [
  "bytes",
  "config",
  "derive_more",
- "flowy-user-infra",
- "flowy-workspace-infra",
+ "flowy-collaboration",
+ "flowy-core-data-model",
+ "flowy-user-data-model",
  "hyper",
  "lazy_static",
  "log",
@@ -668,9 +671,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
 
 [[package]]
 name = "bytes"
-version = "1.0.1"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
+checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
 dependencies = [
  "serde",
 ]
@@ -1148,6 +1151,15 @@ dependencies = [
  "backtrace",
 ]
 
+[[package]]
+name = "error-code"
+version = "0.1.0"
+dependencies = [
+ "derive_more",
+ "flowy-derive",
+ "protobuf",
+]
+
 [[package]]
 name = "eyre"
 version = "0.6.5"
@@ -1195,6 +1207,87 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "flowy-collaboration"
+version = "0.1.0"
+dependencies = [
+ "async-stream",
+ "bytes",
+ "chrono",
+ "dashmap",
+ "flowy-derive",
+ "futures",
+ "lib-infra",
+ "lib-ot",
+ "log",
+ "md5",
+ "parking_lot",
+ "protobuf",
+ "serde",
+ "strum",
+ "strum_macros",
+ "tokio",
+ "tracing",
+ "url",
+]
+
+[[package]]
+name = "flowy-core"
+version = "0.1.0"
+dependencies = [
+ "backend-service",
+ "bincode",
+ "bytes",
+ "chrono",
+ "crossbeam",
+ "crossbeam-utils",
+ "dart-notify",
+ "derive_more",
+ "diesel",
+ "diesel_derives",
+ "flowy-collaboration",
+ "flowy-core-data-model",
+ "flowy-database",
+ "flowy-derive",
+ "flowy-document",
+ "flowy-error",
+ "flowy-net",
+ "futures",
+ "futures-core",
+ "lazy_static",
+ "lib-dispatch",
+ "lib-infra",
+ "lib-ot",
+ "lib-sqlite",
+ "log",
+ "parking_lot",
+ "pin-project 1.0.8",
+ "protobuf",
+ "serde",
+ "strum",
+ "strum_macros",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "flowy-core-data-model"
+version = "0.1.0"
+dependencies = [
+ "bytes",
+ "chrono",
+ "derive_more",
+ "error-code",
+ "flowy-collaboration",
+ "flowy-derive",
+ "log",
+ "protobuf",
+ "strum",
+ "strum_macros",
+ "unicode-segmentation",
+ "uuid",
+]
+
 [[package]]
 name = "flowy-database"
 version = "0.1.0"
@@ -1202,7 +1295,9 @@ dependencies = [
  "diesel",
  "diesel_derives",
  "diesel_migrations",
+ "lazy_static",
  "lib-sqlite",
+ "log",
 ]
 
 [[package]]
@@ -1230,11 +1325,13 @@ dependencies = [
  "derive_more",
  "diesel",
  "diesel_derives",
+ "flowy-collaboration",
  "flowy-database",
  "flowy-derive",
- "flowy-document-infra",
+ "flowy-error",
  "futures",
  "futures-core",
+ "futures-util",
  "lazy_static",
  "lib-dispatch",
  "lib-infra",
@@ -1255,22 +1352,40 @@ dependencies = [
 ]
 
 [[package]]
-name = "flowy-document-infra"
+name = "flowy-error"
 version = "0.1.0"
 dependencies = [
+ "backend-service",
  "bytes",
- "chrono",
+ "error-code",
+ "flowy-collaboration",
+ "flowy-database",
  "flowy-derive",
+ "lib-dispatch",
  "lib-ot",
- "log",
- "md5",
+ "lib-sqlite",
+ "protobuf",
+ "r2d2",
+ "serde_json",
+]
+
+[[package]]
+name = "flowy-net"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "bytes",
+ "flowy-derive",
+ "flowy-error",
+ "lib-dispatch",
+ "lib-infra",
+ "lib-ws",
+ "parking_lot",
  "protobuf",
- "serde",
  "strum",
  "strum_macros",
  "tokio",
  "tracing",
- "url",
 ]
 
 [[package]]
@@ -1280,11 +1395,12 @@ dependencies = [
  "backend-service",
  "bytes",
  "color-eyre",
+ "flowy-collaboration",
+ "flowy-core",
  "flowy-database",
  "flowy-document",
- "flowy-document-infra",
+ "flowy-net",
  "flowy-user",
- "flowy-workspace",
  "futures-core",
  "lib-dispatch",
  "lib-infra",
@@ -1304,17 +1420,20 @@ dependencies = [
  "bincode",
  "bytes",
  "claim",
+ "flowy-collaboration",
+ "flowy-core",
  "flowy-document",
- "flowy-document-infra",
+ "flowy-net",
  "flowy-sdk",
  "flowy-user",
- "flowy-workspace",
  "futures-util",
  "lib-dispatch",
  "lib-infra",
+ "lib-ot",
  "log",
  "protobuf",
  "serde",
+ "serde_json",
  "thread-id",
  "tokio",
 ]
@@ -1326,18 +1445,20 @@ dependencies = [
  "backend-service",
  "bytes",
  "dart-notify",
+ "dashmap",
  "derive_more",
  "diesel",
  "diesel_derives",
  "flowy-database",
  "flowy-derive",
- "flowy-user-infra",
+ "flowy-error",
+ "flowy-net",
+ "flowy-user-data-model",
  "futures-core",
  "lazy_static",
  "lib-dispatch",
  "lib-infra",
  "lib-sqlite",
- "lib-ws",
  "log",
  "once_cell",
  "parking_lot",
@@ -1355,11 +1476,12 @@ dependencies = [
 ]
 
 [[package]]
-name = "flowy-user-infra"
+name = "flowy-user-data-model"
 version = "0.1.0"
 dependencies = [
  "bytes",
  "derive_more",
+ "error-code",
  "fancy-regex",
  "flowy-derive",
  "lazy_static",
@@ -1369,60 +1491,6 @@ dependencies = [
  "validator",
 ]
 
-[[package]]
-name = "flowy-workspace"
-version = "0.1.0"
-dependencies = [
- "backend-service",
- "bincode",
- "bytes",
- "chrono",
- "crossbeam",
- "crossbeam-utils",
- "dart-notify",
- "derive_more",
- "diesel",
- "diesel_derives",
- "flowy-database",
- "flowy-derive",
- "flowy-document",
- "flowy-document-infra",
- "flowy-workspace-infra",
- "futures",
- "futures-core",
- "lazy_static",
- "lib-dispatch",
- "lib-infra",
- "lib-ot",
- "lib-sqlite",
- "log",
- "parking_lot",
- "pin-project 1.0.8",
- "protobuf",
- "serde",
- "strum",
- "strum_macros",
- "tokio",
- "tracing",
-]
-
-[[package]]
-name = "flowy-workspace-infra"
-version = "0.1.0"
-dependencies = [
- "bytes",
- "chrono",
- "derive_more",
- "flowy-derive",
- "flowy-document-infra",
- "log",
- "protobuf",
- "strum",
- "strum_macros",
- "unicode-segmentation",
- "uuid",
-]
-
 [[package]]
 name = "fnv"
 version = "1.0.7"
@@ -1933,16 +2001,9 @@ version = "0.1.0"
 dependencies = [
  "bytes",
  "chrono",
- "diesel",
- "diesel_derives",
- "diesel_migrations",
- "flowy-derive",
  "futures-core",
- "lazy_static",
- "lib-sqlite",
  "log",
  "pin-project 1.0.8",
- "protobuf",
  "rand",
  "tokio",
  "uuid",
@@ -1972,13 +2033,18 @@ version = "0.1.0"
 dependencies = [
  "bytecount",
  "bytes",
+ "dashmap",
  "derive_more",
+ "flowy-derive",
  "lazy_static",
  "log",
+ "md5",
+ "protobuf",
  "serde",
  "serde_json",
  "strum",
  "strum_macros",
+ "tokio",
  "tracing",
 ]
 

+ 6 - 4
backend/Cargo.toml

@@ -59,11 +59,12 @@ pin-project = "1.0.0"
 byteorder = {version = "1.3.4"}
 async-stream = "0.3.2"
 
-flowy-user-infra = { path = "../shared-lib/flowy-user-infra" }
-flowy-workspace-infra = { path = "../shared-lib/flowy-workspace-infra" }
-flowy-document-infra = { path = "../shared-lib/flowy-document-infra" }
+flowy-user-data-model = { path = "../shared-lib/flowy-user-data-model" }
+flowy-core-data-model = { path = "../shared-lib/flowy-core-data-model" }
+flowy-collaboration = { path = "../shared-lib/flowy-collaboration" }
 lib-ws = { path = "../shared-lib/lib-ws" }
 lib-ot = { path = "../shared-lib/lib-ot" }
+lib-infra = { path = "../shared-lib/lib-infra" }
 backend-service = { path = "../shared-lib/backend-service", features = ["http_server"] }
 
 ormx = { version = "0.7", features = ["postgres"]}
@@ -100,6 +101,7 @@ futures-util = "0.3.15"
 backend = { path = ".", features = ["flowy_test"]}
 flowy-sdk = { path = "../frontend/rust-lib/flowy-sdk", features = ["http_server"] }
 flowy-user = { path = "../frontend/rust-lib/flowy-user", features = ["http_server"] }
-flowy-document = { path = "../frontend/rust-lib/flowy-document", features = ["flowy_test", "http_server"] }
+flowy-document = { path = "../frontend/rust-lib/flowy-document", features = ["flowy_unit_test", "http_server"] }
 flowy-test = { path = "../frontend/rust-lib/flowy-test" }
+flowy-net = { path = "../frontend/rust-lib/flowy-net", features = ["http_server"] }
 

+ 9 - 8
backend/src/application.rs

@@ -1,9 +1,8 @@
-use std::{net::TcpListener, time::Duration};
-
 use actix::Actor;
 use actix_identity::{CookieIdentityPolicy, IdentityService};
 use actix_web::{dev::Server, middleware, web, web::Data, App, HttpServer, Scope};
 use sqlx::{postgres::PgPoolOptions, PgPool};
+use std::{net::TcpListener, time::Duration};
 use tokio::time::interval;
 
 use crate::{
@@ -13,16 +12,15 @@ use crate::{
         Settings,
     },
     context::AppContext,
-    service::{
+    services::{
         app::router as app,
         doc::router as doc,
         trash::router as trash,
         user::router as user,
         view::router as view,
         workspace::router as workspace,
-        ws,
-        ws::WsServer,
     },
+    web_socket::WsServer,
 };
 
 pub struct Application {
@@ -61,7 +59,7 @@ pub fn run(listener: TcpListener, app_ctx: AppContext) -> Result<Server, std::io
             .app_data(app_ctx.ws_server.clone())
             .app_data(app_ctx.pg_pool.clone())
             .app_data(app_ctx.ws_bizs.clone())
-            .app_data(app_ctx.doc_biz.clone())
+            .app_data(app_ctx.document_core.clone())
     })
     .listen(listener)?
     .run();
@@ -75,7 +73,7 @@ async fn period_check(_pool: Data<PgPool>) {
     }
 }
 
-fn ws_scope() -> Scope { web::scope("/ws").service(ws::router::establish_ws_connection) }
+fn ws_scope() -> Scope { web::scope("/ws").service(crate::web_socket::router::establish_ws_connection) }
 
 fn user_scope() -> Scope {
     // https://developer.mozilla.org/en-US/docs/Web/HTTP
@@ -124,6 +122,9 @@ fn user_scope() -> Scope {
             .route(web::delete().to(trash::delete_handler))
             .route(web::get().to(trash::read_handler))
         )
+        .service(web::resource("/sync")
+            .route(web::post().to(trash::create_handler))
+        )
         // password
         .service(web::resource("/password_change")
             .route(web::post().to(user::change_password))
@@ -131,7 +132,7 @@ fn user_scope() -> Scope {
 }
 
 pub async fn init_app_context(configuration: &Settings) -> AppContext {
-    let _ = crate::service::log::Builder::new("flowy-server")
+    let _ = crate::services::log::Builder::new("flowy-server")
         .env_filter("Trace")
         .build();
     let pg_pool = get_connection_pool(&configuration.database)

+ 8 - 8
backend/src/context.rs

@@ -1,10 +1,10 @@
-use crate::service::{
-    doc::manager::DocBiz,
-    ws::{WsBizHandlers, WsServer},
+use crate::{
+    services::doc::manager::DocumentCore,
+    web_socket::{WsBizHandlers, WsServer},
 };
 use actix::Addr;
 use actix_web::web::Data;
-use lib_ws::WsModule;
+use lib_ws::WSModule;
 use sqlx::PgPool;
 use std::sync::Arc;
 
@@ -13,7 +13,7 @@ pub struct AppContext {
     pub ws_server: Data<Addr<WsServer>>,
     pub pg_pool: Data<PgPool>,
     pub ws_bizs: Data<WsBizHandlers>,
-    pub doc_biz: Data<Arc<DocBiz>>,
+    pub document_core: Data<Arc<DocumentCore>>,
 }
 
 impl AppContext {
@@ -22,14 +22,14 @@ impl AppContext {
         let pg_pool = Data::new(db_pool);
 
         let mut ws_bizs = WsBizHandlers::new();
-        let doc_biz = Arc::new(DocBiz::new(pg_pool.clone()));
-        ws_bizs.register(WsModule::Doc, doc_biz.clone());
+        let document_core = Arc::new(DocumentCore::new(pg_pool.clone()));
+        ws_bizs.register(WSModule::Doc, document_core.clone());
 
         AppContext {
             ws_server,
             pg_pool,
             ws_bizs: Data::new(ws_bizs),
-            doc_biz: Data::new(doc_biz),
+            document_core: Data::new(document_core),
         }
     }
 }

+ 1 - 1
backend/src/entities/doc.rs

@@ -1,4 +1,4 @@
-use flowy_document_infra::protobuf::Doc;
+use flowy_collaboration::protobuf::Doc;
 
 pub(crate) const DOC_TABLE: &str = "doc_table";
 

+ 1 - 1
backend/src/entities/token.rs

@@ -74,7 +74,7 @@ impl Token {
     }
 }
 
-use crate::service::user::EXPIRED_DURATION_DAYS;
+use crate::services::user::EXPIRED_DURATION_DAYS;
 use actix_web::{dev::Payload, FromRequest, HttpRequest};
 use backend_service::configuration::HEADER_TOKEN;
 use futures::future::{ready, Ready};

+ 1 - 1
backend/src/entities/workspace.rs

@@ -1,5 +1,5 @@
 use chrono::Utc;
-use flowy_workspace_infra::protobuf::{App, RepeatedView, Trash, TrashType, View, ViewType, Workspace};
+use flowy_core_data_model::protobuf::{App, RepeatedView, Trash, TrashType, View, ViewType, Workspace};
 use protobuf::ProtobufEnum;
 
 pub(crate) const WORKSPACE_TABLE: &str = "workspace_table";

+ 2 - 1
backend/src/lib.rs

@@ -3,5 +3,6 @@ pub mod config;
 pub mod context;
 mod entities;
 mod middleware;
-pub mod service;
+pub mod services;
 mod sqlx_ext;
+pub mod web_socket;

+ 1 - 1
backend/src/middleware/auth_middleware.rs

@@ -1,4 +1,4 @@
-use crate::service::user::{LoggedUser, AUTHORIZED_USERS};
+use crate::services::user::{LoggedUser, AUTHORIZED_USERS};
 use actix_service::{Service, Transform};
 use actix_web::{
     dev::{ServiceRequest, ServiceResponse},

+ 0 - 122
backend/src/service/doc/edit/edit_actor.rs

@@ -1,122 +0,0 @@
-use crate::service::{
-    doc::edit::ServerDocEditor,
-    ws::{entities::Socket, WsUser},
-};
-use actix_web::web::Data;
-use async_stream::stream;
-use backend_service::errors::{internal_error, Result as DocResult, ServerError};
-use flowy_document_infra::protobuf::{Doc, Revision};
-use futures::stream::StreamExt;
-use sqlx::PgPool;
-use std::sync::{atomic::Ordering::SeqCst, Arc};
-use tokio::{
-    sync::{mpsc, oneshot},
-    task::spawn_blocking,
-};
-
-#[derive(Clone)]
-pub struct EditUser {
-    user: Arc<WsUser>,
-    pub(crate) socket: Socket,
-}
-
-impl EditUser {
-    pub fn id(&self) -> String { self.user.id().to_string() }
-}
-
-#[derive(Debug)]
-pub enum EditMsg {
-    Revision {
-        user: Arc<WsUser>,
-        socket: Socket,
-        revision: Revision,
-        ret: oneshot::Sender<DocResult<()>>,
-    },
-    DocumentJson {
-        ret: oneshot::Sender<DocResult<String>>,
-    },
-    DocumentRevId {
-        ret: oneshot::Sender<DocResult<i64>>,
-    },
-    NewDocUser {
-        user: Arc<WsUser>,
-        socket: Socket,
-        rev_id: i64,
-        ret: oneshot::Sender<DocResult<()>>,
-    },
-}
-
-pub struct EditDocActor {
-    receiver: Option<mpsc::Receiver<EditMsg>>,
-    edit_doc: Arc<ServerDocEditor>,
-    pg_pool: Data<PgPool>,
-}
-
-impl EditDocActor {
-    pub fn new(receiver: mpsc::Receiver<EditMsg>, doc: Doc, pg_pool: Data<PgPool>) -> Result<Self, ServerError> {
-        let edit_doc = Arc::new(ServerDocEditor::new(doc)?);
-        Ok(Self {
-            receiver: Some(receiver),
-            edit_doc,
-            pg_pool,
-        })
-    }
-
-    pub async fn run(mut self) {
-        let mut receiver = self
-            .receiver
-            .take()
-            .expect("DocActor's receiver should only take one time");
-
-        let stream = stream! {
-            loop {
-                match receiver.recv().await {
-                    Some(msg) => yield msg,
-                    None => break,
-                }
-            }
-        };
-        stream.for_each(|msg| self.handle_message(msg)).await;
-    }
-
-    async fn handle_message(&self, msg: EditMsg) {
-        match msg {
-            EditMsg::Revision {
-                user,
-                socket,
-                revision,
-                ret,
-            } => {
-                let user = EditUser {
-                    user: user.clone(),
-                    socket: socket.clone(),
-                };
-                let _ = ret.send(self.edit_doc.apply_revision(user, revision, self.pg_pool.clone()).await);
-            },
-            EditMsg::DocumentJson { ret } => {
-                let edit_context = self.edit_doc.clone();
-                let json = spawn_blocking(move || edit_context.document_json())
-                    .await
-                    .map_err(internal_error);
-                let _ = ret.send(json);
-            },
-            EditMsg::DocumentRevId { ret } => {
-                let edit_context = self.edit_doc.clone();
-                let _ = ret.send(Ok(edit_context.rev_id.load(SeqCst)));
-            },
-            EditMsg::NewDocUser {
-                user,
-                socket,
-                rev_id,
-                ret,
-            } => {
-                log::debug!("Receive new doc user: {:?}, rev_id: {}", user, rev_id);
-                let user = EditUser {
-                    user: user.clone(),
-                    socket: socket.clone(),
-                };
-                let _ = ret.send(self.edit_doc.new_doc_user(user, rev_id).await);
-            },
-        }
-    }
-}

+ 0 - 259
backend/src/service/doc/edit/editor.rs

@@ -1,259 +0,0 @@
-use crate::service::{
-    doc::{edit::edit_actor::EditUser, update_doc},
-    util::md5,
-    ws::{entities::Socket, WsMessageAdaptor},
-};
-use actix_web::web::Data;
-use backend_service::errors::{internal_error, ServerError};
-use dashmap::DashMap;
-use flowy_document_infra::{
-    core::Document,
-    entities::ws::{WsDataType, WsDocumentData},
-    protobuf::{Doc, RevId, RevType, Revision, RevisionRange, UpdateDocParams},
-};
-use lib_ot::core::{Delta, OperationTransformable};
-use parking_lot::RwLock;
-use protobuf::Message;
-use sqlx::PgPool;
-use std::{
-    cmp::Ordering,
-    sync::{
-        atomic::{AtomicI64, Ordering::SeqCst},
-        Arc,
-    },
-    time::Duration,
-};
-
-pub struct ServerDocEditor {
-    pub doc_id: String,
-    pub rev_id: AtomicI64,
-    document: Arc<RwLock<Document>>,
-    users: DashMap<String, EditUser>,
-}
-
-impl ServerDocEditor {
-    pub fn new(doc: Doc) -> Result<Self, ServerError> {
-        let delta = Delta::from_bytes(&doc.data).map_err(internal_error)?;
-        let document = Arc::new(RwLock::new(Document::from_delta(delta)));
-        let users = DashMap::new();
-        Ok(Self {
-            doc_id: doc.id.clone(),
-            rev_id: AtomicI64::new(doc.rev_id),
-            document,
-            users,
-        })
-    }
-
-    #[tracing::instrument(
-        level = "debug",
-        skip(self, user),
-        fields(
-            user_id = %user.id(),
-            rev_id = %rev_id,
-        )
-    )]
-    pub async fn new_doc_user(&self, user: EditUser, rev_id: i64) -> Result<(), ServerError> {
-        self.users.insert(user.id(), user.clone());
-        let cur_rev_id = self.rev_id.load(SeqCst);
-        match cur_rev_id.cmp(&rev_id) {
-            Ordering::Less => {
-                user.socket
-                    .do_send(mk_pull_message(&self.doc_id, next(cur_rev_id), rev_id))
-                    .map_err(internal_error)?;
-            },
-            Ordering::Equal => {},
-            Ordering::Greater => {
-                let doc_delta = self.document.read().delta().clone();
-                let cli_revision = self.mk_revision(rev_id, doc_delta);
-                let ws_cli_revision = mk_push_message(&self.doc_id, cli_revision);
-                user.socket.do_send(ws_cli_revision).map_err(internal_error)?;
-            },
-        }
-
-        Ok(())
-    }
-
-    #[tracing::instrument(
-        level = "debug",
-        skip(self, user, pg_pool, revision),
-        fields(
-            cur_rev_id = %self.rev_id.load(SeqCst),
-            base_rev_id = %revision.base_rev_id,
-            rev_id = %revision.rev_id,
-        ),
-        err
-    )]
-    pub async fn apply_revision(
-        &self,
-        user: EditUser,
-        revision: Revision,
-        pg_pool: Data<PgPool>,
-    ) -> Result<(), ServerError> {
-        self.users.insert(user.id(), user.clone());
-        let cur_rev_id = self.rev_id.load(SeqCst);
-        match cur_rev_id.cmp(&revision.rev_id) {
-            Ordering::Less => {
-                let next_rev_id = next(cur_rev_id);
-                if cur_rev_id == revision.base_rev_id || next_rev_id == revision.base_rev_id {
-                    // The rev is in the right order, just compose it.
-                    let _ = self.compose_revision(&revision, pg_pool).await?;
-                    let _ = send_acked_msg(&user.socket, &revision)?;
-                } else {
-                    // The server document is outdated, pull the missing revision from the client.
-                    let _ = send_pull_message(&user.socket, &self.doc_id, next_rev_id, revision.rev_id)?;
-                }
-            },
-            Ordering::Equal => {
-                // Do nothing
-                log::warn!("Applied revision rev_id is the same as cur_rev_id");
-            },
-            Ordering::Greater => {
-                // The client document is outdated. Transform the client revision delta and then
-                // send the prime delta to the client. Client should compose the this prime
-                // delta.
-                let cli_revision = self.transform_revision(&revision)?;
-                let _ = send_push_message(&user.socket, &self.doc_id, cli_revision)?;
-            },
-        }
-        Ok(())
-    }
-
-    pub fn document_json(&self) -> String { self.document.read().to_json() }
-
-    async fn compose_revision(&self, revision: &Revision, pg_pool: Data<PgPool>) -> Result<(), ServerError> {
-        let delta = Delta::from_bytes(&revision.delta_data).map_err(internal_error)?;
-        let _ = self.compose_delta(delta)?;
-        let _ = self.rev_id.fetch_update(SeqCst, SeqCst, |_e| Some(revision.rev_id));
-        let _ = self.save_revision(&revision, pg_pool).await?;
-        Ok(())
-    }
-
-    #[tracing::instrument(level = "debug", skip(self, revision))]
-    fn transform_revision(&self, revision: &Revision) -> Result<Revision, ServerError> {
-        let cli_delta = Delta::from_bytes(&revision.delta_data).map_err(internal_error)?;
-        let (cli_prime, server_prime) = self
-            .document
-            .read()
-            .delta()
-            .transform(&cli_delta)
-            .map_err(internal_error)?;
-
-        let _ = self.compose_delta(server_prime)?;
-        let cli_revision = self.mk_revision(revision.rev_id, cli_prime);
-        Ok(cli_revision)
-    }
-
-    fn mk_revision(&self, base_rev_id: i64, delta: Delta) -> Revision {
-        let delta_data = delta.to_bytes().to_vec();
-        let md5 = md5(&delta_data);
-        Revision {
-            base_rev_id,
-            rev_id: self.rev_id.load(SeqCst),
-            delta_data,
-            md5,
-            doc_id: self.doc_id.to_string(),
-            ty: RevType::Remote,
-            ..Default::default()
-        }
-    }
-
-    #[tracing::instrument(
-        level = "debug",
-        skip(self, delta),
-        fields(
-            revision_delta = %delta.to_json(),
-            result,
-        )
-    )]
-    fn compose_delta(&self, delta: Delta) -> Result<(), ServerError> {
-        if delta.is_empty() {
-            log::warn!("Composed delta is empty");
-        }
-
-        match self.document.try_write_for(Duration::from_millis(300)) {
-            None => {
-                log::error!("Failed to acquire write lock of document");
-            },
-            Some(mut write_guard) => {
-                let _ = write_guard.compose_delta(delta).map_err(internal_error)?;
-                tracing::Span::current().record("result", &write_guard.to_json().as_str());
-            },
-        }
-        Ok(())
-    }
-
-    #[tracing::instrument(level = "debug", skip(self, revision, pg_pool), err)]
-    async fn save_revision(&self, revision: &Revision, pg_pool: Data<PgPool>) -> Result<(), ServerError> {
-        // Opti: save with multiple revisions
-        let mut params = UpdateDocParams::new();
-        params.set_doc_id(self.doc_id.clone());
-        params.set_data(self.document.read().to_json());
-        params.set_rev_id(revision.rev_id);
-        let _ = update_doc(pg_pool.get_ref(), params).await?;
-        Ok(())
-    }
-}
-
-#[tracing::instrument(level = "debug", skip(socket, doc_id, revision), err)]
-fn send_push_message(socket: &Socket, doc_id: &str, revision: Revision) -> Result<(), ServerError> {
-    let msg = mk_push_message(doc_id, revision);
-    socket.try_send(msg).map_err(internal_error)
-}
-
-fn mk_push_message(doc_id: &str, revision: Revision) -> WsMessageAdaptor {
-    let bytes = revision.write_to_bytes().unwrap();
-    let data = WsDocumentData {
-        doc_id: doc_id.to_string(),
-        ty: WsDataType::PushRev,
-        data: bytes,
-    };
-    data.into()
-}
-
-#[tracing::instrument(level = "debug", skip(socket, doc_id), err)]
-fn send_pull_message(socket: &Socket, doc_id: &str, from_rev_id: i64, to_rev_id: i64) -> Result<(), ServerError> {
-    let msg = mk_pull_message(doc_id, from_rev_id, to_rev_id);
-    socket.try_send(msg).map_err(internal_error)
-}
-
-fn mk_pull_message(doc_id: &str, from_rev_id: i64, to_rev_id: i64) -> WsMessageAdaptor {
-    let range = RevisionRange {
-        doc_id: doc_id.to_string(),
-        start: from_rev_id,
-        end: to_rev_id,
-        ..Default::default()
-    };
-
-    let bytes = range.write_to_bytes().unwrap();
-    let data = WsDocumentData {
-        doc_id: doc_id.to_string(),
-        ty: WsDataType::PullRev,
-        data: bytes,
-    };
-    data.into()
-}
-
-#[tracing::instrument(level = "debug", skip(socket, revision), err)]
-fn send_acked_msg(socket: &Socket, revision: &Revision) -> Result<(), ServerError> {
-    let msg = mk_acked_message(revision);
-    socket.try_send(msg).map_err(internal_error)
-}
-
-fn mk_acked_message(revision: &Revision) -> WsMessageAdaptor {
-    // let mut wtr = vec![];
-    // let _ = wtr.write_i64::<BigEndian>(revision.rev_id);
-    let mut rev_id = RevId::new();
-    rev_id.set_value(revision.rev_id);
-    let data = rev_id.write_to_bytes().unwrap();
-
-    let data = WsDocumentData {
-        doc_id: revision.doc_id.clone(),
-        ty: WsDataType::Acked,
-        data,
-    };
-
-    data.into()
-}
-
-#[inline]
-fn next(rev_id: i64) -> i64 { rev_id + 1 }

+ 0 - 5
backend/src/service/doc/edit/mod.rs

@@ -1,5 +0,0 @@
-pub(crate) mod edit_actor;
-mod editor;
-
-pub use edit_actor::*;
-pub use editor::*;

+ 0 - 153
backend/src/service/doc/manager.rs

@@ -1,153 +0,0 @@
-use crate::service::{
-    doc::{
-        edit::edit_actor::{EditDocActor, EditMsg},
-        read_doc,
-        ws_actor::{DocWsActor, DocWsMsg},
-    },
-    ws::{entities::Socket, WsBizHandler, WsClientData, WsUser},
-};
-use actix_web::web::Data;
-use backend_service::errors::{internal_error, Result as DocResult, ServerError};
-use dashmap::DashMap;
-use flowy_document_infra::protobuf::{Doc, DocIdentifier, Revision};
-use sqlx::PgPool;
-use std::sync::Arc;
-use tokio::{
-    sync::{mpsc, oneshot},
-    task::spawn_blocking,
-};
-
-pub struct DocBiz {
-    pub manager: Arc<DocManager>,
-    sender: mpsc::Sender<DocWsMsg>,
-    pg_pool: Data<PgPool>,
-}
-
-impl DocBiz {
-    pub fn new(pg_pool: Data<PgPool>) -> Self {
-        let manager = Arc::new(DocManager::new());
-        let (tx, rx) = mpsc::channel(100);
-        let actor = DocWsActor::new(rx, manager.clone());
-        tokio::task::spawn(actor.run());
-        Self {
-            manager,
-            sender: tx,
-            pg_pool,
-        }
-    }
-}
-
-impl WsBizHandler for DocBiz {
-    fn receive_data(&self, client_data: WsClientData) {
-        let (ret, rx) = oneshot::channel();
-        let sender = self.sender.clone();
-        let pool = self.pg_pool.clone();
-
-        actix_rt::spawn(async move {
-            let msg = DocWsMsg::ClientData { client_data, ret, pool };
-            match sender.send(msg).await {
-                Ok(_) => {},
-                Err(e) => log::error!("{}", e),
-            }
-            match rx.await {
-                Ok(_) => {},
-                Err(e) => log::error!("{:?}", e),
-            };
-        });
-    }
-}
-
-pub struct DocManager {
-    docs_map: DashMap<String, Arc<DocOpenHandle>>,
-}
-
-impl std::default::Default for DocManager {
-    fn default() -> Self {
-        Self {
-            docs_map: DashMap::new(),
-        }
-    }
-}
-
-impl DocManager {
-    pub fn new() -> Self { DocManager::default() }
-
-    pub async fn get(&self, doc_id: &str, pg_pool: Data<PgPool>) -> Result<Option<Arc<DocOpenHandle>>, ServerError> {
-        match self.docs_map.get(doc_id) {
-            None => {
-                let params = DocIdentifier {
-                    doc_id: doc_id.to_string(),
-                    ..Default::default()
-                };
-                let doc = read_doc(pg_pool.get_ref(), params).await?;
-                let handle = spawn_blocking(|| DocOpenHandle::new(doc, pg_pool))
-                    .await
-                    .map_err(internal_error)?;
-                let handle = Arc::new(handle?);
-                self.docs_map.insert(doc_id.to_string(), handle.clone());
-                Ok(Some(handle))
-            },
-            Some(ctx) => Ok(Some(ctx.clone())),
-        }
-    }
-}
-
-pub struct DocOpenHandle {
-    pub sender: mpsc::Sender<EditMsg>,
-}
-
-impl DocOpenHandle {
-    pub fn new(doc: Doc, pg_pool: Data<PgPool>) -> Result<Self, ServerError> {
-        let (sender, receiver) = mpsc::channel(100);
-        let actor = EditDocActor::new(receiver, doc, pg_pool)?;
-        tokio::task::spawn(actor.run());
-        Ok(Self { sender })
-    }
-
-    pub async fn add_user(&self, user: Arc<WsUser>, rev_id: i64, socket: Socket) -> Result<(), ServerError> {
-        let (ret, rx) = oneshot::channel();
-        let msg = EditMsg::NewDocUser {
-            user,
-            socket,
-            rev_id,
-            ret,
-        };
-        let _ = self.send(msg, rx).await?;
-        Ok(())
-    }
-
-    pub async fn apply_revision(
-        &self,
-        user: Arc<WsUser>,
-        socket: Socket,
-        revision: Revision,
-    ) -> Result<(), ServerError> {
-        let (ret, rx) = oneshot::channel();
-        let msg = EditMsg::Revision {
-            user,
-            socket,
-            revision,
-            ret,
-        };
-        let _ = self.send(msg, rx).await?;
-        Ok(())
-    }
-
-    pub async fn document_json(&self) -> DocResult<String> {
-        let (ret, rx) = oneshot::channel();
-        let msg = EditMsg::DocumentJson { ret };
-        self.send(msg, rx).await?
-    }
-
-    pub async fn rev_id(&self) -> DocResult<i64> {
-        let (ret, rx) = oneshot::channel();
-        let msg = EditMsg::DocumentRevId { ret };
-        self.send(msg, rx).await?
-    }
-
-    pub(crate) async fn send<T>(&self, msg: EditMsg, rx: oneshot::Receiver<T>) -> DocResult<T> {
-        let _ = self.sender.send(msg).await.map_err(internal_error)?;
-        let result = rx.await?;
-        Ok(result)
-    }
-}

+ 0 - 142
backend/src/service/doc/ws_actor.rs

@@ -1,142 +0,0 @@
-use crate::service::{
-    doc::manager::{DocManager, DocOpenHandle},
-    util::{md5, parse_from_bytes},
-    ws::{entities::Socket, WsClientData, WsUser},
-};
-use actix_rt::task::spawn_blocking;
-use actix_web::web::Data;
-use async_stream::stream;
-use backend_service::errors::{internal_error, Result as DocResult, ServerError};
-use flowy_document_infra::protobuf::{NewDocUser, Revision, WsDataType, WsDocumentData};
-use futures::stream::StreamExt;
-use sqlx::PgPool;
-use std::sync::Arc;
-use tokio::sync::{mpsc, oneshot};
-
-pub enum DocWsMsg {
-    ClientData {
-        client_data: WsClientData,
-        pool: Data<PgPool>,
-        ret: oneshot::Sender<DocResult<()>>,
-    },
-}
-
-pub struct DocWsActor {
-    receiver: Option<mpsc::Receiver<DocWsMsg>>,
-    doc_manager: Arc<DocManager>,
-}
-
-impl DocWsActor {
-    pub fn new(receiver: mpsc::Receiver<DocWsMsg>, manager: Arc<DocManager>) -> Self {
-        Self {
-            receiver: Some(receiver),
-            doc_manager: manager,
-        }
-    }
-
-    pub async fn run(mut self) {
-        let mut receiver = self
-            .receiver
-            .take()
-            .expect("DocActor's receiver should only take one time");
-
-        let stream = stream! {
-            loop {
-                match receiver.recv().await {
-                    Some(msg) => yield msg,
-                    None => break,
-                }
-            }
-        };
-
-        stream.for_each(|msg| self.handle_message(msg)).await;
-    }
-
-    async fn handle_message(&self, msg: DocWsMsg) {
-        match msg {
-            DocWsMsg::ClientData { client_data, pool, ret } => {
-                let _ = ret.send(self.handle_client_data(client_data, pool).await);
-            },
-        }
-    }
-
-    async fn handle_client_data(&self, client_data: WsClientData, pool: Data<PgPool>) -> DocResult<()> {
-        let WsClientData { user, socket, data } = client_data;
-        let document_data = spawn_blocking(move || {
-            let document_data: WsDocumentData = parse_from_bytes(&data)?;
-            DocResult::Ok(document_data)
-        })
-        .await
-        .map_err(internal_error)??;
-
-        let data = document_data.data;
-
-        match document_data.ty {
-            WsDataType::Acked => Ok(()),
-            WsDataType::PushRev => self.apply_pushed_rev(user, socket, data, pool).await,
-            WsDataType::NewDocUser => self.add_doc_user(user, socket, data, pool).await,
-            WsDataType::PullRev => Ok(()),
-            WsDataType::Conflict => Ok(()),
-        }
-    }
-
-    async fn add_doc_user(
-        &self,
-        user: Arc<WsUser>,
-        socket: Socket,
-        data: Vec<u8>,
-        pool: Data<PgPool>,
-    ) -> DocResult<()> {
-        let doc_user = spawn_blocking(move || {
-            let user: NewDocUser = parse_from_bytes(&data)?;
-            DocResult::Ok(user)
-        })
-        .await
-        .map_err(internal_error)??;
-        if let Some(handle) = self.find_doc_handle(&doc_user.doc_id, pool).await {
-            handle.add_user(user, doc_user.rev_id, socket).await?;
-        }
-        Ok(())
-    }
-
-    async fn apply_pushed_rev(
-        &self,
-        user: Arc<WsUser>,
-        socket: Socket,
-        data: Vec<u8>,
-        pool: Data<PgPool>,
-    ) -> DocResult<()> {
-        let revision = spawn_blocking(move || {
-            let revision: Revision = parse_from_bytes(&data)?;
-            let _ = verify_md5(&revision)?;
-            DocResult::Ok(revision)
-        })
-        .await
-        .map_err(internal_error)??;
-        if let Some(handle) = self.find_doc_handle(&revision.doc_id, pool).await {
-            handle.apply_revision(user, socket, revision).await?;
-        }
-        Ok(())
-    }
-
-    async fn find_doc_handle(&self, doc_id: &str, pool: Data<PgPool>) -> Option<Arc<DocOpenHandle>> {
-        match self.doc_manager.get(doc_id, pool).await {
-            Ok(Some(edit_doc)) => Some(edit_doc),
-            Ok(None) => {
-                log::error!("Document with id: {} not exist", doc_id);
-                None
-            },
-            Err(e) => {
-                log::error!("Get doc handle failed: {:?}", e);
-                None
-            },
-        }
-    }
-}
-
-fn verify_md5(revision: &Revision) -> DocResult<()> {
-    if md5(&revision.delta_data) != revision.md5 {
-        return Err(ServerError::internal().context("Revision md5 not match"));
-    }
-    Ok(())
-}

+ 0 - 45
backend/src/service/ws/router.rs

@@ -1,45 +0,0 @@
-use crate::service::{
-    user::LoggedUser,
-    ws::{WsBizHandlers, WsClient, WsServer, WsUser},
-};
-use actix::Addr;
-use actix_web::{
-    get,
-    web::{Data, Path, Payload},
-    Error,
-    HttpRequest,
-    HttpResponse,
-};
-use actix_web_actors::ws;
-
-#[get("/{token}")]
-pub async fn establish_ws_connection(
-    request: HttpRequest,
-    payload: Payload,
-    token: Path<String>,
-    server: Data<Addr<WsServer>>,
-    biz_handlers: Data<WsBizHandlers>,
-) -> Result<HttpResponse, Error> {
-    tracing::info!("establish_ws_connection");
-    match LoggedUser::from_token(token.clone()) {
-        Ok(user) => {
-            let ws_user = WsUser::new(user);
-            let client = WsClient::new(ws_user, server.get_ref().clone(), biz_handlers);
-            let result = ws::start(client, &request, payload);
-            match result {
-                Ok(response) => Ok(response),
-                Err(e) => {
-                    log::error!("ws connection error: {:?}", e);
-                    Err(e)
-                },
-            }
-        },
-        Err(e) => {
-            if e.is_unauthorized() {
-                Ok(HttpResponse::Unauthorized().json(e))
-            } else {
-                Ok(HttpResponse::BadRequest().json(e))
-            }
-        },
-    }
-}

+ 3 - 3
backend/src/service/app/app.rs → backend/src/services/app/app.rs

@@ -1,13 +1,13 @@
 use crate::{
     entities::workspace::{AppTable, APP_TABLE},
-    service::{app::sql_builder::*, user::LoggedUser, view::read_view_belong_to_id},
+    services::{app::sql_builder::*, user::LoggedUser, view::read_view_belong_to_id},
     sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
 };
 
-use crate::service::trash::read_trash_ids;
+use crate::services::trash::read_trash_ids;
 use backend_service::errors::{invalid_params, ServerError};
 use chrono::Utc;
-use flowy_workspace_infra::{
+use flowy_core_data_model::{
     parser::{
         app::{AppDesc, AppName},
         workspace::WorkspaceId,

+ 0 - 0
backend/src/service/app/mod.rs → backend/src/services/app/mod.rs


+ 3 - 3
backend/src/service/app/router.rs → backend/src/services/app/router.rs

@@ -3,11 +3,11 @@ use actix_web::{
     HttpResponse,
 };
 use backend_service::errors::{invalid_params, ServerError};
-use flowy_workspace_infra::protobuf::{AppIdentifier, CreateAppParams, UpdateAppParams};
+use flowy_core_data_model::protobuf::{AppIdentifier, CreateAppParams, UpdateAppParams};
 use protobuf::Message;
 use sqlx::PgPool;
 
-use crate::service::{
+use crate::services::{
     app::{
         app::{create_app, delete_app, read_app, update_app},
         sql_builder::check_app_id,
@@ -17,7 +17,7 @@ use crate::service::{
 };
 use anyhow::Context;
 use backend_service::response::FlowyResponse;
-use flowy_workspace_infra::parser::app::{AppDesc, AppName};
+use flowy_core_data_model::parser::app::{AppDesc, AppName};
 
 pub async fn create_handler(
     payload: Payload,

+ 1 - 1
backend/src/service/app/sql_builder.rs → backend/src/services/app/sql_builder.rs

@@ -4,7 +4,7 @@ use crate::{
 };
 use backend_service::errors::{invalid_params, ServerError};
 use chrono::{DateTime, NaiveDateTime, Utc};
-use flowy_workspace_infra::{
+use flowy_core_data_model::{
     parser::app::AppId,
     protobuf::{App, ColorStyle},
 };

+ 19 - 3
backend/src/service/doc/crud.rs → backend/src/services/doc/crud.rs

@@ -4,12 +4,12 @@ use crate::{
 };
 use anyhow::Context;
 use backend_service::errors::ServerError;
-use flowy_document_infra::protobuf::{CreateDocParams, Doc, DocIdentifier, UpdateDocParams};
+use flowy_collaboration::protobuf::{CreateDocParams, Doc, DocIdentifier, UpdateDocParams};
 use sqlx::{postgres::PgArguments, PgPool, Postgres};
 use uuid::Uuid;
 
 #[tracing::instrument(level = "debug", skip(transaction), err)]
-pub(crate) async fn create_doc(
+pub(crate) async fn create_doc_with_transaction(
     transaction: &mut DBTransaction<'_>,
     params: CreateDocParams,
 ) -> Result<(), ServerError> {
@@ -23,6 +23,22 @@ pub(crate) async fn create_doc(
     Ok(())
 }
 
+pub(crate) async fn create_doc(pool: &PgPool, params: CreateDocParams) -> Result<(), ServerError> {
+    let mut transaction = pool
+        .begin()
+        .await
+        .context("Failed to acquire a Postgres connection to create doc")?;
+
+    let _ = create_doc_with_transaction(&mut transaction, params).await?;
+
+    transaction
+        .commit()
+        .await
+        .context("Failed to commit SQL transaction to create doc.")?;
+
+    Ok(())
+}
+
 #[tracing::instrument(level = "debug", skip(pool), err)]
 pub(crate) async fn read_doc(pool: &PgPool, params: DocIdentifier) -> Result<Doc, ServerError> {
     let doc_id = Uuid::parse_str(&params.doc_id)?;
@@ -59,7 +75,7 @@ pub async fn update_doc(pool: &PgPool, mut params: UpdateDocParams) -> Result<()
 
     let data = Some(params.take_data());
 
-    tracing::Span::current().record("result", &data.as_ref().unwrap_or(&"".to_owned()).as_str());
+    tracing::Span::current().record("delta", &data.as_ref().unwrap_or(&"".to_owned()).as_str());
 
     let (sql, args) = SqlBuilder::update(DOC_TABLE)
         .add_some_arg("data", data)

+ 65 - 0
backend/src/services/doc/editor.rs

@@ -0,0 +1,65 @@
+use crate::{
+    services::doc::update_doc,
+    web_socket::{entities::Socket, WsMessageAdaptor, WsUser},
+};
+use actix_web::web::Data;
+use backend_service::errors::internal_error;
+
+use flowy_collaboration::{
+    core::sync::{RevisionUser, SyncResponse},
+    protobuf::UpdateDocParams,
+};
+
+use sqlx::PgPool;
+use std::sync::Arc;
+
+#[derive(Clone, Debug)]
+pub struct ServerDocUser {
+    pub user: Arc<WsUser>,
+    pub(crate) socket: Socket,
+    pub pg_pool: Data<PgPool>,
+}
+
+impl RevisionUser for ServerDocUser {
+    fn user_id(&self) -> String { self.user.id().to_string() }
+
+    fn recv(&self, resp: SyncResponse) {
+        let result = match resp {
+            SyncResponse::Pull(data) => {
+                let msg: WsMessageAdaptor = data.into();
+                self.socket.try_send(msg).map_err(internal_error)
+            },
+            SyncResponse::Push(data) => {
+                let msg: WsMessageAdaptor = data.into();
+                self.socket.try_send(msg).map_err(internal_error)
+            },
+            SyncResponse::Ack(data) => {
+                let msg: WsMessageAdaptor = data.into();
+                self.socket.try_send(msg).map_err(internal_error)
+            },
+            SyncResponse::NewRevision {
+                rev_id,
+                doc_id,
+                doc_json,
+            } => {
+                let pg_pool = self.pg_pool.clone();
+                tokio::task::spawn(async move {
+                    let mut params = UpdateDocParams::new();
+                    params.set_doc_id(doc_id);
+                    params.set_data(doc_json);
+                    params.set_rev_id(rev_id);
+                    match update_doc(pg_pool.get_ref(), params).await {
+                        Ok(_) => {},
+                        Err(e) => log::error!("{}", e),
+                    }
+                });
+                Ok(())
+            },
+        };
+
+        match result {
+            Ok(_) => {},
+            Err(e) => log::error!("[ServerDocUser]: {}", e),
+        }
+    }
+}

+ 132 - 0
backend/src/services/doc/manager.rs

@@ -0,0 +1,132 @@
+use crate::{
+    services::doc::{
+        read_doc,
+        update_doc,
+        ws_actor::{DocWsActor, DocWsMsg},
+    },
+    web_socket::{WsBizHandler, WsClientData},
+};
+use actix_web::web::Data;
+
+use crate::services::doc::create_doc;
+use backend_service::errors::ServerError;
+use flowy_collaboration::{
+    core::sync::{ServerDocManager, ServerDocPersistence},
+    entities::doc::Doc,
+    errors::CollaborateError,
+    protobuf::{CreateDocParams, DocIdentifier, UpdateDocParams},
+};
+use lib_infra::future::FutureResultSend;
+use lib_ot::{revision::Revision, rich_text::RichTextDelta};
+use sqlx::PgPool;
+use std::{convert::TryInto, sync::Arc};
+use tokio::sync::{mpsc, oneshot};
+
+pub struct DocumentCore {
+    pub manager: Arc<ServerDocManager>,
+    ws_sender: mpsc::Sender<DocWsMsg>,
+    pg_pool: Data<PgPool>,
+}
+
+impl DocumentCore {
+    pub fn new(pg_pool: Data<PgPool>) -> Self {
+        let manager = Arc::new(ServerDocManager::new(Arc::new(DocPersistenceImpl(pg_pool.clone()))));
+        let (ws_sender, rx) = mpsc::channel(100);
+        let actor = DocWsActor::new(rx, manager.clone());
+        tokio::task::spawn(actor.run());
+        Self {
+            manager,
+            ws_sender,
+            pg_pool,
+        }
+    }
+}
+
+impl WsBizHandler for DocumentCore {
+    fn receive(&self, data: WsClientData) {
+        let (ret, rx) = oneshot::channel();
+        let sender = self.ws_sender.clone();
+        let pool = self.pg_pool.clone();
+
+        actix_rt::spawn(async move {
+            let msg = DocWsMsg::ClientData {
+                client_data: data,
+                ret,
+                pool,
+            };
+            match sender.send(msg).await {
+                Ok(_) => {},
+                Err(e) => log::error!("{}", e),
+            }
+            match rx.await {
+                Ok(_) => {},
+                Err(e) => log::error!("{:?}", e),
+            };
+        });
+    }
+}
+
+struct DocPersistenceImpl(Data<PgPool>);
+impl ServerDocPersistence for DocPersistenceImpl {
+    fn update_doc(&self, doc_id: &str, rev_id: i64, delta: RichTextDelta) -> FutureResultSend<(), CollaborateError> {
+        let pg_pool = self.0.clone();
+        let mut params = UpdateDocParams::new();
+        let doc_json = delta.to_json();
+        params.set_doc_id(doc_id.to_string());
+        params.set_data(doc_json);
+        params.set_rev_id(rev_id);
+
+        FutureResultSend::new(async move {
+            let _ = update_doc(pg_pool.get_ref(), params)
+                .await
+                .map_err(server_error_to_collaborate_error)?;
+            Ok(())
+        })
+    }
+
+    fn read_doc(&self, doc_id: &str) -> FutureResultSend<Doc, CollaborateError> {
+        let params = DocIdentifier {
+            doc_id: doc_id.to_string(),
+            ..Default::default()
+        };
+        let pg_pool = self.0.clone();
+        FutureResultSend::new(async move {
+            let mut pb_doc = read_doc(pg_pool.get_ref(), params)
+                .await
+                .map_err(server_error_to_collaborate_error)?;
+            let doc = (&mut pb_doc)
+                .try_into()
+                .map_err(|e| CollaborateError::internal().context(e))?;
+            Ok(doc)
+        })
+    }
+
+    fn create_doc(&self, revision: Revision) -> FutureResultSend<Doc, CollaborateError> {
+        let pg_pool = self.0.clone();
+        FutureResultSend::new(async move {
+            let delta = RichTextDelta::from_bytes(&revision.delta_data)?;
+            let doc_json = delta.to_json();
+
+            let params = CreateDocParams {
+                id: revision.doc_id.clone(),
+                data: doc_json.clone(),
+                unknown_fields: Default::default(),
+                cached_size: Default::default(),
+            };
+
+            let _ = create_doc(pg_pool.get_ref(), params)
+                .await
+                .map_err(server_error_to_collaborate_error)?;
+            let doc: Doc = revision.try_into()?;
+            Ok(doc)
+        })
+    }
+}
+
+fn server_error_to_collaborate_error(error: ServerError) -> CollaborateError {
+    if error.is_record_not_found() {
+        CollaborateError::record_not_found()
+    } else {
+        CollaborateError::internal().context(error)
+    }
+}

+ 2 - 1
backend/src/service/doc/mod.rs → backend/src/services/doc/mod.rs

@@ -1,9 +1,10 @@
 #![allow(clippy::module_inception)]
+
 pub(crate) use crud::*;
 pub use router::*;
 
 pub mod crud;
-mod edit;
+mod editor;
 pub mod manager;
 pub mod router;
 mod ws_actor;

+ 4 - 16
backend/src/service/doc/router.rs → backend/src/services/doc/router.rs

@@ -1,4 +1,4 @@
-use crate::service::{
+use crate::services::{
     doc::{create_doc, read_doc, update_doc},
     util::parse_from_payload,
 };
@@ -6,26 +6,14 @@ use actix_web::{
     web::{Data, Payload},
     HttpResponse,
 };
-use anyhow::Context;
+
 use backend_service::{errors::ServerError, response::FlowyResponse};
-use flowy_document_infra::protobuf::{CreateDocParams, DocIdentifier, UpdateDocParams};
+use flowy_collaboration::protobuf::{CreateDocParams, DocIdentifier, UpdateDocParams};
 use sqlx::PgPool;
 
 pub async fn create_handler(payload: Payload, pool: Data<PgPool>) -> Result<HttpResponse, ServerError> {
     let params: CreateDocParams = parse_from_payload(payload).await?;
-
-    let mut transaction = pool
-        .begin()
-        .await
-        .context("Failed to acquire a Postgres connection to create doc")?;
-
-    let _ = create_doc(&mut transaction, params).await?;
-
-    transaction
-        .commit()
-        .await
-        .context("Failed to commit SQL transaction to create doc.")?;
-
+    let _ = create_doc(&pool, params).await?;
     Ok(FlowyResponse::success().into())
 }
 

+ 132 - 0
backend/src/services/doc/ws_actor.rs

@@ -0,0 +1,132 @@
+use crate::{
+    services::{
+        doc::editor::ServerDocUser,
+        util::{md5, parse_from_bytes},
+    },
+    web_socket::WsClientData,
+};
+use actix_rt::task::spawn_blocking;
+use actix_web::web::Data;
+use async_stream::stream;
+use backend_service::errors::{internal_error, Result, ServerError};
+use flowy_collaboration::{
+    core::sync::{RevisionUser, ServerDocManager, SyncResponse},
+    entities::ws::DocumentWSDataBuilder,
+    protobuf::{DocumentWSData, DocumentWSDataType},
+};
+
+use flowy_collaboration::protobuf::NewDocumentUser;
+use futures::stream::StreamExt;
+use lib_ot::protobuf::Revision;
+use sqlx::PgPool;
+use std::{convert::TryInto, sync::Arc};
+use tokio::sync::{mpsc, oneshot};
+
+pub enum DocWsMsg {
+    ClientData {
+        client_data: WsClientData,
+        pool: Data<PgPool>,
+        ret: oneshot::Sender<Result<()>>,
+    },
+}
+
+pub struct DocWsActor {
+    receiver: Option<mpsc::Receiver<DocWsMsg>>,
+    doc_manager: Arc<ServerDocManager>,
+}
+
+impl DocWsActor {
+    pub fn new(receiver: mpsc::Receiver<DocWsMsg>, manager: Arc<ServerDocManager>) -> Self {
+        Self {
+            receiver: Some(receiver),
+            doc_manager: manager,
+        }
+    }
+
+    pub async fn run(mut self) {
+        let mut receiver = self
+            .receiver
+            .take()
+            .expect("DocActor's receiver should only take one time");
+
+        let stream = stream! {
+            loop {
+                match receiver.recv().await {
+                    Some(msg) => yield msg,
+                    None => break,
+                }
+            }
+        };
+
+        stream.for_each(|msg| self.handle_message(msg)).await;
+    }
+
+    async fn handle_message(&self, msg: DocWsMsg) {
+        match msg {
+            DocWsMsg::ClientData { client_data, pool, ret } => {
+                let _ = ret.send(self.handle_client_data(client_data, pool).await);
+            },
+        }
+    }
+
+    async fn handle_client_data(&self, client_data: WsClientData, pg_pool: Data<PgPool>) -> Result<()> {
+        let WsClientData { user, socket, data } = client_data;
+        let document_data = spawn_blocking(move || {
+            let document_data: DocumentWSData = parse_from_bytes(&data)?;
+            Result::Ok(document_data)
+        })
+        .await
+        .map_err(internal_error)??;
+
+        let user = Arc::new(ServerDocUser { user, socket, pg_pool });
+        match &document_data.ty {
+            DocumentWSDataType::Ack => Ok(()),
+            DocumentWSDataType::PushRev => self.handle_pushed_rev(user, document_data.data).await,
+            DocumentWSDataType::PullRev => Ok(()),
+            DocumentWSDataType::UserConnect => self.handle_user_connect(user, document_data).await,
+        }
+    }
+
+    async fn handle_user_connect(&self, user: Arc<ServerDocUser>, document_data: DocumentWSData) -> Result<()> {
+        let id = document_data.id.clone();
+        let new_user = spawn_blocking(move || parse_from_bytes::<NewDocumentUser>(&document_data.data))
+            .await
+            .map_err(internal_error)??;
+
+        user.recv(SyncResponse::Ack(DocumentWSDataBuilder::build_ack_message(
+            &new_user.doc_id,
+            &id,
+        )));
+        Ok(())
+    }
+
+    async fn handle_pushed_rev(&self, user: Arc<ServerDocUser>, data: Vec<u8>) -> Result<()> {
+        let mut revision_pb = spawn_blocking(move || {
+            let revision: Revision = parse_from_bytes(&data)?;
+            let _ = verify_md5(&revision)?;
+            Result::Ok(revision)
+        })
+        .await
+        .map_err(internal_error)??;
+        let revision: lib_ot::revision::Revision = (&mut revision_pb).try_into().map_err(internal_error)?;
+        // Create the doc if it doesn't exist
+        let handler = match self.doc_manager.get(&revision.doc_id).await {
+            None => self
+                .doc_manager
+                .create_doc(revision.clone())
+                .await
+                .map_err(internal_error)?,
+            Some(handler) => handler,
+        };
+
+        handler.apply_revision(user, revision).await.map_err(internal_error)?;
+        Ok(())
+    }
+}
+
+fn verify_md5(revision: &Revision) -> Result<()> {
+    if md5(&revision.delta_data) != revision.md5 {
+        return Err(ServerError::internal().context("Revision md5 not match"));
+    }
+    Ok(())
+}

+ 0 - 0
backend/src/service/log/mod.rs → backend/src/services/log.rs


+ 0 - 1
backend/src/service/mod.rs → backend/src/services/mod.rs

@@ -6,4 +6,3 @@ pub mod user;
 pub(crate) mod util;
 pub mod view;
 pub mod workspace;
-pub mod ws;

+ 0 - 0
backend/src/service/trash/mod.rs → backend/src/services/trash/mod.rs


+ 2 - 2
backend/src/service/trash/router.rs → backend/src/services/trash/router.rs

@@ -1,4 +1,4 @@
-use crate::service::{
+use crate::services::{
     trash::{create_trash, delete_all_trash, delete_trash, read_trash},
     user::LoggedUser,
     util::parse_from_payload,
@@ -13,7 +13,7 @@ use backend_service::{
     errors::{invalid_params, ServerError},
     response::FlowyResponse,
 };
-use flowy_workspace_infra::{parser::trash::TrashId, protobuf::TrashIdentifiers};
+use flowy_core_data_model::{parser::trash::TrashId, protobuf::TrashIdentifiers};
 use sqlx::PgPool;
 use uuid::Uuid;
 

+ 2 - 2
backend/src/service/trash/trash.rs → backend/src/services/trash/trash.rs

@@ -1,6 +1,6 @@
 use crate::{
     entities::workspace::{TrashTable, TRASH_TABLE},
-    service::{
+    services::{
         app::app::{delete_app, read_app_table},
         user::LoggedUser,
         view::{delete_view, read_view_table},
@@ -9,7 +9,7 @@ use crate::{
 };
 use ::protobuf::ProtobufEnum;
 use backend_service::errors::ServerError;
-use flowy_workspace_infra::protobuf::{RepeatedTrash, Trash, TrashType};
+use flowy_core_data_model::protobuf::{RepeatedTrash, Trash, TrashType};
 use sqlx::{postgres::PgArguments, Postgres, Row};
 use uuid::Uuid;
 

+ 2 - 4
backend/src/service/user/auth.rs → backend/src/services/user/auth.rs

@@ -1,6 +1,6 @@
 use crate::{
     entities::{token::Token, user::UserTable},
-    service::user::{hash_password, verify_password, LoggedUser},
+    services::user::{hash_password, verify_password, LoggedUser},
     sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder},
 };
 use anyhow::Context;
@@ -9,14 +9,13 @@ use backend_service::{
     response::FlowyResponse,
 };
 use chrono::Utc;
-use flowy_user_infra::{
+use flowy_user_data_model::{
     parser::{UserEmail, UserName, UserPassword},
     protobuf::{SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile},
 };
 use sqlx::{PgPool, Postgres};
 
 use super::AUTHORIZED_USERS;
-use crate::service::user::user_default::create_default_workspace;
 
 pub async fn sign_in(pool: &PgPool, params: SignInParams) -> Result<SignInResponse, ServerError> {
     let email = UserEmail::parse(params.email).map_err(|e| ServerError::params_invalid().context(e))?;
@@ -68,7 +67,6 @@ pub async fn register_user(pool: &PgPool, params: SignUpParams) -> Result<FlowyR
 
     let logged_user = LoggedUser::new(&response_data.user_id);
     AUTHORIZED_USERS.store_auth(logged_user, true);
-    let _ = create_default_workspace(&mut transaction, response_data.get_user_id()).await?;
 
     transaction
         .commit()

+ 0 - 0
backend/src/service/user/logged_user.rs → backend/src/services/user/logged_user.rs


+ 0 - 0
backend/src/service/user/mod.rs → backend/src/services/user/mod.rs


+ 2 - 2
backend/src/service/user/router.rs → backend/src/services/user/router.rs

@@ -7,11 +7,11 @@ use actix_web::{
 use sqlx::PgPool;
 
 use backend_service::{errors::ServerError, response::FlowyResponse};
-use flowy_user_infra::protobuf::{SignInParams, SignUpParams, UpdateUserParams};
+use flowy_user_data_model::protobuf::{SignInParams, SignUpParams, UpdateUserParams};
 
 use crate::{
     entities::token::Token,
-    service::{
+    services::{
         user::{get_user_profile, register_user, set_user_profile, sign_in, sign_out, LoggedUser},
         util::parse_from_payload,
     },

+ 7 - 6
backend/src/service/user/user_default.rs → backend/src/services/user/user_default.rs

@@ -1,24 +1,25 @@
 use crate::{
-    service::{
+    services::{
         app::sql_builder::NewAppSqlBuilder as AppBuilder,
         workspace::sql_builder::NewWorkspaceBuilder as WorkspaceBuilder,
     },
     sqlx_ext::{map_sqlx_error, DBTransaction},
 };
 
-use crate::service::view::{create_view_with_args, sql_builder::NewViewSqlBuilder};
+use crate::services::view::{create_view_with_args, sql_builder::NewViewSqlBuilder};
 use backend_service::errors::ServerError;
 use chrono::Utc;
-use flowy_document_infra::user_default::doc_initial_string;
-use flowy_workspace_infra::protobuf::Workspace;
+use flowy_collaboration::core::document::default::initial_string;
+use flowy_core_data_model::protobuf::Workspace;
 use std::convert::TryInto;
 
+#[allow(dead_code)]
 pub async fn create_default_workspace(
     transaction: &mut DBTransaction<'_>,
     user_id: &str,
 ) -> Result<Workspace, ServerError> {
     let time = Utc::now();
-    let workspace: Workspace = flowy_workspace_infra::user_default::create_default_workspace(time)
+    let workspace: Workspace = flowy_core_data_model::user_default::create_default_workspace(time)
         .try_into()
         .unwrap();
 
@@ -41,7 +42,7 @@ pub async fn create_default_workspace(
 
         for view in views.take_items() {
             let (sql, args, view) = NewViewSqlBuilder::from_view(view)?.build()?;
-            let _ = create_view_with_args(transaction, sql, args, view, doc_initial_string()).await?;
+            let _ = create_view_with_args(transaction, sql, args, view, initial_string()).await?;
         }
     }
     Ok(workspace)

+ 0 - 0
backend/src/service/user/utils.rs → backend/src/services/user/utils.rs


+ 0 - 0
backend/src/service/util.rs → backend/src/services/util.rs


+ 0 - 0
backend/src/service/view/mod.rs → backend/src/services/view/mod.rs


+ 4 - 4
backend/src/service/view/router.rs → backend/src/services/view/router.rs

@@ -1,5 +1,5 @@
-use crate::service::{
-    doc::manager::DocBiz,
+use crate::services::{
+    doc::manager::DocumentCore,
     user::LoggedUser,
     util::parse_from_payload,
     view::{create_view, delete_view, read_view, sql_builder::check_view_ids, update_view},
@@ -13,7 +13,7 @@ use backend_service::{
     errors::{invalid_params, ServerError},
     response::FlowyResponse,
 };
-use flowy_workspace_infra::{
+use flowy_core_data_model::{
     parser::view::{ViewDesc, ViewName, ViewThumbnail},
     protobuf::{CreateViewParams, QueryViewRequest, UpdateViewParams, ViewIdentifier},
 };
@@ -23,7 +23,7 @@ use std::sync::Arc;
 pub async fn create_handler(
     payload: Payload,
     pool: Data<PgPool>,
-    _doc_biz: Data<Arc<DocBiz>>,
+    _doc_biz: Data<Arc<DocumentCore>>,
 ) -> Result<HttpResponse, ServerError> {
     let params: CreateViewParams = parse_from_payload(payload).await?;
     let mut transaction = pool

+ 1 - 1
backend/src/service/view/sql_builder.rs → backend/src/services/view/sql_builder.rs

@@ -4,7 +4,7 @@ use crate::{
 };
 use backend_service::errors::{invalid_params, ServerError};
 use chrono::{DateTime, NaiveDateTime, Utc};
-use flowy_workspace_infra::{
+use flowy_core_data_model::{
     parser::view::ViewId,
     protobuf::{View, ViewType},
 };

+ 5 - 5
backend/src/service/view/view.rs → backend/src/services/view/view.rs

@@ -1,7 +1,7 @@
 use crate::{
     entities::workspace::{ViewTable, VIEW_TABLE},
-    service::{
-        doc::{create_doc, delete_doc},
+    services::{
+        doc::{create_doc_with_transaction, delete_doc},
         trash::read_trash_ids,
         user::LoggedUser,
         view::sql_builder::*,
@@ -10,8 +10,8 @@ use crate::{
 };
 use backend_service::errors::{invalid_params, ServerError};
 use chrono::Utc;
-use flowy_document_infra::protobuf::CreateDocParams;
-use flowy_workspace_infra::{
+use flowy_collaboration::protobuf::CreateDocParams;
+use flowy_core_data_model::{
     parser::{
         app::AppId,
         view::{ViewDesc, ViewName, ViewThumbnail},
@@ -94,7 +94,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(transaction, create_doc_params).await?;
+    let _ = create_doc_with_transaction(transaction, create_doc_params).await?;
     Ok(view)
 }
 

+ 0 - 0
backend/src/service/workspace/mod.rs → backend/src/services/workspace/mod.rs


+ 2 - 2
backend/src/service/workspace/router.rs → backend/src/services/workspace/router.rs

@@ -1,4 +1,4 @@
-use crate::service::{
+use crate::services::{
     user::LoggedUser,
     util::parse_from_payload,
     workspace::{
@@ -18,7 +18,7 @@ use backend_service::{
     errors::{invalid_params, ServerError},
     response::FlowyResponse,
 };
-use flowy_workspace_infra::{
+use flowy_core_data_model::{
     parser::workspace::{WorkspaceDesc, WorkspaceName},
     protobuf::{CreateWorkspaceParams, UpdateWorkspaceParams, WorkspaceIdentifier},
 };

+ 1 - 1
backend/src/service/workspace/sql_builder.rs → backend/src/services/workspace/sql_builder.rs

@@ -4,7 +4,7 @@ use crate::{
 };
 use backend_service::errors::{invalid_params, ServerError};
 use chrono::{DateTime, NaiveDateTime, Utc};
-use flowy_workspace_infra::{parser::workspace::WorkspaceId, protobuf::Workspace};
+use flowy_core_data_model::{parser::workspace::WorkspaceId, protobuf::Workspace};
 use sqlx::postgres::PgArguments;
 use uuid::Uuid;
 

+ 2 - 2
backend/src/service/workspace/workspace.rs → backend/src/services/workspace/workspace.rs

@@ -1,12 +1,12 @@
 use super::sql_builder::NewWorkspaceBuilder;
 use crate::{
     entities::workspace::{AppTable, WorkspaceTable, WORKSPACE_TABLE},
-    service::{app::app::read_app, user::LoggedUser, workspace::sql_builder::*},
+    services::{app::app::read_app, user::LoggedUser, workspace::sql_builder::*},
     sqlx_ext::*,
 };
 use anyhow::Context;
 use backend_service::errors::{invalid_params, ServerError};
-use flowy_workspace_infra::{
+use flowy_core_data_model::{
     parser::workspace::WorkspaceId,
     protobuf::{RepeatedApp, RepeatedWorkspace, Workspace},
 };

+ 6 - 7
backend/src/service/ws/biz_handler.rs → backend/src/web_socket/biz_handler.rs

@@ -1,15 +1,14 @@
-use crate::service::ws::WsClientData;
-
-use lib_ws::WsModule;
+use crate::web_socket::WsClientData;
+use lib_ws::WSModule;
 use std::{collections::HashMap, sync::Arc};
 
 pub trait WsBizHandler: Send + Sync {
-    fn receive_data(&self, client_data: WsClientData);
+    fn receive(&self, data: WsClientData);
 }
 
 pub type BizHandler = Arc<dyn WsBizHandler>;
 pub struct WsBizHandlers {
-    inner: HashMap<WsModule, BizHandler>,
+    inner: HashMap<WSModule, BizHandler>,
 }
 
 impl std::default::Default for WsBizHandlers {
@@ -19,7 +18,7 @@ impl std::default::Default for WsBizHandlers {
 impl WsBizHandlers {
     pub fn new() -> Self { WsBizHandlers::default() }
 
-    pub fn register(&mut self, source: WsModule, handler: BizHandler) { self.inner.insert(source, handler); }
+    pub fn register(&mut self, source: WSModule, handler: BizHandler) { self.inner.insert(source, handler); }
 
-    pub fn get(&self, source: &WsModule) -> Option<BizHandler> { self.inner.get(source).cloned() }
+    pub fn get(&self, source: &WSModule) -> Option<BizHandler> { self.inner.get(source).cloned() }
 }

+ 1 - 1
backend/src/service/ws/entities/connect.rs → backend/src/web_socket/entities/connect.rs

@@ -1,4 +1,4 @@
-use crate::service::ws::WsMessageAdaptor;
+use crate::web_socket::WsMessageAdaptor;
 use actix::{Message, Recipient};
 use backend_service::errors::ServerError;
 use serde::{Deserialize, Serialize};

+ 6 - 6
backend/src/service/ws/entities/message.rs → backend/src/web_socket/entities/message.rs

@@ -1,7 +1,7 @@
 use actix::Message;
 use bytes::Bytes;
-use flowy_document_infra::entities::ws::WsDocumentData;
-use lib_ws::{WsMessage, WsModule};
+use flowy_collaboration::entities::ws::DocumentWSData;
+use lib_ws::{WSMessage, WSModule};
 use std::convert::TryInto;
 
 #[derive(Debug, Message, Clone)]
@@ -14,11 +14,11 @@ impl std::ops::Deref for WsMessageAdaptor {
     fn deref(&self) -> &Self::Target { &self.0 }
 }
 
-impl std::convert::From<WsDocumentData> for WsMessageAdaptor {
-    fn from(data: WsDocumentData) -> Self {
+impl std::convert::From<DocumentWSData> for WsMessageAdaptor {
+    fn from(data: DocumentWSData) -> Self {
         let bytes: Bytes = data.try_into().unwrap();
-        let msg = WsMessage {
-            module: WsModule::Doc,
+        let msg = WSMessage {
+            module: WSModule::Doc,
             data: bytes.to_vec(),
         };
 

+ 0 - 0
backend/src/service/ws/entities/mod.rs → backend/src/web_socket/entities/mod.rs


+ 0 - 0
backend/src/service/ws/mod.rs → backend/src/web_socket/mod.rs


+ 63 - 0
backend/src/web_socket/router.rs

@@ -0,0 +1,63 @@
+use crate::{
+    services::user::LoggedUser,
+    web_socket::{WsBizHandlers, WsClient, WsServer, WsUser},
+};
+use actix::Addr;
+use actix_web::{
+    get,
+    web::{Data, Path, Payload},
+    Error,
+    HttpRequest,
+    HttpResponse,
+};
+use actix_web_actors::ws;
+
+#[rustfmt::skip]
+//                   WsClient
+//                  ┌─────────────┐
+//                  │ ┌────────┐  │
+//  wss://xxx ─────▶│ │ WsUser │  │───┐
+//                  │ └────────┘  │   │
+//                  └─────────────┘   │
+//                                    │
+//                                    │    ┌───────────────┐   ┌─────────────┐    ┌────────────────┐
+//                                    ├───▶│ WsBizHandlers │──▶│WsBizHandler │───▶│  WsClientData  │
+//                                    │    └───────────────┘   └─────────────┘    └────────────────┘
+//                   WsClient         │                               △
+//                  ┌─────────────┐   │                               │
+//                  │ ┌────────┐  │   │                               │
+//  wss://xxx ─────▶│ │ WsUser │  │───┘                       ┌───────────────┐
+//                  │ └────────┘  │                           │ DocumentCore  │
+//                  └─────────────┘                           └───────────────┘
+
+#[get("/{token}")]
+pub async fn establish_ws_connection(
+    request: HttpRequest,
+    payload: Payload,
+    token: Path<String>,
+    server: Data<Addr<WsServer>>,
+    biz_handlers: Data<WsBizHandlers>,
+) -> Result<HttpResponse, Error> {
+    tracing::info!("establish_ws_connection");
+    match LoggedUser::from_token(token.clone()) {
+        Ok(user) => {
+            let ws_user = WsUser::new(user);
+            let client = WsClient::new(ws_user, server.get_ref().clone(), biz_handlers);
+            let result = ws::start(client, &request, payload);
+            match result {
+                Ok(response) => Ok(response),
+                Err(e) => {
+                    log::error!("ws connection error: {:?}", e);
+                    Err(e)
+                },
+            }
+        },
+        Err(e) => {
+            if e.is_unauthorized() {
+                Ok(HttpResponse::Unauthorized().json(e))
+            } else {
+                Ok(HttpResponse::BadRequest().json(e))
+            }
+        },
+    }
+}

+ 9 - 11
backend/src/service/ws/ws_client.rs → backend/src/web_socket/ws_client.rs

@@ -1,20 +1,18 @@
 use crate::{
     config::{HEARTBEAT_INTERVAL, PING_TIMEOUT},
-    service::{
-        user::LoggedUser,
-        ws::{
-            entities::{Connect, Disconnect, Socket},
-            WsBizHandlers,
-            WsMessageAdaptor,
-            WsServer,
-        },
+    services::user::LoggedUser,
+    web_socket::{
+        entities::{Connect, Disconnect, Socket},
+        WsBizHandlers,
+        WsMessageAdaptor,
+        WsServer,
     },
 };
 use actix::*;
 use actix_web::web::Data;
 use actix_web_actors::{ws, ws::Message::Text};
 use bytes::Bytes;
-use lib_ws::WsMessage;
+use lib_ws::WSMessage;
 use std::{convert::TryFrom, sync::Arc, time::Instant};
 
 #[derive(Debug)]
@@ -66,7 +64,7 @@ impl WsClient {
 
     fn handle_binary_message(&self, bytes: Bytes, socket: Socket) {
         // TODO: ok to unwrap?
-        let message: WsMessage = WsMessage::try_from(bytes).unwrap();
+        let message: WSMessage = WSMessage::try_from(bytes).unwrap();
         match self.biz_handlers.get(&message.module) {
             None => {
                 log::error!("Can't find the handler for {:?}", message.module);
@@ -77,7 +75,7 @@ impl WsClient {
                     socket,
                     data: Bytes::from(message.data),
                 };
-                handler.receive_data(client_data);
+                handler.receive(client_data);
             },
         }
     }

+ 1 - 1
backend/src/service/ws/ws_server.rs → backend/src/web_socket/ws_server.rs

@@ -1,4 +1,4 @@
-use crate::service::ws::{
+use crate::web_socket::{
     entities::{Connect, Disconnect, Session, SessionId},
     WsMessageAdaptor,
 };

+ 1 - 1
backend/tests/api/auth.rs

@@ -1,6 +1,6 @@
 use crate::util::helper::{spawn_user_server, TestUserServer};
 use backend_service::errors::ErrorCode;
-use flowy_user_infra::entities::{SignInParams, SignUpParams, SignUpResponse, UpdateUserParams};
+use flowy_user_data_model::entities::{SignInParams, SignUpParams, SignUpResponse, UpdateUserParams};
 
 #[actix_rt::test]
 async fn user_register() {

+ 2 - 2
backend/tests/api/doc.rs

@@ -1,6 +1,6 @@
 use crate::util::helper::ViewTest;
-use flowy_document_infra::entities::doc::DocIdentifier;
-use flowy_workspace_infra::entities::view::ViewIdentifiers;
+use flowy_collaboration::entities::doc::DocIdentifier;
+use flowy_core_data_model::entities::view::ViewIdentifiers;
 
 #[actix_rt::test]
 async fn doc_read() {

+ 1 - 1
backend/tests/api/workspace.rs

@@ -1,6 +1,6 @@
 #![allow(clippy::all)]
 use crate::util::helper::*;
-use flowy_workspace_infra::entities::{
+use flowy_core_data_model::entities::{
     app::{AppIdentifier, UpdateAppParams},
     trash::{TrashIdentifier, TrashIdentifiers, TrashType},
     view::{UpdateViewParams, ViewIdentifier},

+ 35 - 28
backend/tests/document/helper.rs → backend/tests/document/edit_script.rs

@@ -1,9 +1,9 @@
 #![allow(clippy::all)]
 #![cfg_attr(rustfmt, rustfmt::skip)]
 use actix_web::web::Data;
-use backend::service::doc::{crud::update_doc, manager::DocManager};
-use flowy_document::services::doc::ClientDocEditor as ClientEditDocContext;
-use flowy_test::{workspace::ViewTest, FlowyTest};
+use backend::services::doc::{crud::update_doc};
+use flowy_document::services::doc::edit::ClientDocEditor as ClientEditDocContext;
+use flowy_test::{helper::ViewTest, FlowySDKTest};
 use flowy_user::services::user::UserSession;
 use futures_util::{stream, stream::StreamExt};
 use sqlx::PgPool;
@@ -11,19 +11,22 @@ use std::sync::Arc;
 use tokio::time::{sleep, Duration};
 // use crate::helper::*;
 use crate::util::helper::{spawn_server, TestServer};
-use flowy_document_infra::{entities::doc::DocIdentifier, protobuf::UpdateDocParams};
-use lib_ot::core::{Attribute, Delta, Interval};
+use flowy_collaboration::{entities::doc::DocIdentifier, protobuf::UpdateDocParams};
+use lib_ot::rich_text::{RichTextAttribute, RichTextDelta};
 use parking_lot::RwLock;
+use lib_ot::core::Interval;
+use flowy_collaboration::core::sync::ServerDocManager;
+use flowy_net::services::ws::WsManager;
 
 pub struct DocumentTest {
     server: TestServer,
-    flowy_test: FlowyTest,
+    flowy_test: FlowySDKTest,
 }
 #[derive(Clone)]
 pub enum DocScript {
     ClientConnectWs,
     ClientInsertText(usize, &'static str),
-    ClientFormatText(Interval, Attribute),
+    ClientFormatText(Interval, RichTextAttribute),
     ClientOpenDoc,
     AssertClient(&'static str),
     AssertServer(&'static str, i64),
@@ -33,7 +36,7 @@ pub enum DocScript {
 impl DocumentTest {
     pub async fn new() -> Self {
         let server = spawn_server().await;
-        let flowy_test = FlowyTest::setup_with(server.client_server_config.clone());
+        let flowy_test = FlowySDKTest::setup_with(server.client_server_config.clone());
         Self { server, flowy_test }
     }
 
@@ -49,30 +52,33 @@ impl DocumentTest {
 #[derive(Clone)]
 struct ScriptContext {
     client_edit_context: Option<Arc<ClientEditDocContext>>,
-    flowy_test: FlowyTest,
+    client_sdk: FlowySDKTest,
     client_user_session: Arc<UserSession>,
-    server_doc_manager: Arc<DocManager>,
+    ws_manager: Arc<WsManager>,
+    server_doc_manager: Arc<ServerDocManager>,
     server_pg_pool: Data<PgPool>,
     doc_id: String,
 }
 
 impl ScriptContext {
-    async fn new(flowy_test: FlowyTest, server: TestServer) -> Self {
-        let user_session = flowy_test.sdk.user_session.clone();
-        let doc_id = create_doc(&flowy_test).await;
+    async fn new(client_sdk: FlowySDKTest, server: TestServer) -> Self {
+        let user_session = client_sdk.user_session.clone();
+        let ws_manager = client_sdk.ws_manager.clone();
+        let doc_id = create_doc(&client_sdk).await;
 
         Self {
             client_edit_context: None,
-            flowy_test,
+            client_sdk,
             client_user_session: user_session,
-            server_doc_manager: server.app_ctx.doc_biz.manager.clone(),
+            ws_manager,
+            server_doc_manager: server.app_ctx.document_core.manager.clone(),
             server_pg_pool: Data::new(server.pg_pool.clone()),
             doc_id,
         }
     }
 
     async fn open_doc(&mut self) {
-        let flowy_document = self.flowy_test.sdk.flowy_document.clone();
+        let flowy_document = self.client_sdk.flowy_document.clone();
         let doc_id = self.doc_id.clone();
 
         let edit_context = flowy_document.open(DocIdentifier { doc_id }).await.unwrap();
@@ -97,9 +103,10 @@ async fn run_scripts(context: Arc<RwLock<ScriptContext>>, scripts: Vec<DocScript
             match script {
                 DocScript::ClientConnectWs => {
                     // sleep(Duration::from_millis(300)).await;
+                    let ws_manager = context.read().ws_manager.clone();
                     let user_session = context.read().client_user_session.clone();
                     let token = user_session.token().unwrap();
-                    let _ = user_session.start_ws_connection(&token).await.unwrap();
+                    let _ = ws_manager.start(token).await.unwrap();
                 },
                 DocScript::ClientOpenDoc => {
                     context.write().open_doc().await;
@@ -116,18 +123,18 @@ async fn run_scripts(context: Arc<RwLock<ScriptContext>>, scripts: Vec<DocScript
                         .unwrap();
                 },
                 DocScript::AssertClient(s) => {
-                    sleep(Duration::from_millis(100)).await;
+                    sleep(Duration::from_millis(2000)).await;
                     let json = context.read().client_edit_context().doc_json().await.unwrap();
                     assert_eq(s, &json);
                 },
-                DocScript::AssertServer(s, rev_id) => {
+                DocScript::AssertServer(_s, _rev_id) => {
                     sleep(Duration::from_millis(100)).await;
-                    let pg_pool = context.read().server_pg_pool.clone();
-                    let doc_manager = context.read().server_doc_manager.clone();
-                    let edit_doc = doc_manager.get(&doc_id, pg_pool).await.unwrap().unwrap();
-                    let json = edit_doc.document_json().await.unwrap();
-                    assert_eq(s, &json);
-                    assert_eq!(edit_doc.rev_id().await.unwrap(), rev_id);
+                    // let pg_pool = context.read().server_pg_pool.clone();
+                    // let doc_manager = context.read().server_doc_manager.clone();
+                    // let edit_doc = doc_manager.get(&doc_id).unwrap();
+                    // let json = edit_doc.document_json().await.unwrap();
+                    // assert_eq(s, &json);
+                    // assert_eq!(edit_doc.rev_id().await.unwrap(), rev_id);
                 },
                 DocScript::ServerSaveDocument(json, rev_id) => {
                     let pg_pool = context.read().server_pg_pool.clone();
@@ -150,8 +157,8 @@ async fn run_scripts(context: Arc<RwLock<ScriptContext>>, scripts: Vec<DocScript
 }
 
 fn assert_eq(expect: &str, receive: &str) {
-    let expected_delta: Delta = serde_json::from_str(expect).unwrap();
-    let target_delta: Delta = serde_json::from_str(receive).unwrap();
+    let expected_delta: RichTextDelta = serde_json::from_str(expect).unwrap();
+    let target_delta: RichTextDelta = serde_json::from_str(receive).unwrap();
 
     if expected_delta != target_delta {
         log::error!("✅ expect: {}", expect,);
@@ -160,7 +167,7 @@ fn assert_eq(expect: &str, receive: &str) {
     assert_eq!(target_delta, expected_delta);
 }
 
-async fn create_doc(flowy_test: &FlowyTest) -> String {
+async fn create_doc(flowy_test: &FlowySDKTest) -> String {
     let view_test = ViewTest::new(flowy_test).await;
     view_test.view.id
 }

+ 6 - 6
backend/tests/document/edit.rs → backend/tests/document/edit_test.rs

@@ -1,6 +1,6 @@
-use crate::document::helper::{DocScript, DocumentTest};
-use flowy_document_infra::core::{Document, FlowyDoc};
-use lib_ot::core::{Attribute, Interval};
+use crate::document::edit_script::{DocScript, DocumentTest};
+use flowy_collaboration::core::document::{Document, FlowyDoc};
+use lib_ot::{core::Interval, rich_text::RichTextAttribute};
 
 #[rustfmt::skip]
 //                         ┌─────────┐       ┌─────────┐
@@ -51,11 +51,11 @@ async fn delta_sync_while_editing_with_attribute() {
         DocScript::ClientConnectWs,
         DocScript::ClientOpenDoc,
         DocScript::ClientInsertText(0, "abc"),
-        DocScript::ClientFormatText(Interval::new(0, 3), Attribute::Bold(true)),
+        DocScript::ClientFormatText(Interval::new(0, 3), RichTextAttribute::Bold(true)),
         DocScript::AssertClient(r#"[{"insert":"abc","attributes":{"bold":true}},{"insert":"\n"}]"#),
         DocScript::AssertServer(r#"[{"insert":"abc","attributes":{"bold":true}},{"insert":"\n"}]"#, 2),
         DocScript::ClientInsertText(3, "efg"),
-        DocScript::ClientFormatText(Interval::new(3, 5), Attribute::Italic(true)),
+        DocScript::ClientFormatText(Interval::new(3, 5), RichTextAttribute::Italic(true)),
         DocScript::AssertClient(r#"[{"insert":"abc","attributes":{"bold":true}},{"insert":"ef","attributes":{"bold":true,"italic":true}},{"insert":"g","attributes":{"bold":true}},{"insert":"\n"}]"#),
         DocScript::AssertServer(r#"[{"insert":"abc","attributes":{"bold":true}},{"insert":"ef","attributes":{"bold":true,"italic":true}},{"insert":"g","attributes":{"bold":true}},{"insert":"\n"}]"#, 4),
     ])
@@ -197,7 +197,7 @@ async fn delta_sync_while_local_rev_greater_than_server_rev() {
         DocScript::ClientInsertText(6, "efg"),
         DocScript::ClientConnectWs,
         DocScript::AssertClient(r#"[{"insert":"123abcefg\n"}]"#),
-        // DocScript::AssertServer(r#"[{"insert":"123abcefg\n"}]"#, 3),
+        DocScript::AssertServer(r#"[{"insert":"123abcefg\n"}]"#, 3),
     ])
     .await;
 }

+ 2 - 2
backend/tests/document/mod.rs

@@ -1,2 +1,2 @@
-mod edit;
-mod helper;
+mod edit_script;
+mod edit_test;

+ 4 - 4
backend/tests/util/helper.rs

@@ -9,10 +9,10 @@ use backend_service::{
     user_request::*,
     workspace_request::*,
 };
+use flowy_collaboration::entities::doc::{Doc, DocIdentifier};
+use flowy_core_data_model::entities::prelude::*;
 use flowy_document::services::server::read_doc_request;
-use flowy_document_infra::entities::doc::{Doc, DocIdentifier};
-use flowy_user_infra::entities::*;
-use flowy_workspace_infra::entities::prelude::*;
+use flowy_user_data_model::entities::*;
 use sqlx::{Connection, Executor, PgConnection, PgPool};
 use uuid::Uuid;
 
@@ -188,7 +188,7 @@ impl std::convert::From<TestServer> for TestUserServer {
             pg_pool: server.pg_pool,
             user_token: None,
             user_id: None,
-            client_server_config: server.client_server_config.clone(),
+            client_server_config: server.client_server_config,
         }
     }
 }

+ 2 - 2
frontend/app_flowy/ios/Runner.xcodeproj/project.pbxproj

@@ -3,7 +3,7 @@
 	archiveVersion = 1;
 	classes = {
 	};
-	objectVersion = 46;
+	objectVersion = 50;
 	objects = {
 
 /* Begin PBXBuildFile section */
@@ -156,7 +156,7 @@
 		97C146E61CF9000F007C117D /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastUpgradeCheck = 1020;
+				LastUpgradeCheck = 1300;
 				ORGANIZATIONNAME = "";
 				TargetAttributes = {
 					97C146ED1CF9000F007C117D = {

+ 1 - 1
frontend/app_flowy/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1020"
+   LastUpgradeVersion = "1300"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"

+ 4 - 4
frontend/app_flowy/lib/user/application/sign_in_bloc.dart

@@ -1,7 +1,7 @@
 import 'package:app_flowy/user/domain/i_auth.dart';
 import 'package:dartz/dartz.dart';
-import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile, ErrorCode;
-import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile, ErrorCode;
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
@@ -40,7 +40,7 @@ class SignInBloc extends Bloc<SignInEvent, SignInState> {
     );
   }
 
-  SignInState stateFromCode(UserError error) {
+  SignInState stateFromCode(FlowyError error) {
     switch (ErrorCode.valueOf(error.code)!) {
       case ErrorCode.EmailFormatInvalid:
         return state.copyWith(isSubmitting: false, emailError: some(error.msg), passwordError: none());
@@ -67,7 +67,7 @@ abstract class SignInState with _$SignInState {
     required bool isSubmitting,
     required Option<String> passwordError,
     required Option<String> emailError,
-    required Option<Either<UserProfile, UserError>> successOrFail,
+    required Option<Either<UserProfile, FlowyError>> successOrFail,
   }) = _SignInState;
 
   factory SignInState.initial() => SignInState(

+ 9 - 9
frontend/app_flowy/lib/user/application/sign_in_bloc.freezed.dart

@@ -519,7 +519,7 @@ class _$SignInStateTearOff {
       required bool isSubmitting,
       required Option<String> passwordError,
       required Option<String> emailError,
-      required Option<Either<UserProfile, UserError>> successOrFail}) {
+      required Option<Either<UserProfile, FlowyError>> successOrFail}) {
     return _SignInState(
       email: email,
       password: password,
@@ -541,7 +541,7 @@ mixin _$SignInState {
   bool get isSubmitting => throw _privateConstructorUsedError;
   Option<String> get passwordError => throw _privateConstructorUsedError;
   Option<String> get emailError => throw _privateConstructorUsedError;
-  Option<Either<UserProfile, UserError>> get successOrFail =>
+  Option<Either<UserProfile, FlowyError>> get successOrFail =>
       throw _privateConstructorUsedError;
 
   @JsonKey(ignore: true)
@@ -560,7 +560,7 @@ abstract class $SignInStateCopyWith<$Res> {
       bool isSubmitting,
       Option<String> passwordError,
       Option<String> emailError,
-      Option<Either<UserProfile, UserError>> successOrFail});
+      Option<Either<UserProfile, FlowyError>> successOrFail});
 }
 
 /// @nodoc
@@ -604,7 +604,7 @@ class _$SignInStateCopyWithImpl<$Res> implements $SignInStateCopyWith<$Res> {
       successOrFail: successOrFail == freezed
           ? _value.successOrFail
           : successOrFail // ignore: cast_nullable_to_non_nullable
-              as Option<Either<UserProfile, UserError>>,
+              as Option<Either<UserProfile, FlowyError>>,
     ));
   }
 }
@@ -622,7 +622,7 @@ abstract class _$SignInStateCopyWith<$Res>
       bool isSubmitting,
       Option<String> passwordError,
       Option<String> emailError,
-      Option<Either<UserProfile, UserError>> successOrFail});
+      Option<Either<UserProfile, FlowyError>> successOrFail});
 }
 
 /// @nodoc
@@ -668,7 +668,7 @@ class __$SignInStateCopyWithImpl<$Res> extends _$SignInStateCopyWithImpl<$Res>
       successOrFail: successOrFail == freezed
           ? _value.successOrFail
           : successOrFail // ignore: cast_nullable_to_non_nullable
-              as Option<Either<UserProfile, UserError>>,
+              as Option<Either<UserProfile, FlowyError>>,
     ));
   }
 }
@@ -695,7 +695,7 @@ class _$_SignInState implements _SignInState {
   @override
   final Option<String> emailError;
   @override
-  final Option<Either<UserProfile, UserError>> successOrFail;
+  final Option<Either<UserProfile, FlowyError>> successOrFail;
 
   @override
   String toString() {
@@ -748,7 +748,7 @@ abstract class _SignInState implements SignInState {
           required bool isSubmitting,
           required Option<String> passwordError,
           required Option<String> emailError,
-          required Option<Either<UserProfile, UserError>> successOrFail}) =
+          required Option<Either<UserProfile, FlowyError>> successOrFail}) =
       _$_SignInState;
 
   @override
@@ -762,7 +762,7 @@ abstract class _SignInState implements SignInState {
   @override
   Option<String> get emailError => throw _privateConstructorUsedError;
   @override
-  Option<Either<UserProfile, UserError>> get successOrFail =>
+  Option<Either<UserProfile, FlowyError>> get successOrFail =>
       throw _privateConstructorUsedError;
   @override
   @JsonKey(ignore: true)

+ 4 - 4
frontend/app_flowy/lib/user/application/sign_up_bloc.dart

@@ -1,8 +1,8 @@
 import 'package:app_flowy/user/domain/i_auth.dart';
 import 'package:dartz/dartz.dart';
 import 'package:easy_localization/easy_localization.dart';
-import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile, ErrorCode;
-import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile, ErrorCode;
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:app_flowy/generated/locale_keys.g.dart';
@@ -78,7 +78,7 @@ class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
     );
   }
 
-  SignUpState stateFromCode(UserError error) {
+  SignUpState stateFromCode(FlowyError error) {
     switch (ErrorCode.valueOf(error.code)!) {
       case ErrorCode.EmailFormatInvalid:
         return state.copyWith(
@@ -118,7 +118,7 @@ class SignUpState with _$SignUpState {
     required Option<String> passwordError,
     required Option<String> repeatPasswordError,
     required Option<String> emailError,
-    required Option<Either<UserProfile, UserError>> successOrFail,
+    required Option<Either<UserProfile, FlowyError>> successOrFail,
   }) = _SignUpState;
 
   factory SignUpState.initial() => SignUpState(

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

@@ -707,7 +707,7 @@ class _$SignUpStateTearOff {
       required Option<String> passwordError,
       required Option<String> repeatPasswordError,
       required Option<String> emailError,
-      required Option<Either<UserProfile, UserError>> successOrFail}) {
+      required Option<Either<UserProfile, FlowyError>> successOrFail}) {
     return _SignUpState(
       email: email,
       password: password,
@@ -733,7 +733,7 @@ mixin _$SignUpState {
   Option<String> get passwordError => throw _privateConstructorUsedError;
   Option<String> get repeatPasswordError => throw _privateConstructorUsedError;
   Option<String> get emailError => throw _privateConstructorUsedError;
-  Option<Either<UserProfile, UserError>> get successOrFail =>
+  Option<Either<UserProfile, FlowyError>> get successOrFail =>
       throw _privateConstructorUsedError;
 
   @JsonKey(ignore: true)
@@ -754,7 +754,7 @@ abstract class $SignUpStateCopyWith<$Res> {
       Option<String> passwordError,
       Option<String> repeatPasswordError,
       Option<String> emailError,
-      Option<Either<UserProfile, UserError>> successOrFail});
+      Option<Either<UserProfile, FlowyError>> successOrFail});
 }
 
 /// @nodoc
@@ -808,7 +808,7 @@ class _$SignUpStateCopyWithImpl<$Res> implements $SignUpStateCopyWith<$Res> {
       successOrFail: successOrFail == freezed
           ? _value.successOrFail
           : successOrFail // ignore: cast_nullable_to_non_nullable
-              as Option<Either<UserProfile, UserError>>,
+              as Option<Either<UserProfile, FlowyError>>,
     ));
   }
 }
@@ -828,7 +828,7 @@ abstract class _$SignUpStateCopyWith<$Res>
       Option<String> passwordError,
       Option<String> repeatPasswordError,
       Option<String> emailError,
-      Option<Either<UserProfile, UserError>> successOrFail});
+      Option<Either<UserProfile, FlowyError>> successOrFail});
 }
 
 /// @nodoc
@@ -884,7 +884,7 @@ class __$SignUpStateCopyWithImpl<$Res> extends _$SignUpStateCopyWithImpl<$Res>
       successOrFail: successOrFail == freezed
           ? _value.successOrFail
           : successOrFail // ignore: cast_nullable_to_non_nullable
-              as Option<Either<UserProfile, UserError>>,
+              as Option<Either<UserProfile, FlowyError>>,
     ));
   }
 }
@@ -917,7 +917,7 @@ class _$_SignUpState implements _SignUpState {
   @override
   final Option<String> emailError;
   @override
-  final Option<Either<UserProfile, UserError>> successOrFail;
+  final Option<Either<UserProfile, FlowyError>> successOrFail;
 
   @override
   String toString() {
@@ -980,7 +980,7 @@ abstract class _SignUpState implements SignUpState {
           required Option<String> passwordError,
           required Option<String> repeatPasswordError,
           required Option<String> emailError,
-          required Option<Either<UserProfile, UserError>> successOrFail}) =
+          required Option<Either<UserProfile, FlowyError>> successOrFail}) =
       _$_SignUpState;
 
   @override
@@ -998,7 +998,7 @@ abstract class _SignUpState implements SignUpState {
   @override
   Option<String> get emailError => throw _privateConstructorUsedError;
   @override
-  Option<Either<UserProfile, UserError>> get successOrFail =>
+  Option<Either<UserProfile, FlowyError>> get successOrFail =>
       throw _privateConstructorUsedError;
   @override
   @JsonKey(ignore: true)

+ 3 - 3
frontend/app_flowy/lib/user/domain/auth_state.dart

@@ -1,11 +1,11 @@
-import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
-import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile;
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 part 'auth_state.freezed.dart';
 
 @freezed
 abstract class AuthState with _$AuthState {
   const factory AuthState.authenticated(UserProfile userProfile) = Authenticated;
-  const factory AuthState.unauthenticated(UserError error) = Unauthenticated;
+  const factory AuthState.unauthenticated(FlowyError error) = Unauthenticated;
   const factory AuthState.initial() = _Initial;
 }

+ 18 - 18
frontend/app_flowy/lib/user/domain/auth_state.freezed.dart

@@ -23,7 +23,7 @@ class _$AuthStateTearOff {
     );
   }
 
-  Unauthenticated unauthenticated(UserError error) {
+  Unauthenticated unauthenticated(FlowyError error) {
     return Unauthenticated(
       error,
     );
@@ -42,21 +42,21 @@ mixin _$AuthState {
   @optionalTypeArgs
   TResult when<TResult extends Object?>({
     required TResult Function(UserProfile userProfile) authenticated,
-    required TResult Function(UserError error) unauthenticated,
+    required TResult Function(FlowyError error) unauthenticated,
     required TResult Function() initial,
   }) =>
       throw _privateConstructorUsedError;
   @optionalTypeArgs
   TResult? whenOrNull<TResult extends Object?>({
     TResult Function(UserProfile userProfile)? authenticated,
-    TResult Function(UserError error)? unauthenticated,
+    TResult Function(FlowyError error)? unauthenticated,
     TResult Function()? initial,
   }) =>
       throw _privateConstructorUsedError;
   @optionalTypeArgs
   TResult maybeWhen<TResult extends Object?>({
     TResult Function(UserProfile userProfile)? authenticated,
-    TResult Function(UserError error)? unauthenticated,
+    TResult Function(FlowyError error)? unauthenticated,
     TResult Function()? initial,
     required TResult orElse(),
   }) =>
@@ -166,7 +166,7 @@ class _$Authenticated implements Authenticated {
   @optionalTypeArgs
   TResult when<TResult extends Object?>({
     required TResult Function(UserProfile userProfile) authenticated,
-    required TResult Function(UserError error) unauthenticated,
+    required TResult Function(FlowyError error) unauthenticated,
     required TResult Function() initial,
   }) {
     return authenticated(userProfile);
@@ -176,7 +176,7 @@ class _$Authenticated implements Authenticated {
   @optionalTypeArgs
   TResult? whenOrNull<TResult extends Object?>({
     TResult Function(UserProfile userProfile)? authenticated,
-    TResult Function(UserError error)? unauthenticated,
+    TResult Function(FlowyError error)? unauthenticated,
     TResult Function()? initial,
   }) {
     return authenticated?.call(userProfile);
@@ -186,7 +186,7 @@ class _$Authenticated implements Authenticated {
   @optionalTypeArgs
   TResult maybeWhen<TResult extends Object?>({
     TResult Function(UserProfile userProfile)? authenticated,
-    TResult Function(UserError error)? unauthenticated,
+    TResult Function(FlowyError error)? unauthenticated,
     TResult Function()? initial,
     required TResult orElse(),
   }) {
@@ -245,7 +245,7 @@ abstract class $UnauthenticatedCopyWith<$Res> {
   factory $UnauthenticatedCopyWith(
           Unauthenticated value, $Res Function(Unauthenticated) then) =
       _$UnauthenticatedCopyWithImpl<$Res>;
-  $Res call({UserError error});
+  $Res call({FlowyError error});
 }
 
 /// @nodoc
@@ -266,7 +266,7 @@ class _$UnauthenticatedCopyWithImpl<$Res> extends _$AuthStateCopyWithImpl<$Res>
       error == freezed
           ? _value.error
           : error // ignore: cast_nullable_to_non_nullable
-              as UserError,
+              as FlowyError,
     ));
   }
 }
@@ -277,7 +277,7 @@ class _$Unauthenticated implements Unauthenticated {
   const _$Unauthenticated(this.error);
 
   @override
-  final UserError error;
+  final FlowyError error;
 
   @override
   String toString() {
@@ -305,7 +305,7 @@ class _$Unauthenticated implements Unauthenticated {
   @optionalTypeArgs
   TResult when<TResult extends Object?>({
     required TResult Function(UserProfile userProfile) authenticated,
-    required TResult Function(UserError error) unauthenticated,
+    required TResult Function(FlowyError error) unauthenticated,
     required TResult Function() initial,
   }) {
     return unauthenticated(error);
@@ -315,7 +315,7 @@ class _$Unauthenticated implements Unauthenticated {
   @optionalTypeArgs
   TResult? whenOrNull<TResult extends Object?>({
     TResult Function(UserProfile userProfile)? authenticated,
-    TResult Function(UserError error)? unauthenticated,
+    TResult Function(FlowyError error)? unauthenticated,
     TResult Function()? initial,
   }) {
     return unauthenticated?.call(error);
@@ -325,7 +325,7 @@ class _$Unauthenticated implements Unauthenticated {
   @optionalTypeArgs
   TResult maybeWhen<TResult extends Object?>({
     TResult Function(UserProfile userProfile)? authenticated,
-    TResult Function(UserError error)? unauthenticated,
+    TResult Function(FlowyError error)? unauthenticated,
     TResult Function()? initial,
     required TResult orElse(),
   }) {
@@ -371,9 +371,9 @@ class _$Unauthenticated implements Unauthenticated {
 }
 
 abstract class Unauthenticated implements AuthState {
-  const factory Unauthenticated(UserError error) = _$Unauthenticated;
+  const factory Unauthenticated(FlowyError error) = _$Unauthenticated;
 
-  UserError get error => throw _privateConstructorUsedError;
+  FlowyError get error => throw _privateConstructorUsedError;
   @JsonKey(ignore: true)
   $UnauthenticatedCopyWith<Unauthenticated> get copyWith =>
       throw _privateConstructorUsedError;
@@ -417,7 +417,7 @@ class _$_Initial implements _Initial {
   @optionalTypeArgs
   TResult when<TResult extends Object?>({
     required TResult Function(UserProfile userProfile) authenticated,
-    required TResult Function(UserError error) unauthenticated,
+    required TResult Function(FlowyError error) unauthenticated,
     required TResult Function() initial,
   }) {
     return initial();
@@ -427,7 +427,7 @@ class _$_Initial implements _Initial {
   @optionalTypeArgs
   TResult? whenOrNull<TResult extends Object?>({
     TResult Function(UserProfile userProfile)? authenticated,
-    TResult Function(UserError error)? unauthenticated,
+    TResult Function(FlowyError error)? unauthenticated,
     TResult Function()? initial,
   }) {
     return initial?.call();
@@ -437,7 +437,7 @@ class _$_Initial implements _Initial {
   @optionalTypeArgs
   TResult maybeWhen<TResult extends Object?>({
     TResult Function(UserProfile userProfile)? authenticated,
-    TResult Function(UserError error)? unauthenticated,
+    TResult Function(FlowyError error)? unauthenticated,
     TResult Function()? initial,
     required TResult orElse(),
   }) {

+ 6 - 6
frontend/app_flowy/lib/user/domain/i_auth.dart

@@ -1,7 +1,7 @@
 import 'package:dartz/dartz.dart';
-import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
-import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/protobuf.dart';
+import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile;
 import 'package:flutter/material.dart';
 
 class NewUser {
@@ -14,9 +14,9 @@ class NewUser {
 }
 
 abstract class IAuth {
-  Future<Either<UserProfile, UserError>> signIn(String? email, String? password);
-  Future<Either<UserProfile, UserError>> signUp(String? name, String? password, String? email);
-  Future<Either<Unit, UserError>> signOut();
+  Future<Either<UserProfile, FlowyError>> signIn(String? email, String? password);
+  Future<Either<UserProfile, FlowyError>> signUp(String? name, String? password, String? email);
+  Future<Either<Unit, FlowyError>> signOut();
 }
 
 abstract class IAuthRouter {

+ 2 - 2
frontend/app_flowy/lib/user/domain/i_splash.dart

@@ -1,5 +1,5 @@
-import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
+import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile;
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/protobuf.dart';
 import 'package:flutter/widgets.dart';
 
 import 'auth_state.dart';

+ 3 - 6
frontend/app_flowy/lib/user/infrastructure/deps_resolver.dart

@@ -11,7 +11,6 @@ import 'package:app_flowy/workspace/application/home/home_bloc.dart';
 import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart';
 import 'package:app_flowy/workspace/domain/i_user.dart';
 import 'package:app_flowy/workspace/infrastructure/i_user_impl.dart';
-import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
 import 'package:get_it/get_it.dart';
 
 import 'network_monitor.dart';
@@ -34,11 +33,9 @@ class UserDepsResolver {
     getIt.registerFactory<EditPannelBloc>(() => EditPannelBloc());
     getIt.registerFactory<SplashBloc>(() => SplashBloc(getIt<ISplashUser>()));
 
-    getIt.registerFactoryParam<HomeListenBloc, UserProfile, void>(
-      (user, _) => HomeListenBloc(
-        getIt<IUserListener>(param1: user),
-      ),
-    );
+    getIt.registerFactoryParam<HomeListenBloc, UserProfile, void>((user, _) => HomeListenBloc(
+          getIt<IUserListener>(param1: user),
+        ));
 
     getIt.registerLazySingleton<NetworkMonitor>(() => NetworkMonitor());
   }

+ 6 - 6
frontend/app_flowy/lib/user/infrastructure/i_auth_impl.dart

@@ -5,11 +5,11 @@ import 'package:app_flowy/workspace/presentation/home/home_screen.dart';
 import 'package:dartz/dartz.dart';
 import 'package:flowy_infra/time/duration.dart';
 import 'package:flowy_infra_ui/widget/route/animation.dart';
-import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
+import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile;
 import 'package:app_flowy/user/domain/i_auth.dart';
 import 'package:app_flowy/user/infrastructure/repos/auth_repo.dart';
-import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/protobuf.dart';
 import 'package:flutter/material.dart';
 
 class AuthImpl extends IAuth {
@@ -19,17 +19,17 @@ class AuthImpl extends IAuth {
   });
 
   @override
-  Future<Either<UserProfile, UserError>> signIn(String? email, String? password) {
+  Future<Either<UserProfile, FlowyError>> signIn(String? email, String? password) {
     return repo.signIn(email: email, password: password);
   }
 
   @override
-  Future<Either<UserProfile, UserError>> signUp(String? name, String? password, String? email) {
+  Future<Either<UserProfile, FlowyError>> signUp(String? name, String? password, String? email) {
     return repo.signUp(name: name, password: password, email: email);
   }
 
   @override
-  Future<Either<Unit, UserError>> signOut() {
+  Future<Either<Unit, FlowyError>> signOut() {
     return repo.signOut();
   }
 }

+ 4 - 4
frontend/app_flowy/lib/user/infrastructure/i_splash_impl.dart

@@ -10,8 +10,8 @@ import 'package:app_flowy/workspace/presentation/home/home_screen.dart';
 import 'package:flowy_infra/time/duration.dart';
 import 'package:flowy_infra_ui/widget/route/animation.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
-import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
+import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile;
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/protobuf.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/widgets.dart';
 
@@ -24,8 +24,8 @@ class SplashUserImpl implements ISplashUser {
         (userProfile) {
           return AuthState.authenticated(userProfile);
         },
-        (userError) {
-          return AuthState.unauthenticated(userError);
+        (FlowyError) {
+          return AuthState.unauthenticated(FlowyError);
         },
       );
     });

+ 2 - 2
frontend/app_flowy/lib/user/infrastructure/network_monitor.dart

@@ -3,7 +3,7 @@ import 'dart:async';
 import 'package:connectivity_plus/connectivity_plus.dart';
 import 'package:flowy_log/flowy_log.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
-import 'package:flowy_sdk/protobuf/lib-infra/protobuf.dart';
+import 'package:flowy_sdk/protobuf/flowy-net/network_state.pb.dart';
 import 'package:flutter/services.dart';
 
 class NetworkMonitor {
@@ -45,7 +45,7 @@ class NetworkMonitor {
     }();
     Log.info("Network type: $networkType");
     final state = NetworkState.create()..ty = networkType;
-    UserEventUpdateNetworkType(state).send().then((result) {
+    NetworkEventUpdateNetworkType(state).send().then((result) {
       result.fold(
         (l) {},
         (e) => Log.error(e),

+ 5 - 5
frontend/app_flowy/lib/user/infrastructure/repos/auth_repo.dart

@@ -1,10 +1,10 @@
 import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
-import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show SignInRequest, SignUpRequest, UserProfile;
-import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show SignInRequest, SignUpRequest, UserProfile;
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 
 class AuthRepository {
-  Future<Either<UserProfile, UserError>> signIn({required String? email, required String? password}) {
+  Future<Either<UserProfile, FlowyError>> signIn({required String? email, required String? password}) {
     //
     final request = SignInRequest.create()
       ..email = email ?? ''
@@ -13,7 +13,7 @@ class AuthRepository {
     return UserEventSignIn(request).send();
   }
 
-  Future<Either<UserProfile, UserError>> signUp(
+  Future<Either<UserProfile, FlowyError>> signUp(
       {required String? name, required String? password, required String? email}) {
     final request = SignUpRequest.create()
       ..email = email ?? ''
@@ -35,7 +35,7 @@ class AuthRepository {
     // });
   }
 
-  Future<Either<Unit, UserError>> signOut() {
+  Future<Either<Unit, FlowyError>> signOut() {
     return UserEventSignOut().send();
   }
 }

+ 3 - 3
frontend/app_flowy/lib/user/presentation/sign_in_screen.dart

@@ -9,8 +9,8 @@ import 'package:flowy_infra_ui/widget/rounded_button.dart';
 import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
 import 'package:flowy_infra_ui/style_widget/snap_bar.dart';
-import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile;
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:dartz/dartz.dart';
@@ -39,7 +39,7 @@ class SignInScreen extends StatelessWidget {
     );
   }
 
-  void _handleSuccessOrFail(Either<UserProfile, UserError> result, BuildContext context) {
+  void _handleSuccessOrFail(Either<UserProfile, FlowyError> result, BuildContext context) {
     result.fold(
       (user) => router.pushWelcomeScreen(context, user),
       (error) => showSnapBar(context, error.msg),

+ 3 - 3
frontend/app_flowy/lib/user/presentation/sign_up_screen.dart

@@ -7,8 +7,8 @@ import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/widget/rounded_button.dart';
 import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
-import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile;
 import 'package:flowy_infra_ui/style_widget/snap_bar.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
@@ -36,7 +36,7 @@ class SignUpScreen extends StatelessWidget {
     );
   }
 
-  void _handleSuccessOrFail(BuildContext context, Either<UserProfile, UserError> result) {
+  void _handleSuccessOrFail(BuildContext context, Either<UserProfile, FlowyError> result) {
     result.fold(
       (user) => router.pushWelcomeScreen(context, user),
       (error) => showSnapBar(context, error.msg),

+ 3 - 4
frontend/app_flowy/lib/user/presentation/skip_log_in_screen.dart

@@ -9,9 +9,8 @@ import 'package:flowy_infra_ui/widget/rounded_button.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
 import 'package:flowy_log/flowy_log.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/protobuf.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:url_launcher/url_launcher.dart';
@@ -114,7 +113,7 @@ class _SkipLogInScreenState extends State<SkipLogInScreen> {
   void _openCurrentWorkspace(
     BuildContext context,
     UserProfile user,
-    dartz.Either<CurrentWorkspaceSetting, WorkspaceError> workspacesOrError,
+    dartz.Either<CurrentWorkspaceSetting, FlowyError> workspacesOrError,
   ) {
     workspacesOrError.fold(
       (workspaceSetting) {

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

@@ -3,7 +3,7 @@ import 'package:app_flowy/user/application/splash_bloc.dart';
 import 'package:app_flowy/user/domain/auth_state.dart';
 import 'package:app_flowy/user/domain/i_splash.dart';
 import 'package:flowy_sdk/dispatch/dispatch.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/errors.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 

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

@@ -5,7 +5,7 @@ import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
 import 'package:flowy_infra_ui/style_widget/button.dart';
 import 'package:flowy_infra_ui/widget/error_page.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/workspace_create.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/workspace_create.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';

+ 5 - 5
frontend/app_flowy/lib/workspace/application/app/app_bloc.dart

@@ -1,8 +1,8 @@
 import 'package:app_flowy/workspace/domain/i_app.dart';
 import 'package:flowy_log/flowy_log.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/app_create.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/view_create.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/app_create.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/view_create.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:dartz/dartz.dart';
@@ -61,7 +61,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
     return super.close();
   }
 
-  void _handleViewsChanged(Either<List<View>, WorkspaceError> result) {
+  void _handleViewsChanged(Either<List<View>, FlowyError> result) {
     result.fold(
       (views) => add(AppEvent.didReceiveViews(views)),
       (error) {
@@ -112,7 +112,7 @@ class AppState with _$AppState {
     required bool isLoading,
     required List<View>? views,
     View? latestCreatedView,
-    required Either<Unit, WorkspaceError> successOrFailure,
+    required Either<Unit, FlowyError> successOrFailure,
   }) = _AppState;
 
   factory AppState.initial(App app) => AppState(

+ 9 - 9
frontend/app_flowy/lib/workspace/application/app/app_bloc.freezed.dart

@@ -1051,7 +1051,7 @@ class _$AppStateTearOff {
       required bool isLoading,
       required List<View>? views,
       View? latestCreatedView,
-      required Either<Unit, WorkspaceError> successOrFailure}) {
+      required Either<Unit, FlowyError> successOrFailure}) {
     return _AppState(
       app: app,
       isLoading: isLoading,
@@ -1071,7 +1071,7 @@ mixin _$AppState {
   bool get isLoading => throw _privateConstructorUsedError;
   List<View>? get views => throw _privateConstructorUsedError;
   View? get latestCreatedView => throw _privateConstructorUsedError;
-  Either<Unit, WorkspaceError> get successOrFailure =>
+  Either<Unit, FlowyError> get successOrFailure =>
       throw _privateConstructorUsedError;
 
   @JsonKey(ignore: true)
@@ -1088,7 +1088,7 @@ abstract class $AppStateCopyWith<$Res> {
       bool isLoading,
       List<View>? views,
       View? latestCreatedView,
-      Either<Unit, WorkspaceError> successOrFailure});
+      Either<Unit, FlowyError> successOrFailure});
 }
 
 /// @nodoc
@@ -1127,7 +1127,7 @@ class _$AppStateCopyWithImpl<$Res> implements $AppStateCopyWith<$Res> {
       successOrFailure: successOrFailure == freezed
           ? _value.successOrFailure
           : successOrFailure // ignore: cast_nullable_to_non_nullable
-              as Either<Unit, WorkspaceError>,
+              as Either<Unit, FlowyError>,
     ));
   }
 }
@@ -1142,7 +1142,7 @@ abstract class _$AppStateCopyWith<$Res> implements $AppStateCopyWith<$Res> {
       bool isLoading,
       List<View>? views,
       View? latestCreatedView,
-      Either<Unit, WorkspaceError> successOrFailure});
+      Either<Unit, FlowyError> successOrFailure});
 }
 
 /// @nodoc
@@ -1182,7 +1182,7 @@ class __$AppStateCopyWithImpl<$Res> extends _$AppStateCopyWithImpl<$Res>
       successOrFailure: successOrFailure == freezed
           ? _value.successOrFailure
           : successOrFailure // ignore: cast_nullable_to_non_nullable
-              as Either<Unit, WorkspaceError>,
+              as Either<Unit, FlowyError>,
     ));
   }
 }
@@ -1206,7 +1206,7 @@ class _$_AppState implements _AppState {
   @override
   final View? latestCreatedView;
   @override
-  final Either<Unit, WorkspaceError> successOrFailure;
+  final Either<Unit, FlowyError> successOrFailure;
 
   @override
   String toString() {
@@ -1253,7 +1253,7 @@ abstract class _AppState implements AppState {
       required bool isLoading,
       required List<View>? views,
       View? latestCreatedView,
-      required Either<Unit, WorkspaceError> successOrFailure}) = _$_AppState;
+      required Either<Unit, FlowyError> successOrFailure}) = _$_AppState;
 
   @override
   App get app => throw _privateConstructorUsedError;
@@ -1264,7 +1264,7 @@ abstract class _AppState implements AppState {
   @override
   View? get latestCreatedView => throw _privateConstructorUsedError;
   @override
-  Either<Unit, WorkspaceError> get successOrFailure =>
+  Either<Unit, FlowyError> get successOrFailure =>
       throw _privateConstructorUsedError;
   @override
   @JsonKey(ignore: true)

+ 4 - 4
frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart

@@ -2,9 +2,9 @@ import 'dart:convert';
 
 import 'package:app_flowy/workspace/domain/i_trash.dart';
 import 'package:app_flowy/workspace/domain/i_view.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/trash_create.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/view_create.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/trash_create.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/view_create.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flutter_quill/flutter_quill.dart';
 import 'package:flowy_log/flowy_log.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
@@ -155,5 +155,5 @@ class DocState with _$DocState {
 @freezed
 class DocLoadState with _$DocLoadState {
   const factory DocLoadState.loading() = _Loading;
-  const factory DocLoadState.finish(Either<Unit, WorkspaceError> successOrFail) = _Finish;
+  const factory DocLoadState.finish(Either<Unit, FlowyError> successOrFail) = _Finish;
 }

+ 15 - 15
frontend/app_flowy/lib/workspace/application/doc/doc_bloc.freezed.dart

@@ -909,7 +909,7 @@ class _$DocLoadStateTearOff {
     return const _Loading();
   }
 
-  _Finish finish(Either<Unit, WorkspaceError> successOrFail) {
+  _Finish finish(Either<Unit, FlowyError> successOrFail) {
     return _Finish(
       successOrFail,
     );
@@ -924,20 +924,20 @@ mixin _$DocLoadState {
   @optionalTypeArgs
   TResult when<TResult extends Object?>({
     required TResult Function() loading,
-    required TResult Function(Either<Unit, WorkspaceError> successOrFail)
+    required TResult Function(Either<Unit, FlowyError> successOrFail)
         finish,
   }) =>
       throw _privateConstructorUsedError;
   @optionalTypeArgs
   TResult? whenOrNull<TResult extends Object?>({
     TResult Function()? loading,
-    TResult Function(Either<Unit, WorkspaceError> successOrFail)? finish,
+    TResult Function(Either<Unit, FlowyError> successOrFail)? finish,
   }) =>
       throw _privateConstructorUsedError;
   @optionalTypeArgs
   TResult maybeWhen<TResult extends Object?>({
     TResult Function()? loading,
-    TResult Function(Either<Unit, WorkspaceError> successOrFail)? finish,
+    TResult Function(Either<Unit, FlowyError> successOrFail)? finish,
     required TResult orElse(),
   }) =>
       throw _privateConstructorUsedError;
@@ -1016,7 +1016,7 @@ class _$_Loading implements _Loading {
   @optionalTypeArgs
   TResult when<TResult extends Object?>({
     required TResult Function() loading,
-    required TResult Function(Either<Unit, WorkspaceError> successOrFail)
+    required TResult Function(Either<Unit, FlowyError> successOrFail)
         finish,
   }) {
     return loading();
@@ -1026,7 +1026,7 @@ class _$_Loading implements _Loading {
   @optionalTypeArgs
   TResult? whenOrNull<TResult extends Object?>({
     TResult Function()? loading,
-    TResult Function(Either<Unit, WorkspaceError> successOrFail)? finish,
+    TResult Function(Either<Unit, FlowyError> successOrFail)? finish,
   }) {
     return loading?.call();
   }
@@ -1035,7 +1035,7 @@ class _$_Loading implements _Loading {
   @optionalTypeArgs
   TResult maybeWhen<TResult extends Object?>({
     TResult Function()? loading,
-    TResult Function(Either<Unit, WorkspaceError> successOrFail)? finish,
+    TResult Function(Either<Unit, FlowyError> successOrFail)? finish,
     required TResult orElse(),
   }) {
     if (loading != null) {
@@ -1084,7 +1084,7 @@ abstract class _Loading implements DocLoadState {
 abstract class _$FinishCopyWith<$Res> {
   factory _$FinishCopyWith(_Finish value, $Res Function(_Finish) then) =
       __$FinishCopyWithImpl<$Res>;
-  $Res call({Either<Unit, WorkspaceError> successOrFail});
+  $Res call({Either<Unit, FlowyError> successOrFail});
 }
 
 /// @nodoc
@@ -1104,7 +1104,7 @@ class __$FinishCopyWithImpl<$Res> extends _$DocLoadStateCopyWithImpl<$Res>
       successOrFail == freezed
           ? _value.successOrFail
           : successOrFail // ignore: cast_nullable_to_non_nullable
-              as Either<Unit, WorkspaceError>,
+              as Either<Unit, FlowyError>,
     ));
   }
 }
@@ -1115,7 +1115,7 @@ class _$_Finish implements _Finish {
   const _$_Finish(this.successOrFail);
 
   @override
-  final Either<Unit, WorkspaceError> successOrFail;
+  final Either<Unit, FlowyError> successOrFail;
 
   @override
   String toString() {
@@ -1144,7 +1144,7 @@ class _$_Finish implements _Finish {
   @optionalTypeArgs
   TResult when<TResult extends Object?>({
     required TResult Function() loading,
-    required TResult Function(Either<Unit, WorkspaceError> successOrFail)
+    required TResult Function(Either<Unit, FlowyError> successOrFail)
         finish,
   }) {
     return finish(successOrFail);
@@ -1154,7 +1154,7 @@ class _$_Finish implements _Finish {
   @optionalTypeArgs
   TResult? whenOrNull<TResult extends Object?>({
     TResult Function()? loading,
-    TResult Function(Either<Unit, WorkspaceError> successOrFail)? finish,
+    TResult Function(Either<Unit, FlowyError> successOrFail)? finish,
   }) {
     return finish?.call(successOrFail);
   }
@@ -1163,7 +1163,7 @@ class _$_Finish implements _Finish {
   @optionalTypeArgs
   TResult maybeWhen<TResult extends Object?>({
     TResult Function()? loading,
-    TResult Function(Either<Unit, WorkspaceError> successOrFail)? finish,
+    TResult Function(Either<Unit, FlowyError> successOrFail)? finish,
     required TResult orElse(),
   }) {
     if (finish != null) {
@@ -1205,9 +1205,9 @@ class _$_Finish implements _Finish {
 }
 
 abstract class _Finish implements DocLoadState {
-  const factory _Finish(Either<Unit, WorkspaceError> successOrFail) = _$_Finish;
+  const factory _Finish(Either<Unit, FlowyError> successOrFail) = _$_Finish;
 
-  Either<Unit, WorkspaceError> get successOrFail =>
+  Either<Unit, FlowyError> get successOrFail =>
       throw _privateConstructorUsedError;
   @JsonKey(ignore: true)
   _$FinishCopyWith<_Finish> get copyWith => throw _privateConstructorUsedError;

+ 4 - 4
frontend/app_flowy/lib/workspace/application/doc/share_bloc.dart

@@ -1,8 +1,8 @@
 import 'package:app_flowy/workspace/domain/i_share.dart';
 import 'package:app_flowy/workspace/infrastructure/markdown/delta_markdown.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/export.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/view_create.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/export.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/view_create.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:dartz/dartz.dart';
@@ -48,5 +48,5 @@ class DocShareEvent with _$DocShareEvent {
 class DocShareState with _$DocShareState {
   const factory DocShareState.initial() = _Initial;
   const factory DocShareState.loading() = _Loading;
-  const factory DocShareState.finish(Either<ExportData, WorkspaceError> successOrFail) = _Finish;
+  const factory DocShareState.finish(Either<ExportData, FlowyError> successOrFail) = _Finish;
 }

+ 18 - 18
frontend/app_flowy/lib/workspace/application/doc/share_bloc.freezed.dart

@@ -434,7 +434,7 @@ class _$DocShareStateTearOff {
     return const _Loading();
   }
 
-  _Finish finish(Either<ExportData, WorkspaceError> successOrFail) {
+  _Finish finish(Either<ExportData, FlowyError> successOrFail) {
     return _Finish(
       successOrFail,
     );
@@ -450,7 +450,7 @@ mixin _$DocShareState {
   TResult when<TResult extends Object?>({
     required TResult Function() initial,
     required TResult Function() loading,
-    required TResult Function(Either<ExportData, WorkspaceError> successOrFail)
+    required TResult Function(Either<ExportData, FlowyError> successOrFail)
         finish,
   }) =>
       throw _privateConstructorUsedError;
@@ -458,14 +458,14 @@ mixin _$DocShareState {
   TResult? whenOrNull<TResult extends Object?>({
     TResult Function()? initial,
     TResult Function()? loading,
-    TResult Function(Either<ExportData, WorkspaceError> successOrFail)? finish,
+    TResult Function(Either<ExportData, FlowyError> successOrFail)? finish,
   }) =>
       throw _privateConstructorUsedError;
   @optionalTypeArgs
   TResult maybeWhen<TResult extends Object?>({
     TResult Function()? initial,
     TResult Function()? loading,
-    TResult Function(Either<ExportData, WorkspaceError> successOrFail)? finish,
+    TResult Function(Either<ExportData, FlowyError> successOrFail)? finish,
     required TResult orElse(),
   }) =>
       throw _privateConstructorUsedError;
@@ -549,7 +549,7 @@ class _$_Initial implements _Initial {
   TResult when<TResult extends Object?>({
     required TResult Function() initial,
     required TResult Function() loading,
-    required TResult Function(Either<ExportData, WorkspaceError> successOrFail)
+    required TResult Function(Either<ExportData, FlowyError> successOrFail)
         finish,
   }) {
     return initial();
@@ -560,7 +560,7 @@ class _$_Initial implements _Initial {
   TResult? whenOrNull<TResult extends Object?>({
     TResult Function()? initial,
     TResult Function()? loading,
-    TResult Function(Either<ExportData, WorkspaceError> successOrFail)? finish,
+    TResult Function(Either<ExportData, FlowyError> successOrFail)? finish,
   }) {
     return initial?.call();
   }
@@ -570,7 +570,7 @@ class _$_Initial implements _Initial {
   TResult maybeWhen<TResult extends Object?>({
     TResult Function()? initial,
     TResult Function()? loading,
-    TResult Function(Either<ExportData, WorkspaceError> successOrFail)? finish,
+    TResult Function(Either<ExportData, FlowyError> successOrFail)? finish,
     required TResult orElse(),
   }) {
     if (initial != null) {
@@ -657,7 +657,7 @@ class _$_Loading implements _Loading {
   TResult when<TResult extends Object?>({
     required TResult Function() initial,
     required TResult Function() loading,
-    required TResult Function(Either<ExportData, WorkspaceError> successOrFail)
+    required TResult Function(Either<ExportData, FlowyError> successOrFail)
         finish,
   }) {
     return loading();
@@ -668,7 +668,7 @@ class _$_Loading implements _Loading {
   TResult? whenOrNull<TResult extends Object?>({
     TResult Function()? initial,
     TResult Function()? loading,
-    TResult Function(Either<ExportData, WorkspaceError> successOrFail)? finish,
+    TResult Function(Either<ExportData, FlowyError> successOrFail)? finish,
   }) {
     return loading?.call();
   }
@@ -678,7 +678,7 @@ class _$_Loading implements _Loading {
   TResult maybeWhen<TResult extends Object?>({
     TResult Function()? initial,
     TResult Function()? loading,
-    TResult Function(Either<ExportData, WorkspaceError> successOrFail)? finish,
+    TResult Function(Either<ExportData, FlowyError> successOrFail)? finish,
     required TResult orElse(),
   }) {
     if (loading != null) {
@@ -730,7 +730,7 @@ abstract class _Loading implements DocShareState {
 abstract class _$FinishCopyWith<$Res> {
   factory _$FinishCopyWith(_Finish value, $Res Function(_Finish) then) =
       __$FinishCopyWithImpl<$Res>;
-  $Res call({Either<ExportData, WorkspaceError> successOrFail});
+  $Res call({Either<ExportData, FlowyError> successOrFail});
 }
 
 /// @nodoc
@@ -750,7 +750,7 @@ class __$FinishCopyWithImpl<$Res> extends _$DocShareStateCopyWithImpl<$Res>
       successOrFail == freezed
           ? _value.successOrFail
           : successOrFail // ignore: cast_nullable_to_non_nullable
-              as Either<ExportData, WorkspaceError>,
+              as Either<ExportData, FlowyError>,
     ));
   }
 }
@@ -761,7 +761,7 @@ class _$_Finish implements _Finish {
   const _$_Finish(this.successOrFail);
 
   @override
-  final Either<ExportData, WorkspaceError> successOrFail;
+  final Either<ExportData, FlowyError> successOrFail;
 
   @override
   String toString() {
@@ -791,7 +791,7 @@ class _$_Finish implements _Finish {
   TResult when<TResult extends Object?>({
     required TResult Function() initial,
     required TResult Function() loading,
-    required TResult Function(Either<ExportData, WorkspaceError> successOrFail)
+    required TResult Function(Either<ExportData, FlowyError> successOrFail)
         finish,
   }) {
     return finish(successOrFail);
@@ -802,7 +802,7 @@ class _$_Finish implements _Finish {
   TResult? whenOrNull<TResult extends Object?>({
     TResult Function()? initial,
     TResult Function()? loading,
-    TResult Function(Either<ExportData, WorkspaceError> successOrFail)? finish,
+    TResult Function(Either<ExportData, FlowyError> successOrFail)? finish,
   }) {
     return finish?.call(successOrFail);
   }
@@ -812,7 +812,7 @@ class _$_Finish implements _Finish {
   TResult maybeWhen<TResult extends Object?>({
     TResult Function()? initial,
     TResult Function()? loading,
-    TResult Function(Either<ExportData, WorkspaceError> successOrFail)? finish,
+    TResult Function(Either<ExportData, FlowyError> successOrFail)? finish,
     required TResult orElse(),
   }) {
     if (finish != null) {
@@ -857,10 +857,10 @@ class _$_Finish implements _Finish {
 }
 
 abstract class _Finish implements DocShareState {
-  const factory _Finish(Either<ExportData, WorkspaceError> successOrFail) =
+  const factory _Finish(Either<ExportData, FlowyError> successOrFail) =
       _$_Finish;
 
-  Either<ExportData, WorkspaceError> get successOrFail =>
+  Either<ExportData, FlowyError> get successOrFail =>
       throw _privateConstructorUsedError;
   @JsonKey(ignore: true)
   _$FinishCopyWith<_Finish> get copyWith => throw _privateConstructorUsedError;

+ 1 - 3
frontend/app_flowy/lib/workspace/application/edit_pannel/edit_pannel_bloc.dart

@@ -1,6 +1,5 @@
 import 'package:app_flowy/workspace/domain/edit_context.dart';
 import 'package:dartz/dartz.dart';
-import 'package:flutter/material.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 // ignore: import_of_legacy_library_into_null_safe
 import 'package:flutter_bloc/flutter_bloc.dart';
@@ -27,8 +26,7 @@ class EditPannelBloc extends Bloc<EditPannelEvent, EditPannelState> {
 
 @freezed
 class EditPannelEvent with _$EditPannelEvent {
-  const factory EditPannelEvent.startEdit(EditPannelContext context) =
-      _StartEdit;
+  const factory EditPannelEvent.startEdit(EditPannelContext context) = _StartEdit;
 
   const factory EditPannelEvent.endEdit(EditPannelContext context) = _EndEdit;
 }

+ 3 - 2
frontend/app_flowy/lib/workspace/application/home/home_listen_bloc.dart

@@ -1,5 +1,6 @@
 import 'package:app_flowy/workspace/domain/i_user.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:dartz/dartz.dart';
@@ -31,7 +32,7 @@ class HomeListenBloc extends Bloc<HomeListenEvent, HomeListenState> {
     super.close();
   }
 
-  void _authDidChanged(Either<Unit, UserError> errorOrNothing) {
+  void _authDidChanged(Either<Unit, FlowyError> errorOrNothing) {
     errorOrNothing.fold((_) {}, (error) {
       if (error.code == ErrorCode.UserUnauthorized.value) {
         add(HomeListenEvent.unauthorized(error.msg));

+ 5 - 6
frontend/app_flowy/lib/workspace/application/menu/menu_bloc.dart

@@ -4,9 +4,8 @@ import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
 import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
 import 'package:dartz/dartz.dart';
 import 'package:flowy_log/flowy_log.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/app_create.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
-import 'package:flutter/material.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/app_create.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
@@ -78,7 +77,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
     );
   }
 
-  void _handleAppsOrFail(Either<List<App>, WorkspaceError> appsOrFail) {
+  void _handleAppsOrFail(Either<List<App>, FlowyError> appsOrFail) {
     appsOrFail.fold(
       (apps) => add(MenuEvent.didReceiveApps(left(apps))),
       (error) => add(MenuEvent.didReceiveApps(right(error))),
@@ -92,7 +91,7 @@ class MenuEvent with _$MenuEvent {
   const factory MenuEvent.collapse() = Collapse;
   const factory MenuEvent.openPage(HomeStackContext context) = OpenPage;
   const factory MenuEvent.createApp(String name, {String? desc}) = CreateApp;
-  const factory MenuEvent.didReceiveApps(Either<List<App>, WorkspaceError> appsOrFail) = ReceiveApps;
+  const factory MenuEvent.didReceiveApps(Either<List<App>, FlowyError> appsOrFail) = ReceiveApps;
 }
 
 @freezed
@@ -100,7 +99,7 @@ class MenuState with _$MenuState {
   const factory MenuState({
     required bool isCollapse,
     required Option<List<App>> apps,
-    required Either<Unit, WorkspaceError> successOrFailure,
+    required Either<Unit, FlowyError> successOrFailure,
     required HomeStackContext stackContext,
   }) = _MenuState;
 

+ 33 - 33
frontend/app_flowy/lib/workspace/application/menu/menu_bloc.freezed.dart

@@ -38,7 +38,7 @@ class _$MenuEventTearOff {
     );
   }
 
-  ReceiveApps didReceiveApps(Either<List<App>, WorkspaceError> appsOrFail) {
+  ReceiveApps didReceiveApps(Either<List<App>, FlowyError> appsOrFail) {
     return ReceiveApps(
       appsOrFail,
     );
@@ -57,7 +57,7 @@ mixin _$MenuEvent {
     required TResult Function(HomeStackContext<dynamic, dynamic> context)
         openPage,
     required TResult Function(String name, String? desc) createApp,
-    required TResult Function(Either<List<App>, WorkspaceError> appsOrFail)
+    required TResult Function(Either<List<App>, FlowyError> appsOrFail)
         didReceiveApps,
   }) =>
       throw _privateConstructorUsedError;
@@ -67,7 +67,7 @@ mixin _$MenuEvent {
     TResult Function()? collapse,
     TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
     TResult Function(String name, String? desc)? createApp,
-    TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
+    TResult Function(Either<List<App>, FlowyError> appsOrFail)?
         didReceiveApps,
   }) =>
       throw _privateConstructorUsedError;
@@ -77,7 +77,7 @@ mixin _$MenuEvent {
     TResult Function()? collapse,
     TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
     TResult Function(String name, String? desc)? createApp,
-    TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
+    TResult Function(Either<List<App>, FlowyError> appsOrFail)?
         didReceiveApps,
     required TResult orElse(),
   }) =>
@@ -169,7 +169,7 @@ class _$_Initial implements _Initial {
     required TResult Function(HomeStackContext<dynamic, dynamic> context)
         openPage,
     required TResult Function(String name, String? desc) createApp,
-    required TResult Function(Either<List<App>, WorkspaceError> appsOrFail)
+    required TResult Function(Either<List<App>, FlowyError> appsOrFail)
         didReceiveApps,
   }) {
     return initial();
@@ -182,7 +182,7 @@ class _$_Initial implements _Initial {
     TResult Function()? collapse,
     TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
     TResult Function(String name, String? desc)? createApp,
-    TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
+    TResult Function(Either<List<App>, FlowyError> appsOrFail)?
         didReceiveApps,
   }) {
     return initial?.call();
@@ -195,7 +195,7 @@ class _$_Initial implements _Initial {
     TResult Function()? collapse,
     TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
     TResult Function(String name, String? desc)? createApp,
-    TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
+    TResult Function(Either<List<App>, FlowyError> appsOrFail)?
         didReceiveApps,
     required TResult orElse(),
   }) {
@@ -292,7 +292,7 @@ class _$Collapse implements Collapse {
     required TResult Function(HomeStackContext<dynamic, dynamic> context)
         openPage,
     required TResult Function(String name, String? desc) createApp,
-    required TResult Function(Either<List<App>, WorkspaceError> appsOrFail)
+    required TResult Function(Either<List<App>, FlowyError> appsOrFail)
         didReceiveApps,
   }) {
     return collapse();
@@ -305,7 +305,7 @@ class _$Collapse implements Collapse {
     TResult Function()? collapse,
     TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
     TResult Function(String name, String? desc)? createApp,
-    TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
+    TResult Function(Either<List<App>, FlowyError> appsOrFail)?
         didReceiveApps,
   }) {
     return collapse?.call();
@@ -318,7 +318,7 @@ class _$Collapse implements Collapse {
     TResult Function()? collapse,
     TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
     TResult Function(String name, String? desc)? createApp,
-    TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
+    TResult Function(Either<List<App>, FlowyError> appsOrFail)?
         didReceiveApps,
     required TResult orElse(),
   }) {
@@ -440,7 +440,7 @@ class _$OpenPage implements OpenPage {
     required TResult Function(HomeStackContext<dynamic, dynamic> context)
         openPage,
     required TResult Function(String name, String? desc) createApp,
-    required TResult Function(Either<List<App>, WorkspaceError> appsOrFail)
+    required TResult Function(Either<List<App>, FlowyError> appsOrFail)
         didReceiveApps,
   }) {
     return openPage(context);
@@ -453,7 +453,7 @@ class _$OpenPage implements OpenPage {
     TResult Function()? collapse,
     TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
     TResult Function(String name, String? desc)? createApp,
-    TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
+    TResult Function(Either<List<App>, FlowyError> appsOrFail)?
         didReceiveApps,
   }) {
     return openPage?.call(context);
@@ -466,7 +466,7 @@ class _$OpenPage implements OpenPage {
     TResult Function()? collapse,
     TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
     TResult Function(String name, String? desc)? createApp,
-    TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
+    TResult Function(Either<List<App>, FlowyError> appsOrFail)?
         didReceiveApps,
     required TResult orElse(),
   }) {
@@ -606,7 +606,7 @@ class _$CreateApp implements CreateApp {
     required TResult Function(HomeStackContext<dynamic, dynamic> context)
         openPage,
     required TResult Function(String name, String? desc) createApp,
-    required TResult Function(Either<List<App>, WorkspaceError> appsOrFail)
+    required TResult Function(Either<List<App>, FlowyError> appsOrFail)
         didReceiveApps,
   }) {
     return createApp(name, desc);
@@ -619,7 +619,7 @@ class _$CreateApp implements CreateApp {
     TResult Function()? collapse,
     TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
     TResult Function(String name, String? desc)? createApp,
-    TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
+    TResult Function(Either<List<App>, FlowyError> appsOrFail)?
         didReceiveApps,
   }) {
     return createApp?.call(name, desc);
@@ -632,7 +632,7 @@ class _$CreateApp implements CreateApp {
     TResult Function()? collapse,
     TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
     TResult Function(String name, String? desc)? createApp,
-    TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
+    TResult Function(Either<List<App>, FlowyError> appsOrFail)?
         didReceiveApps,
     required TResult orElse(),
   }) {
@@ -698,7 +698,7 @@ abstract class $ReceiveAppsCopyWith<$Res> {
   factory $ReceiveAppsCopyWith(
           ReceiveApps value, $Res Function(ReceiveApps) then) =
       _$ReceiveAppsCopyWithImpl<$Res>;
-  $Res call({Either<List<App>, WorkspaceError> appsOrFail});
+  $Res call({Either<List<App>, FlowyError> appsOrFail});
 }
 
 /// @nodoc
@@ -719,7 +719,7 @@ class _$ReceiveAppsCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res>
       appsOrFail == freezed
           ? _value.appsOrFail
           : appsOrFail // ignore: cast_nullable_to_non_nullable
-              as Either<List<App>, WorkspaceError>,
+              as Either<List<App>, FlowyError>,
     ));
   }
 }
@@ -730,7 +730,7 @@ class _$ReceiveApps implements ReceiveApps {
   const _$ReceiveApps(this.appsOrFail);
 
   @override
-  final Either<List<App>, WorkspaceError> appsOrFail;
+  final Either<List<App>, FlowyError> appsOrFail;
 
   @override
   String toString() {
@@ -763,7 +763,7 @@ class _$ReceiveApps implements ReceiveApps {
     required TResult Function(HomeStackContext<dynamic, dynamic> context)
         openPage,
     required TResult Function(String name, String? desc) createApp,
-    required TResult Function(Either<List<App>, WorkspaceError> appsOrFail)
+    required TResult Function(Either<List<App>, FlowyError> appsOrFail)
         didReceiveApps,
   }) {
     return didReceiveApps(appsOrFail);
@@ -776,7 +776,7 @@ class _$ReceiveApps implements ReceiveApps {
     TResult Function()? collapse,
     TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
     TResult Function(String name, String? desc)? createApp,
-    TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
+    TResult Function(Either<List<App>, FlowyError> appsOrFail)?
         didReceiveApps,
   }) {
     return didReceiveApps?.call(appsOrFail);
@@ -789,7 +789,7 @@ class _$ReceiveApps implements ReceiveApps {
     TResult Function()? collapse,
     TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
     TResult Function(String name, String? desc)? createApp,
-    TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
+    TResult Function(Either<List<App>, FlowyError> appsOrFail)?
         didReceiveApps,
     required TResult orElse(),
   }) {
@@ -841,10 +841,10 @@ class _$ReceiveApps implements ReceiveApps {
 }
 
 abstract class ReceiveApps implements MenuEvent {
-  const factory ReceiveApps(Either<List<App>, WorkspaceError> appsOrFail) =
+  const factory ReceiveApps(Either<List<App>, FlowyError> appsOrFail) =
       _$ReceiveApps;
 
-  Either<List<App>, WorkspaceError> get appsOrFail =>
+  Either<List<App>, FlowyError> get appsOrFail =>
       throw _privateConstructorUsedError;
   @JsonKey(ignore: true)
   $ReceiveAppsCopyWith<ReceiveApps> get copyWith =>
@@ -858,7 +858,7 @@ class _$MenuStateTearOff {
   _MenuState call(
       {required bool isCollapse,
       required Option<List<App>> apps,
-      required Either<Unit, WorkspaceError> successOrFailure,
+      required Either<Unit, FlowyError> successOrFailure,
       required HomeStackContext<dynamic, dynamic> stackContext}) {
     return _MenuState(
       isCollapse: isCollapse,
@@ -876,7 +876,7 @@ const $MenuState = _$MenuStateTearOff();
 mixin _$MenuState {
   bool get isCollapse => throw _privateConstructorUsedError;
   Option<List<App>> get apps => throw _privateConstructorUsedError;
-  Either<Unit, WorkspaceError> get successOrFailure =>
+  Either<Unit, FlowyError> get successOrFailure =>
       throw _privateConstructorUsedError;
   HomeStackContext<dynamic, dynamic> get stackContext =>
       throw _privateConstructorUsedError;
@@ -893,7 +893,7 @@ abstract class $MenuStateCopyWith<$Res> {
   $Res call(
       {bool isCollapse,
       Option<List<App>> apps,
-      Either<Unit, WorkspaceError> successOrFailure,
+      Either<Unit, FlowyError> successOrFailure,
       HomeStackContext<dynamic, dynamic> stackContext});
 }
 
@@ -924,7 +924,7 @@ class _$MenuStateCopyWithImpl<$Res> implements $MenuStateCopyWith<$Res> {
       successOrFailure: successOrFailure == freezed
           ? _value.successOrFailure
           : successOrFailure // ignore: cast_nullable_to_non_nullable
-              as Either<Unit, WorkspaceError>,
+              as Either<Unit, FlowyError>,
       stackContext: stackContext == freezed
           ? _value.stackContext
           : stackContext // ignore: cast_nullable_to_non_nullable
@@ -942,7 +942,7 @@ abstract class _$MenuStateCopyWith<$Res> implements $MenuStateCopyWith<$Res> {
   $Res call(
       {bool isCollapse,
       Option<List<App>> apps,
-      Either<Unit, WorkspaceError> successOrFailure,
+      Either<Unit, FlowyError> successOrFailure,
       HomeStackContext<dynamic, dynamic> stackContext});
 }
 
@@ -974,7 +974,7 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res>
       successOrFailure: successOrFailure == freezed
           ? _value.successOrFailure
           : successOrFailure // ignore: cast_nullable_to_non_nullable
-              as Either<Unit, WorkspaceError>,
+              as Either<Unit, FlowyError>,
       stackContext: stackContext == freezed
           ? _value.stackContext
           : stackContext // ignore: cast_nullable_to_non_nullable
@@ -997,7 +997,7 @@ class _$_MenuState implements _MenuState {
   @override
   final Option<List<App>> apps;
   @override
-  final Either<Unit, WorkspaceError> successOrFailure;
+  final Either<Unit, FlowyError> successOrFailure;
   @override
   final HomeStackContext<dynamic, dynamic> stackContext;
 
@@ -1041,7 +1041,7 @@ abstract class _MenuState implements MenuState {
   const factory _MenuState(
       {required bool isCollapse,
       required Option<List<App>> apps,
-      required Either<Unit, WorkspaceError> successOrFailure,
+      required Either<Unit, FlowyError> successOrFailure,
       required HomeStackContext<dynamic, dynamic> stackContext}) = _$_MenuState;
 
   @override
@@ -1049,7 +1049,7 @@ abstract class _MenuState implements MenuState {
   @override
   Option<List<App>> get apps => throw _privateConstructorUsedError;
   @override
-  Either<Unit, WorkspaceError> get successOrFailure =>
+  Either<Unit, FlowyError> get successOrFailure =>
       throw _privateConstructorUsedError;
   @override
   HomeStackContext<dynamic, dynamic> get stackContext =>

+ 4 - 5
frontend/app_flowy/lib/workspace/application/menu/menu_user_bloc.dart

@@ -1,8 +1,7 @@
 import 'package:app_flowy/workspace/domain/i_user.dart';
 import 'package:flowy_log/flowy_log.dart';
-import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/workspace_create.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/workspace_create.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:dartz/dartz.dart';
@@ -40,8 +39,8 @@ class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
     result.fold((l) => null, (error) => Log.error(error));
   }
 
-  void _profileUpdated(Either<UserProfile, UserError> userOrFailed) {}
-  void _workspacesUpdated(Either<List<Workspace>, WorkspaceError> workspacesOrFailed) {
+  void _profileUpdated(Either<UserProfile, FlowyError> userOrFailed) {}
+  void _workspacesUpdated(Either<List<Workspace>, FlowyError> workspacesOrFailed) {
     // fetch workspaces
     // iUserImpl.fetchWorkspaces().then((result) {
     //   result.fold(

+ 5 - 5
frontend/app_flowy/lib/workspace/application/trash/trash_bloc.dart

@@ -1,8 +1,8 @@
 import 'package:app_flowy/workspace/domain/i_trash.dart';
 import 'package:dartz/dartz.dart';
 import 'package:flowy_log/flowy_log.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/trash_create.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/trash_create.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 part 'trash_bloc.freezed.dart';
@@ -45,14 +45,14 @@ class TrashBloc extends Bloc<TrashEvent, TrashState> {
     );
   }
 
-  Stream<TrashState> _handleResult(Either<dynamic, WorkspaceError> result) async* {
+  Stream<TrashState> _handleResult(Either<dynamic, FlowyError> result) async* {
     yield result.fold(
       (l) => state.copyWith(successOrFailure: left(unit)),
       (error) => state.copyWith(successOrFailure: right(error)),
     );
   }
 
-  void _listenTrashUpdated(Either<List<Trash>, WorkspaceError> trashOrFailed) {
+  void _listenTrashUpdated(Either<List<Trash>, FlowyError> trashOrFailed) {
     trashOrFailed.fold(
       (trash) {
         add(TrashEvent.didReceiveTrash(trash));
@@ -84,7 +84,7 @@ class TrashEvent with _$TrashEvent {
 class TrashState with _$TrashState {
   const factory TrashState({
     required List<Trash> objects,
-    required Either<Unit, WorkspaceError> successOrFailure,
+    required Either<Unit, FlowyError> successOrFailure,
   }) = _TrashState;
 
   factory TrashState.init() => TrashState(

+ 9 - 9
frontend/app_flowy/lib/workspace/application/trash/trash_bloc.freezed.dart

@@ -980,7 +980,7 @@ class _$TrashStateTearOff {
 
   _TrashState call(
       {required List<Trash> objects,
-      required Either<Unit, WorkspaceError> successOrFailure}) {
+      required Either<Unit, FlowyError> successOrFailure}) {
     return _TrashState(
       objects: objects,
       successOrFailure: successOrFailure,
@@ -994,7 +994,7 @@ const $TrashState = _$TrashStateTearOff();
 /// @nodoc
 mixin _$TrashState {
   List<Trash> get objects => throw _privateConstructorUsedError;
-  Either<Unit, WorkspaceError> get successOrFailure =>
+  Either<Unit, FlowyError> get successOrFailure =>
       throw _privateConstructorUsedError;
 
   @JsonKey(ignore: true)
@@ -1008,7 +1008,7 @@ abstract class $TrashStateCopyWith<$Res> {
           TrashState value, $Res Function(TrashState) then) =
       _$TrashStateCopyWithImpl<$Res>;
   $Res call(
-      {List<Trash> objects, Either<Unit, WorkspaceError> successOrFailure});
+      {List<Trash> objects, Either<Unit, FlowyError> successOrFailure});
 }
 
 /// @nodoc
@@ -1032,7 +1032,7 @@ class _$TrashStateCopyWithImpl<$Res> implements $TrashStateCopyWith<$Res> {
       successOrFailure: successOrFailure == freezed
           ? _value.successOrFailure
           : successOrFailure // ignore: cast_nullable_to_non_nullable
-              as Either<Unit, WorkspaceError>,
+              as Either<Unit, FlowyError>,
     ));
   }
 }
@@ -1044,7 +1044,7 @@ abstract class _$TrashStateCopyWith<$Res> implements $TrashStateCopyWith<$Res> {
       __$TrashStateCopyWithImpl<$Res>;
   @override
   $Res call(
-      {List<Trash> objects, Either<Unit, WorkspaceError> successOrFailure});
+      {List<Trash> objects, Either<Unit, FlowyError> successOrFailure});
 }
 
 /// @nodoc
@@ -1070,7 +1070,7 @@ class __$TrashStateCopyWithImpl<$Res> extends _$TrashStateCopyWithImpl<$Res>
       successOrFailure: successOrFailure == freezed
           ? _value.successOrFailure
           : successOrFailure // ignore: cast_nullable_to_non_nullable
-              as Either<Unit, WorkspaceError>,
+              as Either<Unit, FlowyError>,
     ));
   }
 }
@@ -1083,7 +1083,7 @@ class _$_TrashState implements _TrashState {
   @override
   final List<Trash> objects;
   @override
-  final Either<Unit, WorkspaceError> successOrFailure;
+  final Either<Unit, FlowyError> successOrFailure;
 
   @override
   String toString() {
@@ -1117,12 +1117,12 @@ class _$_TrashState implements _TrashState {
 abstract class _TrashState implements TrashState {
   const factory _TrashState(
       {required List<Trash> objects,
-      required Either<Unit, WorkspaceError> successOrFailure}) = _$_TrashState;
+      required Either<Unit, FlowyError> successOrFailure}) = _$_TrashState;
 
   @override
   List<Trash> get objects => throw _privateConstructorUsedError;
   @override
-  Either<Unit, WorkspaceError> get successOrFailure =>
+  Either<Unit, FlowyError> get successOrFailure =>
       throw _privateConstructorUsedError;
   @override
   @JsonKey(ignore: true)

+ 5 - 5
frontend/app_flowy/lib/workspace/application/view/view_bloc.dart

@@ -1,6 +1,6 @@
 import 'package:dartz/dartz.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/view_create.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/view_create.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:app_flowy/workspace/domain/i_view.dart';
@@ -56,7 +56,7 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
     );
   }
 
-  Stream<ViewState> _handleViewDidUpdate(Either<View, WorkspaceError> result) async* {
+  Stream<ViewState> _handleViewDidUpdate(Either<View, FlowyError> result) async* {
     yield result.fold(
       (view) => state.copyWith(view: view, successOrFailure: left(unit)),
       (error) => state.copyWith(successOrFailure: right(error)),
@@ -77,7 +77,7 @@ class ViewEvent with _$ViewEvent {
   const factory ViewEvent.rename(String newName) = Rename;
   const factory ViewEvent.delete() = Delete;
   const factory ViewEvent.duplicate() = Duplicate;
-  const factory ViewEvent.viewDidUpdate(Either<View, WorkspaceError> result) = ViewDidUpdate;
+  const factory ViewEvent.viewDidUpdate(Either<View, FlowyError> result) = ViewDidUpdate;
 }
 
 @freezed
@@ -85,7 +85,7 @@ class ViewState with _$ViewState {
   const factory ViewState({
     required View view,
     required bool isEditing,
-    required Either<Unit, WorkspaceError> successOrFailure,
+    required Either<Unit, FlowyError> successOrFailure,
   }) = _ViewState;
 
   factory ViewState.init(View view) => ViewState(

+ 36 - 36
frontend/app_flowy/lib/workspace/application/view/view_bloc.freezed.dart

@@ -41,7 +41,7 @@ class _$ViewEventTearOff {
     return const Duplicate();
   }
 
-  ViewDidUpdate viewDidUpdate(Either<View, WorkspaceError> result) {
+  ViewDidUpdate viewDidUpdate(Either<View, FlowyError> result) {
     return ViewDidUpdate(
       result,
     );
@@ -60,7 +60,7 @@ mixin _$ViewEvent {
     required TResult Function(String newName) rename,
     required TResult Function() delete,
     required TResult Function() duplicate,
-    required TResult Function(Either<View, WorkspaceError> result)
+    required TResult Function(Either<View, FlowyError> result)
         viewDidUpdate,
   }) =>
       throw _privateConstructorUsedError;
@@ -71,7 +71,7 @@ mixin _$ViewEvent {
     TResult Function(String newName)? rename,
     TResult Function()? delete,
     TResult Function()? duplicate,
-    TResult Function(Either<View, WorkspaceError> result)? viewDidUpdate,
+    TResult Function(Either<View, FlowyError> result)? viewDidUpdate,
   }) =>
       throw _privateConstructorUsedError;
   @optionalTypeArgs
@@ -81,7 +81,7 @@ mixin _$ViewEvent {
     TResult Function(String newName)? rename,
     TResult Function()? delete,
     TResult Function()? duplicate,
-    TResult Function(Either<View, WorkspaceError> result)? viewDidUpdate,
+    TResult Function(Either<View, FlowyError> result)? viewDidUpdate,
     required TResult orElse(),
   }) =>
       throw _privateConstructorUsedError;
@@ -175,7 +175,7 @@ class _$Initial implements Initial {
     required TResult Function(String newName) rename,
     required TResult Function() delete,
     required TResult Function() duplicate,
-    required TResult Function(Either<View, WorkspaceError> result)
+    required TResult Function(Either<View, FlowyError> result)
         viewDidUpdate,
   }) {
     return initial();
@@ -189,7 +189,7 @@ class _$Initial implements Initial {
     TResult Function(String newName)? rename,
     TResult Function()? delete,
     TResult Function()? duplicate,
-    TResult Function(Either<View, WorkspaceError> result)? viewDidUpdate,
+    TResult Function(Either<View, FlowyError> result)? viewDidUpdate,
   }) {
     return initial?.call();
   }
@@ -202,7 +202,7 @@ class _$Initial implements Initial {
     TResult Function(String newName)? rename,
     TResult Function()? delete,
     TResult Function()? duplicate,
-    TResult Function(Either<View, WorkspaceError> result)? viewDidUpdate,
+    TResult Function(Either<View, FlowyError> result)? viewDidUpdate,
     required TResult orElse(),
   }) {
     if (initial != null) {
@@ -328,7 +328,7 @@ class _$SetEditing implements SetEditing {
     required TResult Function(String newName) rename,
     required TResult Function() delete,
     required TResult Function() duplicate,
-    required TResult Function(Either<View, WorkspaceError> result)
+    required TResult Function(Either<View, FlowyError> result)
         viewDidUpdate,
   }) {
     return setIsEditing(isEditing);
@@ -342,7 +342,7 @@ class _$SetEditing implements SetEditing {
     TResult Function(String newName)? rename,
     TResult Function()? delete,
     TResult Function()? duplicate,
-    TResult Function(Either<View, WorkspaceError> result)? viewDidUpdate,
+    TResult Function(Either<View, FlowyError> result)? viewDidUpdate,
   }) {
     return setIsEditing?.call(isEditing);
   }
@@ -355,7 +355,7 @@ class _$SetEditing implements SetEditing {
     TResult Function(String newName)? rename,
     TResult Function()? delete,
     TResult Function()? duplicate,
-    TResult Function(Either<View, WorkspaceError> result)? viewDidUpdate,
+    TResult Function(Either<View, FlowyError> result)? viewDidUpdate,
     required TResult orElse(),
   }) {
     if (setIsEditing != null) {
@@ -484,7 +484,7 @@ class _$Rename implements Rename {
     required TResult Function(String newName) rename,
     required TResult Function() delete,
     required TResult Function() duplicate,
-    required TResult Function(Either<View, WorkspaceError> result)
+    required TResult Function(Either<View, FlowyError> result)
         viewDidUpdate,
   }) {
     return rename(newName);
@@ -498,7 +498,7 @@ class _$Rename implements Rename {
     TResult Function(String newName)? rename,
     TResult Function()? delete,
     TResult Function()? duplicate,
-    TResult Function(Either<View, WorkspaceError> result)? viewDidUpdate,
+    TResult Function(Either<View, FlowyError> result)? viewDidUpdate,
   }) {
     return rename?.call(newName);
   }
@@ -511,7 +511,7 @@ class _$Rename implements Rename {
     TResult Function(String newName)? rename,
     TResult Function()? delete,
     TResult Function()? duplicate,
-    TResult Function(Either<View, WorkspaceError> result)? viewDidUpdate,
+    TResult Function(Either<View, FlowyError> result)? viewDidUpdate,
     required TResult orElse(),
   }) {
     if (rename != null) {
@@ -614,7 +614,7 @@ class _$Delete implements Delete {
     required TResult Function(String newName) rename,
     required TResult Function() delete,
     required TResult Function() duplicate,
-    required TResult Function(Either<View, WorkspaceError> result)
+    required TResult Function(Either<View, FlowyError> result)
         viewDidUpdate,
   }) {
     return delete();
@@ -628,7 +628,7 @@ class _$Delete implements Delete {
     TResult Function(String newName)? rename,
     TResult Function()? delete,
     TResult Function()? duplicate,
-    TResult Function(Either<View, WorkspaceError> result)? viewDidUpdate,
+    TResult Function(Either<View, FlowyError> result)? viewDidUpdate,
   }) {
     return delete?.call();
   }
@@ -641,7 +641,7 @@ class _$Delete implements Delete {
     TResult Function(String newName)? rename,
     TResult Function()? delete,
     TResult Function()? duplicate,
-    TResult Function(Either<View, WorkspaceError> result)? viewDidUpdate,
+    TResult Function(Either<View, FlowyError> result)? viewDidUpdate,
     required TResult orElse(),
   }) {
     if (delete != null) {
@@ -740,7 +740,7 @@ class _$Duplicate implements Duplicate {
     required TResult Function(String newName) rename,
     required TResult Function() delete,
     required TResult Function() duplicate,
-    required TResult Function(Either<View, WorkspaceError> result)
+    required TResult Function(Either<View, FlowyError> result)
         viewDidUpdate,
   }) {
     return duplicate();
@@ -754,7 +754,7 @@ class _$Duplicate implements Duplicate {
     TResult Function(String newName)? rename,
     TResult Function()? delete,
     TResult Function()? duplicate,
-    TResult Function(Either<View, WorkspaceError> result)? viewDidUpdate,
+    TResult Function(Either<View, FlowyError> result)? viewDidUpdate,
   }) {
     return duplicate?.call();
   }
@@ -767,7 +767,7 @@ class _$Duplicate implements Duplicate {
     TResult Function(String newName)? rename,
     TResult Function()? delete,
     TResult Function()? duplicate,
-    TResult Function(Either<View, WorkspaceError> result)? viewDidUpdate,
+    TResult Function(Either<View, FlowyError> result)? viewDidUpdate,
     required TResult orElse(),
   }) {
     if (duplicate != null) {
@@ -829,7 +829,7 @@ abstract class $ViewDidUpdateCopyWith<$Res> {
   factory $ViewDidUpdateCopyWith(
           ViewDidUpdate value, $Res Function(ViewDidUpdate) then) =
       _$ViewDidUpdateCopyWithImpl<$Res>;
-  $Res call({Either<View, WorkspaceError> result});
+  $Res call({Either<View, FlowyError> result});
 }
 
 /// @nodoc
@@ -850,7 +850,7 @@ class _$ViewDidUpdateCopyWithImpl<$Res> extends _$ViewEventCopyWithImpl<$Res>
       result == freezed
           ? _value.result
           : result // ignore: cast_nullable_to_non_nullable
-              as Either<View, WorkspaceError>,
+              as Either<View, FlowyError>,
     ));
   }
 }
@@ -861,7 +861,7 @@ class _$ViewDidUpdate implements ViewDidUpdate {
   const _$ViewDidUpdate(this.result);
 
   @override
-  final Either<View, WorkspaceError> result;
+  final Either<View, FlowyError> result;
 
   @override
   String toString() {
@@ -893,7 +893,7 @@ class _$ViewDidUpdate implements ViewDidUpdate {
     required TResult Function(String newName) rename,
     required TResult Function() delete,
     required TResult Function() duplicate,
-    required TResult Function(Either<View, WorkspaceError> result)
+    required TResult Function(Either<View, FlowyError> result)
         viewDidUpdate,
   }) {
     return viewDidUpdate(result);
@@ -907,7 +907,7 @@ class _$ViewDidUpdate implements ViewDidUpdate {
     TResult Function(String newName)? rename,
     TResult Function()? delete,
     TResult Function()? duplicate,
-    TResult Function(Either<View, WorkspaceError> result)? viewDidUpdate,
+    TResult Function(Either<View, FlowyError> result)? viewDidUpdate,
   }) {
     return viewDidUpdate?.call(result);
   }
@@ -920,7 +920,7 @@ class _$ViewDidUpdate implements ViewDidUpdate {
     TResult Function(String newName)? rename,
     TResult Function()? delete,
     TResult Function()? duplicate,
-    TResult Function(Either<View, WorkspaceError> result)? viewDidUpdate,
+    TResult Function(Either<View, FlowyError> result)? viewDidUpdate,
     required TResult orElse(),
   }) {
     if (viewDidUpdate != null) {
@@ -974,10 +974,10 @@ class _$ViewDidUpdate implements ViewDidUpdate {
 }
 
 abstract class ViewDidUpdate implements ViewEvent {
-  const factory ViewDidUpdate(Either<View, WorkspaceError> result) =
+  const factory ViewDidUpdate(Either<View, FlowyError> result) =
       _$ViewDidUpdate;
 
-  Either<View, WorkspaceError> get result => throw _privateConstructorUsedError;
+  Either<View, FlowyError> get result => throw _privateConstructorUsedError;
   @JsonKey(ignore: true)
   $ViewDidUpdateCopyWith<ViewDidUpdate> get copyWith =>
       throw _privateConstructorUsedError;
@@ -990,7 +990,7 @@ class _$ViewStateTearOff {
   _ViewState call(
       {required View view,
       required bool isEditing,
-      required Either<Unit, WorkspaceError> successOrFailure}) {
+      required Either<Unit, FlowyError> successOrFailure}) {
     return _ViewState(
       view: view,
       isEditing: isEditing,
@@ -1006,7 +1006,7 @@ const $ViewState = _$ViewStateTearOff();
 mixin _$ViewState {
   View get view => throw _privateConstructorUsedError;
   bool get isEditing => throw _privateConstructorUsedError;
-  Either<Unit, WorkspaceError> get successOrFailure =>
+  Either<Unit, FlowyError> get successOrFailure =>
       throw _privateConstructorUsedError;
 
   @JsonKey(ignore: true)
@@ -1021,7 +1021,7 @@ abstract class $ViewStateCopyWith<$Res> {
   $Res call(
       {View view,
       bool isEditing,
-      Either<Unit, WorkspaceError> successOrFailure});
+      Either<Unit, FlowyError> successOrFailure});
 }
 
 /// @nodoc
@@ -1050,7 +1050,7 @@ class _$ViewStateCopyWithImpl<$Res> implements $ViewStateCopyWith<$Res> {
       successOrFailure: successOrFailure == freezed
           ? _value.successOrFailure
           : successOrFailure // ignore: cast_nullable_to_non_nullable
-              as Either<Unit, WorkspaceError>,
+              as Either<Unit, FlowyError>,
     ));
   }
 }
@@ -1064,7 +1064,7 @@ abstract class _$ViewStateCopyWith<$Res> implements $ViewStateCopyWith<$Res> {
   $Res call(
       {View view,
       bool isEditing,
-      Either<Unit, WorkspaceError> successOrFailure});
+      Either<Unit, FlowyError> successOrFailure});
 }
 
 /// @nodoc
@@ -1094,7 +1094,7 @@ class __$ViewStateCopyWithImpl<$Res> extends _$ViewStateCopyWithImpl<$Res>
       successOrFailure: successOrFailure == freezed
           ? _value.successOrFailure
           : successOrFailure // ignore: cast_nullable_to_non_nullable
-              as Either<Unit, WorkspaceError>,
+              as Either<Unit, FlowyError>,
     ));
   }
 }
@@ -1112,7 +1112,7 @@ class _$_ViewState implements _ViewState {
   @override
   final bool isEditing;
   @override
-  final Either<Unit, WorkspaceError> successOrFailure;
+  final Either<Unit, FlowyError> successOrFailure;
 
   @override
   String toString() {
@@ -1150,14 +1150,14 @@ abstract class _ViewState implements ViewState {
   const factory _ViewState(
       {required View view,
       required bool isEditing,
-      required Either<Unit, WorkspaceError> successOrFailure}) = _$_ViewState;
+      required Either<Unit, FlowyError> successOrFailure}) = _$_ViewState;
 
   @override
   View get view => throw _privateConstructorUsedError;
   @override
   bool get isEditing => throw _privateConstructorUsedError;
   @override
-  Either<Unit, WorkspaceError> get successOrFailure =>
+  Either<Unit, FlowyError> get successOrFailure =>
       throw _privateConstructorUsedError;
   @override
   @JsonKey(ignore: true)

+ 5 - 5
frontend/app_flowy/lib/workspace/application/workspace/welcome_bloc.dart

@@ -1,8 +1,8 @@
 import 'package:app_flowy/workspace/domain/i_user.dart';
 import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
 import 'package:flowy_log/flowy_log.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/workspace_create.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/workspace_create.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:dartz/dartz.dart';
@@ -76,7 +76,7 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
     );
   }
 
-  void _workspacesUpdated(Either<List<Workspace>, WorkspaceError> workspacesOrFail) {
+  void _workspacesUpdated(Either<List<Workspace>, FlowyError> workspacesOrFail) {
     add(WelcomeEvent.workspacesReveived(workspacesOrFail));
   }
 }
@@ -87,7 +87,7 @@ class WelcomeEvent with _$WelcomeEvent {
   // const factory WelcomeEvent.fetchWorkspaces() = FetchWorkspace;
   const factory WelcomeEvent.createWorkspace(String name, String desc) = CreateWorkspace;
   const factory WelcomeEvent.openWorkspace(Workspace workspace) = OpenWorkspace;
-  const factory WelcomeEvent.workspacesReveived(Either<List<Workspace>, WorkspaceError> workspacesOrFail) =
+  const factory WelcomeEvent.workspacesReveived(Either<List<Workspace>, FlowyError> workspacesOrFail) =
       WorkspacesReceived;
 }
 
@@ -96,7 +96,7 @@ class WelcomeState with _$WelcomeState {
   const factory WelcomeState({
     required bool isLoading,
     required List<Workspace> workspaces,
-    required Either<Unit, WorkspaceError> successOrFailure,
+    required Either<Unit, FlowyError> successOrFailure,
   }) = _WelcomeState;
 
   factory WelcomeState.initial() => WelcomeState(

+ 30 - 30
frontend/app_flowy/lib/workspace/application/workspace/welcome_bloc.freezed.dart

@@ -35,7 +35,7 @@ class _$WelcomeEventTearOff {
   }
 
   WorkspacesReceived workspacesReveived(
-      Either<List<Workspace>, WorkspaceError> workspacesOrFail) {
+      Either<List<Workspace>, FlowyError> workspacesOrFail) {
     return WorkspacesReceived(
       workspacesOrFail,
     );
@@ -53,7 +53,7 @@ mixin _$WelcomeEvent {
     required TResult Function(String name, String desc) createWorkspace,
     required TResult Function(Workspace workspace) openWorkspace,
     required TResult Function(
-            Either<List<Workspace>, WorkspaceError> workspacesOrFail)
+            Either<List<Workspace>, FlowyError> workspacesOrFail)
         workspacesReveived,
   }) =>
       throw _privateConstructorUsedError;
@@ -62,7 +62,7 @@ mixin _$WelcomeEvent {
     TResult Function()? initial,
     TResult Function(String name, String desc)? createWorkspace,
     TResult Function(Workspace workspace)? openWorkspace,
-    TResult Function(Either<List<Workspace>, WorkspaceError> workspacesOrFail)?
+    TResult Function(Either<List<Workspace>, FlowyError> workspacesOrFail)?
         workspacesReveived,
   }) =>
       throw _privateConstructorUsedError;
@@ -71,7 +71,7 @@ mixin _$WelcomeEvent {
     TResult Function()? initial,
     TResult Function(String name, String desc)? createWorkspace,
     TResult Function(Workspace workspace)? openWorkspace,
-    TResult Function(Either<List<Workspace>, WorkspaceError> workspacesOrFail)?
+    TResult Function(Either<List<Workspace>, FlowyError> workspacesOrFail)?
         workspacesReveived,
     required TResult orElse(),
   }) =>
@@ -160,7 +160,7 @@ class _$Initial implements Initial {
     required TResult Function(String name, String desc) createWorkspace,
     required TResult Function(Workspace workspace) openWorkspace,
     required TResult Function(
-            Either<List<Workspace>, WorkspaceError> workspacesOrFail)
+            Either<List<Workspace>, FlowyError> workspacesOrFail)
         workspacesReveived,
   }) {
     return initial();
@@ -172,7 +172,7 @@ class _$Initial implements Initial {
     TResult Function()? initial,
     TResult Function(String name, String desc)? createWorkspace,
     TResult Function(Workspace workspace)? openWorkspace,
-    TResult Function(Either<List<Workspace>, WorkspaceError> workspacesOrFail)?
+    TResult Function(Either<List<Workspace>, FlowyError> workspacesOrFail)?
         workspacesReveived,
   }) {
     return initial?.call();
@@ -184,7 +184,7 @@ class _$Initial implements Initial {
     TResult Function()? initial,
     TResult Function(String name, String desc)? createWorkspace,
     TResult Function(Workspace workspace)? openWorkspace,
-    TResult Function(Either<List<Workspace>, WorkspaceError> workspacesOrFail)?
+    TResult Function(Either<List<Workspace>, FlowyError> workspacesOrFail)?
         workspacesReveived,
     required TResult orElse(),
   }) {
@@ -316,7 +316,7 @@ class _$CreateWorkspace implements CreateWorkspace {
     required TResult Function(String name, String desc) createWorkspace,
     required TResult Function(Workspace workspace) openWorkspace,
     required TResult Function(
-            Either<List<Workspace>, WorkspaceError> workspacesOrFail)
+            Either<List<Workspace>, FlowyError> workspacesOrFail)
         workspacesReveived,
   }) {
     return createWorkspace(name, desc);
@@ -328,7 +328,7 @@ class _$CreateWorkspace implements CreateWorkspace {
     TResult Function()? initial,
     TResult Function(String name, String desc)? createWorkspace,
     TResult Function(Workspace workspace)? openWorkspace,
-    TResult Function(Either<List<Workspace>, WorkspaceError> workspacesOrFail)?
+    TResult Function(Either<List<Workspace>, FlowyError> workspacesOrFail)?
         workspacesReveived,
   }) {
     return createWorkspace?.call(name, desc);
@@ -340,7 +340,7 @@ class _$CreateWorkspace implements CreateWorkspace {
     TResult Function()? initial,
     TResult Function(String name, String desc)? createWorkspace,
     TResult Function(Workspace workspace)? openWorkspace,
-    TResult Function(Either<List<Workspace>, WorkspaceError> workspacesOrFail)?
+    TResult Function(Either<List<Workspace>, FlowyError> workspacesOrFail)?
         workspacesReveived,
     required TResult orElse(),
   }) {
@@ -467,7 +467,7 @@ class _$OpenWorkspace implements OpenWorkspace {
     required TResult Function(String name, String desc) createWorkspace,
     required TResult Function(Workspace workspace) openWorkspace,
     required TResult Function(
-            Either<List<Workspace>, WorkspaceError> workspacesOrFail)
+            Either<List<Workspace>, FlowyError> workspacesOrFail)
         workspacesReveived,
   }) {
     return openWorkspace(workspace);
@@ -479,7 +479,7 @@ class _$OpenWorkspace implements OpenWorkspace {
     TResult Function()? initial,
     TResult Function(String name, String desc)? createWorkspace,
     TResult Function(Workspace workspace)? openWorkspace,
-    TResult Function(Either<List<Workspace>, WorkspaceError> workspacesOrFail)?
+    TResult Function(Either<List<Workspace>, FlowyError> workspacesOrFail)?
         workspacesReveived,
   }) {
     return openWorkspace?.call(workspace);
@@ -491,7 +491,7 @@ class _$OpenWorkspace implements OpenWorkspace {
     TResult Function()? initial,
     TResult Function(String name, String desc)? createWorkspace,
     TResult Function(Workspace workspace)? openWorkspace,
-    TResult Function(Either<List<Workspace>, WorkspaceError> workspacesOrFail)?
+    TResult Function(Either<List<Workspace>, FlowyError> workspacesOrFail)?
         workspacesReveived,
     required TResult orElse(),
   }) {
@@ -553,7 +553,7 @@ abstract class $WorkspacesReceivedCopyWith<$Res> {
   factory $WorkspacesReceivedCopyWith(
           WorkspacesReceived value, $Res Function(WorkspacesReceived) then) =
       _$WorkspacesReceivedCopyWithImpl<$Res>;
-  $Res call({Either<List<Workspace>, WorkspaceError> workspacesOrFail});
+  $Res call({Either<List<Workspace>, FlowyError> workspacesOrFail});
 }
 
 /// @nodoc
@@ -575,7 +575,7 @@ class _$WorkspacesReceivedCopyWithImpl<$Res>
       workspacesOrFail == freezed
           ? _value.workspacesOrFail
           : workspacesOrFail // ignore: cast_nullable_to_non_nullable
-              as Either<List<Workspace>, WorkspaceError>,
+              as Either<List<Workspace>, FlowyError>,
     ));
   }
 }
@@ -586,7 +586,7 @@ class _$WorkspacesReceived implements WorkspacesReceived {
   const _$WorkspacesReceived(this.workspacesOrFail);
 
   @override
-  final Either<List<Workspace>, WorkspaceError> workspacesOrFail;
+  final Either<List<Workspace>, FlowyError> workspacesOrFail;
 
   @override
   String toString() {
@@ -619,7 +619,7 @@ class _$WorkspacesReceived implements WorkspacesReceived {
     required TResult Function(String name, String desc) createWorkspace,
     required TResult Function(Workspace workspace) openWorkspace,
     required TResult Function(
-            Either<List<Workspace>, WorkspaceError> workspacesOrFail)
+            Either<List<Workspace>, FlowyError> workspacesOrFail)
         workspacesReveived,
   }) {
     return workspacesReveived(workspacesOrFail);
@@ -631,7 +631,7 @@ class _$WorkspacesReceived implements WorkspacesReceived {
     TResult Function()? initial,
     TResult Function(String name, String desc)? createWorkspace,
     TResult Function(Workspace workspace)? openWorkspace,
-    TResult Function(Either<List<Workspace>, WorkspaceError> workspacesOrFail)?
+    TResult Function(Either<List<Workspace>, FlowyError> workspacesOrFail)?
         workspacesReveived,
   }) {
     return workspacesReveived?.call(workspacesOrFail);
@@ -643,7 +643,7 @@ class _$WorkspacesReceived implements WorkspacesReceived {
     TResult Function()? initial,
     TResult Function(String name, String desc)? createWorkspace,
     TResult Function(Workspace workspace)? openWorkspace,
-    TResult Function(Either<List<Workspace>, WorkspaceError> workspacesOrFail)?
+    TResult Function(Either<List<Workspace>, FlowyError> workspacesOrFail)?
         workspacesReveived,
     required TResult orElse(),
   }) {
@@ -693,10 +693,10 @@ class _$WorkspacesReceived implements WorkspacesReceived {
 
 abstract class WorkspacesReceived implements WelcomeEvent {
   const factory WorkspacesReceived(
-          Either<List<Workspace>, WorkspaceError> workspacesOrFail) =
+          Either<List<Workspace>, FlowyError> workspacesOrFail) =
       _$WorkspacesReceived;
 
-  Either<List<Workspace>, WorkspaceError> get workspacesOrFail =>
+  Either<List<Workspace>, FlowyError> get workspacesOrFail =>
       throw _privateConstructorUsedError;
   @JsonKey(ignore: true)
   $WorkspacesReceivedCopyWith<WorkspacesReceived> get copyWith =>
@@ -710,7 +710,7 @@ class _$WelcomeStateTearOff {
   _WelcomeState call(
       {required bool isLoading,
       required List<Workspace> workspaces,
-      required Either<Unit, WorkspaceError> successOrFailure}) {
+      required Either<Unit, FlowyError> successOrFailure}) {
     return _WelcomeState(
       isLoading: isLoading,
       workspaces: workspaces,
@@ -726,7 +726,7 @@ const $WelcomeState = _$WelcomeStateTearOff();
 mixin _$WelcomeState {
   bool get isLoading => throw _privateConstructorUsedError;
   List<Workspace> get workspaces => throw _privateConstructorUsedError;
-  Either<Unit, WorkspaceError> get successOrFailure =>
+  Either<Unit, FlowyError> get successOrFailure =>
       throw _privateConstructorUsedError;
 
   @JsonKey(ignore: true)
@@ -742,7 +742,7 @@ abstract class $WelcomeStateCopyWith<$Res> {
   $Res call(
       {bool isLoading,
       List<Workspace> workspaces,
-      Either<Unit, WorkspaceError> successOrFailure});
+      Either<Unit, FlowyError> successOrFailure});
 }
 
 /// @nodoc
@@ -771,7 +771,7 @@ class _$WelcomeStateCopyWithImpl<$Res> implements $WelcomeStateCopyWith<$Res> {
       successOrFailure: successOrFailure == freezed
           ? _value.successOrFailure
           : successOrFailure // ignore: cast_nullable_to_non_nullable
-              as Either<Unit, WorkspaceError>,
+              as Either<Unit, FlowyError>,
     ));
   }
 }
@@ -786,7 +786,7 @@ abstract class _$WelcomeStateCopyWith<$Res>
   $Res call(
       {bool isLoading,
       List<Workspace> workspaces,
-      Either<Unit, WorkspaceError> successOrFailure});
+      Either<Unit, FlowyError> successOrFailure});
 }
 
 /// @nodoc
@@ -817,7 +817,7 @@ class __$WelcomeStateCopyWithImpl<$Res> extends _$WelcomeStateCopyWithImpl<$Res>
       successOrFailure: successOrFailure == freezed
           ? _value.successOrFailure
           : successOrFailure // ignore: cast_nullable_to_non_nullable
-              as Either<Unit, WorkspaceError>,
+              as Either<Unit, FlowyError>,
     ));
   }
 }
@@ -835,7 +835,7 @@ class _$_WelcomeState implements _WelcomeState {
   @override
   final List<Workspace> workspaces;
   @override
-  final Either<Unit, WorkspaceError> successOrFailure;
+  final Either<Unit, FlowyError> successOrFailure;
 
   @override
   String toString() {
@@ -874,7 +874,7 @@ abstract class _WelcomeState implements WelcomeState {
   const factory _WelcomeState(
           {required bool isLoading,
           required List<Workspace> workspaces,
-          required Either<Unit, WorkspaceError> successOrFailure}) =
+          required Either<Unit, FlowyError> successOrFailure}) =
       _$_WelcomeState;
 
   @override
@@ -882,7 +882,7 @@ abstract class _WelcomeState implements WelcomeState {
   @override
   List<Workspace> get workspaces => throw _privateConstructorUsedError;
   @override
-  Either<Unit, WorkspaceError> get successOrFailure =>
+  Either<Unit, FlowyError> get successOrFailure =>
       throw _privateConstructorUsedError;
   @override
   @JsonKey(ignore: true)

+ 7 - 9
frontend/app_flowy/lib/workspace/domain/i_app.dart

@@ -1,20 +1,18 @@
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/app_create.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/view_create.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
+import 'package:flowy_sdk/protobuf/flowy-core-data-model/protobuf.dart';
 import 'package:dartz/dartz.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 
 typedef AppUpdatedCallback = void Function(App app);
-typedef AppViewsChangeCallback = void Function(Either<List<View>, WorkspaceError> viewsOrFailed);
+typedef AppViewsChangeCallback = void Function(Either<List<View>, FlowyError> viewsOrFailed);
 
 abstract class IApp {
-  Future<Either<List<View>, WorkspaceError>> getViews();
+  Future<Either<List<View>, FlowyError>> getViews();
 
-  Future<Either<View, WorkspaceError>> createView({required String name, String? desc, required ViewType viewType});
+  Future<Either<View, FlowyError>> createView({required String name, String? desc, required ViewType viewType});
 
-  Future<Either<Unit, WorkspaceError>> delete();
+  Future<Either<Unit, FlowyError>> delete();
 
-  Future<Either<Unit, WorkspaceError>> rename(String newName);
+  Future<Either<Unit, FlowyError>> rename(String newName);
 }
 
 abstract class IAppListenr {

+ 5 - 5
frontend/app_flowy/lib/workspace/domain/i_doc.dart

@@ -1,10 +1,10 @@
 import 'dart:async';
 import 'package:dartz/dartz.dart';
-import 'package:flowy_sdk/protobuf/flowy-document-infra/doc.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-collaboration/doc.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 
 abstract class IDoc {
-  Future<Either<DocDelta, WorkspaceError>> readDoc();
-  Future<Either<DocDelta, WorkspaceError>> composeDelta({required String json});
-  Future<Either<Unit, WorkspaceError>> closeDoc();
+  Future<Either<DocDelta, FlowyError>> readDoc();
+  Future<Either<DocDelta, FlowyError>> composeDelta({required String json});
+  Future<Either<Unit, FlowyError>> closeDoc();
 }

Некоторые файлы не были показаны из-за большого количества измененных файлов