diff --git a/app_flowy/lib/workspace/domain/i_doc.dart b/app_flowy/lib/workspace/domain/i_doc.dart index 4527a94455..7956e8fb2b 100644 --- a/app_flowy/lib/workspace/domain/i_doc.dart +++ b/app_flowy/lib/workspace/domain/i_doc.dart @@ -1,6 +1,6 @@ import 'dart:async'; import 'package:dartz/dartz.dart'; -import 'package:flowy_sdk/protobuf/flowy-document/doc.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-document-infra/doc.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart'; abstract class IDoc { diff --git a/app_flowy/lib/workspace/infrastructure/i_doc_impl.dart b/app_flowy/lib/workspace/infrastructure/i_doc_impl.dart index a212bc58a9..a290c96b56 100644 --- a/app_flowy/lib/workspace/infrastructure/i_doc_impl.dart +++ b/app_flowy/lib/workspace/infrastructure/i_doc_impl.dart @@ -4,7 +4,7 @@ import 'dart:typed_data'; import 'package:dartz/dartz.dart'; import 'package:app_flowy/workspace/domain/i_doc.dart'; import 'package:app_flowy/workspace/infrastructure/repos/doc_repo.dart'; -import 'package:flowy_sdk/protobuf/flowy-document/doc.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-document-infra/doc.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart'; class IDocImpl extends IDoc { diff --git a/app_flowy/lib/workspace/infrastructure/repos/doc_repo.dart b/app_flowy/lib/workspace/infrastructure/repos/doc_repo.dart index 2da70bc018..3b0b14a675 100644 --- a/app_flowy/lib/workspace/infrastructure/repos/doc_repo.dart +++ b/app_flowy/lib/workspace/infrastructure/repos/doc_repo.dart @@ -1,6 +1,6 @@ import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; -import 'package:flowy_sdk/protobuf/flowy-document/doc.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-document-infra/doc.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace-infra/view_query.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart'; diff --git a/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart b/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart index 810856f4dc..eca2545988 100644 --- a/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart +++ b/app_flowy/packages/flowy_sdk/lib/dispatch/dispatch.dart @@ -15,7 +15,8 @@ import 'package:flowy_sdk/ffi.dart' as ffi; import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart'; import 'package:flowy_sdk/protobuf/dart-ffi/protobuf.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart'; -import 'package:flowy_sdk/protobuf/flowy-document/protobuf.dart'; +import 'package:flowy_sdk/protobuf/flowy-document-infra/protobuf.dart'; + // ignore: unused_import import 'package:flowy_sdk/protobuf/flowy-infra/protobuf.dart'; import 'package:protobuf/protobuf.dart'; diff --git a/backend/src/service/user/user_default.rs b/backend/src/service/user/user_default.rs index 3628d9e32a..c18a76d9a4 100644 --- a/backend/src/service/user/user_default.rs +++ b/backend/src/service/user/user_default.rs @@ -8,7 +8,7 @@ use crate::{ use crate::service::view::{create_view_with_args, sql_builder::NewViewSqlBuilder}; use chrono::Utc; -use flowy_document_infra::document_default::doc_initial_string; +use flowy_document_infra::user_default::doc_initial_string; use flowy_net::errors::ServerError; use flowy_workspace_infra::protobuf::Workspace; use std::convert::TryInto; diff --git a/backend/tests/document/helper.rs b/backend/tests/document/helper.rs index e1d15de586..e10b30e385 100644 --- a/backend/tests/document/helper.rs +++ b/backend/tests/document/helper.rs @@ -73,10 +73,9 @@ impl ScriptContext { async fn open_doc(&mut self) { let flowy_document = self.flowy_test.sdk.flowy_document.clone(); - let pool = self.client_user_session.db_pool().unwrap(); let doc_id = self.doc_id.clone(); - let edit_context = flowy_document.open(DocIdentifier { doc_id }, pool).await.unwrap(); + let edit_context = flowy_document.open(DocIdentifier { doc_id }).await.unwrap(); self.client_edit_context = Some(edit_context); } diff --git a/rust-lib/flowy-document-infra/src/lib.rs b/rust-lib/flowy-document-infra/src/lib.rs index 7a76152d96..2ed4beec28 100644 --- a/rust-lib/flowy-document-infra/src/lib.rs +++ b/rust-lib/flowy-document-infra/src/lib.rs @@ -1,4 +1,4 @@ -pub mod document_default; pub mod entities; pub mod protobuf; +pub mod user_default; pub mod util; diff --git a/rust-lib/flowy-document-infra/src/document_default.rs b/rust-lib/flowy-document-infra/src/user_default.rs similarity index 53% rename from rust-lib/flowy-document-infra/src/document_default.rs rename to rust-lib/flowy-document-infra/src/user_default.rs index 15cb43003e..a1af02b216 100644 --- a/rust-lib/flowy-document-infra/src/document_default.rs +++ b/rust-lib/flowy-document-infra/src/user_default.rs @@ -1,23 +1,25 @@ use flowy_ot::core::{Delta, DeltaBuilder}; -#[allow(dead_code)] #[inline] pub fn doc_initial_delta() -> Delta { DeltaBuilder::new().insert("\n").build() } -#[allow(dead_code)] + #[inline] pub fn doc_initial_string() -> String { doc_initial_delta().to_json() } -#[allow(dead_code)] + #[inline] -pub fn doc_initial_bytes() -> Vec { doc_initial_string().into_bytes() } +pub fn initial_read_me() -> Delta { + let json = include_str!("READ_ME.json"); + let delta = Delta::from_json(json).unwrap(); + delta +} #[cfg(test)] mod tests { + use crate::user_default::initial_read_me; use flowy_ot::core::Delta; #[test] fn load_read_me() { - let json = include_str!("READ_ME.json"); - let delta = Delta::from_json(json).unwrap(); - assert_eq!(delta.to_json(), json); + println!("{}", initial_read_me().to_json()); } } diff --git a/rust-lib/flowy-document/src/module.rs b/rust-lib/flowy-document/src/module.rs index 5974b0e6e9..f098d66901 100644 --- a/rust-lib/flowy-document/src/module.rs +++ b/rust-lib/flowy-document/src/module.rs @@ -15,10 +15,12 @@ pub trait DocumentUser: Send + Sync { fn user_dir(&self) -> Result; fn user_id(&self) -> Result; fn token(&self) -> Result; + fn db_pool(&self) -> Result, DocError>; } pub struct FlowyDocument { doc_ctrl: Arc, + user: Arc, } impl FlowyDocument { @@ -28,8 +30,8 @@ impl FlowyDocument { server_config: &ServerConfig, ) -> FlowyDocument { let server = construct_doc_server(server_config); - let controller = Arc::new(DocController::new(server.clone(), user.clone(), ws_manager.clone())); - Self { doc_ctrl: controller } + let doc_ctrl = Arc::new(DocController::new(server.clone(), user.clone(), ws_manager.clone())); + Self { doc_ctrl, user } } pub fn init(&self) -> Result<(), DocError> { @@ -42,8 +44,8 @@ impl FlowyDocument { Ok(()) } - pub async fn open(&self, params: DocIdentifier, pool: Arc) -> Result, DocError> { - let edit_context = self.doc_ctrl.open(params, pool).await?; + pub async fn open(&self, params: DocIdentifier) -> Result, DocError> { + let edit_context = self.doc_ctrl.open(params, self.user.db_pool()?).await?; Ok(edit_context) } @@ -65,7 +67,10 @@ impl FlowyDocument { pub async fn apply_doc_delta(&self, params: DocDelta) -> Result { // workaround: compare the rust's delta with flutter's delta. Will be removed // very soon - let doc = self.doc_ctrl.apply_local_delta(params.clone()).await?; + let doc = self + .doc_ctrl + .apply_local_delta(params.clone(), self.user.db_pool()?) + .await?; Ok(doc) } } diff --git a/rust-lib/flowy-document/src/services/cache.rs b/rust-lib/flowy-document/src/services/cache.rs index 6c60196c84..8b0ac76f01 100644 --- a/rust-lib/flowy-document/src/services/cache.rs +++ b/rust-lib/flowy-document/src/services/cache.rs @@ -30,10 +30,10 @@ impl DocCache { self.inner.insert(doc_id, doc); } - pub(crate) fn is_opened(&self, doc_id: &str) -> bool { self.inner.get(doc_id).is_some() } + pub(crate) fn contains(&self, doc_id: &str) -> bool { self.inner.get(doc_id).is_some() } pub(crate) fn get(&self, doc_id: &str) -> Result, DocError> { - if !self.is_opened(&doc_id) { + if !self.contains(&doc_id) { return Err(doc_not_found()); } let opened_doc = self.inner.get(doc_id).unwrap(); diff --git a/rust-lib/flowy-document/src/services/doc/doc_controller.rs b/rust-lib/flowy-document/src/services/doc/doc_controller.rs index bdb17745b6..e597853ae8 100644 --- a/rust-lib/flowy-document/src/services/doc/doc_controller.rs +++ b/rust-lib/flowy-document/src/services/doc/doc_controller.rs @@ -47,7 +47,7 @@ impl DocController { params: DocIdentifier, pool: Arc, ) -> Result, DocError> { - if self.cache.is_opened(¶ms.doc_id) == false { + if self.cache.contains(¶ms.doc_id) == false { let edit_ctx = self.make_edit_context(¶ms.doc_id, pool.clone()).await?; return Ok(edit_ctx); } @@ -74,8 +74,17 @@ impl DocController { // as None e.g. // json : {"retain":7,"attributes":{"bold":null}} // deserialize delta: [ {retain: 7, attributes: {Bold: AttributeValue(None)}} ] - #[tracing::instrument(level = "debug", skip(self, delta), fields(doc_id = %delta.doc_id), err)] - pub(crate) async fn apply_local_delta(&self, delta: DocDelta) -> Result { + #[tracing::instrument(level = "debug", skip(self, delta, db_pool), fields(doc_id = %delta.doc_id), err)] + pub(crate) async fn apply_local_delta( + &self, + delta: DocDelta, + db_pool: Arc, + ) -> Result { + if !self.cache.contains(&delta.doc_id) { + let doc_identifier: DocIdentifier = delta.doc_id.clone().into(); + let _ = self.open(doc_identifier, db_pool).await?; + } + let edit_doc_ctx = self.cache.get(&delta.doc_id)?; let _ = edit_doc_ctx.composing_local_delta(Bytes::from(delta.data)).await?; Ok(edit_doc_ctx.delta().await?) diff --git a/rust-lib/flowy-document/src/services/doc/document/document.rs b/rust-lib/flowy-document/src/services/doc/document/document.rs index bf9a48f74c..1df8df75e8 100644 --- a/rust-lib/flowy-document/src/services/doc/document/document.rs +++ b/rust-lib/flowy-document/src/services/doc/document/document.rs @@ -2,7 +2,7 @@ use crate::{ errors::DocError, services::doc::{view::View, History, UndoResult, RECORD_THRESHOLD}, }; -use flowy_document_infra::document_default::doc_initial_delta; +use flowy_document_infra::user_default::doc_initial_delta; use flowy_ot::core::*; use tokio::sync::mpsc; diff --git a/rust-lib/flowy-document/src/services/server/server_api_mock.rs b/rust-lib/flowy-document/src/services/server/server_api_mock.rs index b999e19218..29cc85e577 100644 --- a/rust-lib/flowy-document/src/services/server/server_api_mock.rs +++ b/rust-lib/flowy-document/src/services/server/server_api_mock.rs @@ -1,7 +1,7 @@ use crate::{errors::DocError, services::server::DocumentServerAPI}; use flowy_document_infra::{ - document_default::doc_initial_string, entities::doc::{CreateDocParams, Doc, DocIdentifier, UpdateDocParams}, + user_default::doc_initial_string, }; use flowy_infra::future::ResultFuture; diff --git a/rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs b/rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs index 5a826c408a..cee1a8dd38 100644 --- a/rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs +++ b/rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs @@ -8,6 +8,7 @@ use flowy_document::{ use flowy_user::{errors::ErrorCode, services::user::UserSession}; use flowy_ws::{WsMessage, WsMessageHandler, WsModule}; +use flowy_database::ConnectionPool; use flowy_document::services::ws::{DocumentWebSocket, WsDocumentManager}; use flowy_user::errors::UserError; use std::{path::Path, sync::Arc}; @@ -63,6 +64,8 @@ impl DocumentUser for DocumentUserImpl { fn user_id(&self) -> Result { self.user.user_id().map_err(map_user_error) } fn token(&self) -> Result { self.user.token().map_err(map_user_error) } + + fn db_pool(&self) -> Result, DocError> { self.user.db_pool().map_err(map_user_error) } } struct WsSenderImpl { diff --git a/rust-lib/flowy-workspace-infra/src/entities/view/view_create.rs b/rust-lib/flowy-workspace-infra/src/entities/view/view_create.rs index e66092de1c..35479c5342 100644 --- a/rust-lib/flowy-workspace-infra/src/entities/view/view_create.rs +++ b/rust-lib/flowy-workspace-infra/src/entities/view/view_create.rs @@ -8,7 +8,7 @@ use crate::{ }, }; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; -use flowy_document_infra::document_default::doc_initial_string; +use flowy_document_infra::user_default::doc_initial_string; use std::convert::TryInto; #[derive(PartialEq, Debug, ProtoBuf_Enum, Clone)] diff --git a/rust-lib/flowy-workspace/src/services/view_controller.rs b/rust-lib/flowy-workspace/src/services/view_controller.rs index 8213f09bbf..53996b5702 100644 --- a/rust-lib/flowy-workspace/src/services/view_controller.rs +++ b/rust-lib/flowy-workspace/src/services/view_controller.rs @@ -108,7 +108,7 @@ impl ViewController { #[tracing::instrument(level = "debug", skip(self, params), fields(doc_id = %params.doc_id), err)] pub(crate) async fn open_view(&self, params: DocIdentifier) -> Result { let doc_id = params.doc_id.clone(); - let edit_context = self.document.open(params, self.database.db_pool()?).await?; + let edit_context = self.document.open(params).await?; KV::set_str(LATEST_VIEW_ID, doc_id); Ok(edit_context.delta().await.map_err(internal_error)?) diff --git a/rust-lib/flowy-workspace/src/services/workspace_controller.rs b/rust-lib/flowy-workspace/src/services/workspace_controller.rs index bfaa575a1d..83373aab3c 100644 --- a/rust-lib/flowy-workspace/src/services/workspace_controller.rs +++ b/rust-lib/flowy-workspace/src/services/workspace_controller.rs @@ -7,6 +7,7 @@ use crate::{ }; use chrono::Utc; use flowy_database::SqliteConnection; +use flowy_document_infra::{entities::doc::DocDelta, user_default::initial_read_me}; use flowy_infra::kv::KV; use flowy_workspace_infra::{ entities::{app::RepeatedApp, view::View, workspace::*}, @@ -101,6 +102,13 @@ impl WorkspaceController { let _ = self.app_controller.create_app(app).await?; for (index, view) in views.into_iter().enumerate() { if index == 0 { + let delta = initial_read_me(); + let doc_delta = DocDelta { + doc_id: view.id.clone(), + data: delta.to_json(), + }; + let _ = self.view_controller.apply_doc_delta(doc_delta).await?; + self.view_controller.set_latest_view(&view); } let _ = self.view_controller.create_view(view).await?;