chore: fix database row sync (#4964)

* chore: fix database row sync

* ci: fix test

* ci: fix web build

* chore: bump collab
This commit is contained in:
Nathan.fooo
2024-03-23 09:18:47 +08:00
committed by GitHub
parent c0642d3ff3
commit b307312a71
45 changed files with 364 additions and 347 deletions

View File

@ -838,7 +838,7 @@ dependencies = [
[[package]] [[package]]
name = "collab" name = "collab"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -862,7 +862,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-database" name = "collab-database"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -892,7 +892,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-document" name = "collab-document"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",
@ -911,7 +911,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-entity" name = "collab-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -926,7 +926,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-folder" name = "collab-folder"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -952,6 +952,7 @@ dependencies = [
"collab", "collab",
"collab-entity", "collab-entity",
"collab-plugins", "collab-plugins",
"futures",
"lib-infra", "lib-infra",
"parking_lot 0.12.1", "parking_lot 0.12.1",
"serde", "serde",
@ -963,7 +964,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-plugins" name = "collab-plugins"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-stream", "async-stream",
@ -1002,7 +1003,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-user" name = "collab-user"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",

View File

@ -96,10 +96,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9
# To switch to the local path, run: # To switch to the local path, run:
# scripts/tool/update_collab_source.sh # scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️ # ⚠️⚠️⚠️️
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }

View File

@ -636,7 +636,7 @@ dependencies = [
[[package]] [[package]]
name = "collab" name = "collab"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -660,7 +660,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-document" name = "collab-document"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",
@ -679,7 +679,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-entity" name = "collab-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -694,7 +694,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-folder" name = "collab-folder"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -720,6 +720,7 @@ dependencies = [
"collab", "collab",
"collab-entity", "collab-entity",
"collab-plugins", "collab-plugins",
"futures",
"lib-infra", "lib-infra",
"parking_lot 0.12.1", "parking_lot 0.12.1",
"serde", "serde",
@ -731,7 +732,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-plugins" name = "collab-plugins"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-stream", "async-stream",
@ -769,7 +770,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-user" name = "collab-user"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",
@ -5025,4 +5026,4 @@ dependencies = [
[[patch.unused]] [[patch.unused]]
name = "collab-database" name = "collab-database"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"

View File

@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9
# To switch to the local path, run: # To switch to the local path, run:
# scripts/tool/update_collab_source.sh # scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️ # ⚠️⚠️⚠️️
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }

View File

@ -2,7 +2,7 @@ use crate::authenticate_user::AuthenticateUser;
use crate::define::{user_profile_key, user_workspace_key, AF_USER_SESSION_KEY}; use crate::define::{user_profile_key, user_workspace_key, AF_USER_SESSION_KEY};
use af_persistence::store::{AppFlowyWASMStore, IndexddbStore}; use af_persistence::store::{AppFlowyWASMStore, IndexddbStore};
use anyhow::Context; use anyhow::Context;
use collab::core::collab::CollabDocState; use collab::core::collab::DocStateSource;
use collab_entity::CollabType; use collab_entity::CollabType;
use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig}; use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig};
use collab_integrate::{CollabKVDB, MutexCollab}; use collab_integrate::{CollabKVDB, MutexCollab};
@ -200,7 +200,7 @@ impl UserManager {
&self, &self,
session: &Session, session: &Session,
collab_db: Weak<CollabKVDB>, collab_db: Weak<CollabKVDB>,
raw_data: CollabDocState, raw_data: Vec<u8>,
) -> Result<Arc<MutexCollab>, FlowyError> { ) -> Result<Arc<MutexCollab>, FlowyError> {
let collab_builder = self.collab_builder.upgrade().ok_or(FlowyError::new( let collab_builder = self.collab_builder.upgrade().ok_or(FlowyError::new(
ErrorCode::Internal, ErrorCode::Internal,
@ -212,7 +212,7 @@ impl UserManager {
session.user_id, session.user_id,
&user_awareness_id.to_string(), &user_awareness_id.to_string(),
CollabType::UserAwareness, CollabType::UserAwareness,
raw_data, DocStateSource::FromDocState(raw_data),
collab_db, collab_db,
CollabBuilderConfig::default().sync_enable(true), CollabBuilderConfig::default().sync_enable(true),
) )

View File

@ -55,8 +55,8 @@ impl CollabCloudPluginProvider for ServerProviderWASM {
CollabPluginProviderType::AppFlowyCloud CollabPluginProviderType::AppFlowyCloud
} }
fn get_plugins(&self, _context: CollabPluginProviderContext) -> Fut<Vec<Box<dyn CollabPlugin>>> { fn get_plugins(&self, _context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>> {
to_fut(async move { vec![] }) vec![]
} }
fn is_sync_enabled(&self) -> bool { fn is_sync_enabled(&self) -> bool {

View File

@ -764,7 +764,7 @@ dependencies = [
[[package]] [[package]]
name = "collab" name = "collab"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -788,7 +788,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-database" name = "collab-database"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -818,7 +818,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-document" name = "collab-document"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",
@ -837,7 +837,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-entity" name = "collab-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -852,7 +852,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-folder" name = "collab-folder"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@ -878,6 +878,7 @@ dependencies = [
"collab", "collab",
"collab-entity", "collab-entity",
"collab-plugins", "collab-plugins",
"futures",
"lib-infra", "lib-infra",
"parking_lot 0.12.1", "parking_lot 0.12.1",
"serde", "serde",
@ -889,7 +890,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-plugins" name = "collab-plugins"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-stream", "async-stream",
@ -928,7 +929,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-user" name = "collab-user"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collab", "collab",

View File

@ -120,10 +120,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9
# To switch to the local path, run: # To switch to the local path, run:
# scripts/tool/update_collab_source.sh # scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️ # ⚠️⚠️⚠️️
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" } collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }

View File

@ -19,6 +19,7 @@ parking_lot.workspace = true
async-trait.workspace = true async-trait.workspace = true
tokio = { workspace = true, features = ["sync"]} tokio = { workspace = true, features = ["sync"]}
lib-infra = { workspace = true } lib-infra = { workspace = true }
futures = "0.3"
[features] [features]
default = [] default = []

View File

@ -3,7 +3,7 @@ use std::sync::{Arc, Weak};
use crate::CollabKVDB; use crate::CollabKVDB;
use anyhow::Error; use anyhow::Error;
use collab::core::collab::{CollabDocState, MutexCollab}; use collab::core::collab::{DocStateSource, MutexCollab};
use collab::preclude::CollabBuilder; use collab::preclude::CollabBuilder;
use collab_entity::{CollabObject, CollabType}; use collab_entity::{CollabObject, CollabType};
use collab_plugins::connect_state::{CollabConnectReachability, CollabConnectState}; use collab_plugins::connect_state::{CollabConnectReachability, CollabConnectState};
@ -68,7 +68,7 @@ impl Display for CollabPluginProviderContext {
pub struct AppFlowyCollabBuilder { pub struct AppFlowyCollabBuilder {
network_reachability: CollabConnectReachability, network_reachability: CollabConnectReachability,
workspace_id: RwLock<Option<String>>, workspace_id: RwLock<Option<String>>,
plugin_provider: tokio::sync::RwLock<Arc<dyn CollabCloudPluginProvider>>, plugin_provider: RwLock<Arc<dyn CollabCloudPluginProvider>>,
snapshot_persistence: Mutex<Option<Arc<dyn SnapshotPersistence>>>, snapshot_persistence: Mutex<Option<Arc<dyn SnapshotPersistence>>>,
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
rocksdb_backup: Mutex<Option<Arc<dyn RocksdbBackup>>>, rocksdb_backup: Mutex<Option<Arc<dyn RocksdbBackup>>>,
@ -97,7 +97,7 @@ impl AppFlowyCollabBuilder {
Self { Self {
network_reachability: CollabConnectReachability::new(), network_reachability: CollabConnectReachability::new(),
workspace_id: Default::default(), workspace_id: Default::default(),
plugin_provider: tokio::sync::RwLock::new(Arc::new(storage_provider)), plugin_provider: RwLock::new(Arc::new(storage_provider)),
snapshot_persistence: Default::default(), snapshot_persistence: Default::default(),
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
rocksdb_backup: Default::default(), rocksdb_backup: Default::default(),
@ -167,22 +167,20 @@ impl AppFlowyCollabBuilder {
uid: i64, uid: i64,
object_id: &str, object_id: &str,
object_type: CollabType, object_type: CollabType,
collab_doc_state: CollabDocState, collab_doc_state: DocStateSource,
collab_db: Weak<CollabKVDB>, collab_db: Weak<CollabKVDB>,
build_config: CollabBuilderConfig, build_config: CollabBuilderConfig,
) -> Result<Arc<MutexCollab>, Error> { ) -> Result<Arc<MutexCollab>, Error> {
let persistence_config = CollabPersistenceConfig::default(); let persistence_config = CollabPersistenceConfig::default();
self self.build_with_config(
.build_with_config( uid,
uid, object_id,
object_id, object_type,
object_type, collab_db,
collab_db, collab_doc_state,
collab_doc_state, persistence_config,
persistence_config, build_config,
build_config, )
)
.await
} }
/// Creates a new collaboration builder with the custom configuration. /// Creates a new collaboration builder with the custom configuration.
@ -200,13 +198,13 @@ impl AppFlowyCollabBuilder {
/// - `collab_db`: A weak reference to the [CollabKVDB]. /// - `collab_db`: A weak reference to the [CollabKVDB].
/// ///
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub async fn build_with_config( pub fn build_with_config(
&self, &self,
uid: i64, uid: i64,
object_id: &str, object_id: &str,
object_type: CollabType, object_type: CollabType,
collab_db: Weak<CollabKVDB>, collab_db: Weak<CollabKVDB>,
collab_doc_state: CollabDocState, collab_doc_state: DocStateSource,
#[allow(unused_variables)] persistence_config: CollabPersistenceConfig, #[allow(unused_variables)] persistence_config: CollabPersistenceConfig,
build_config: CollabBuilderConfig, build_config: CollabBuilderConfig,
) -> Result<Arc<MutexCollab>, Error> { ) -> Result<Arc<MutexCollab>, Error> {
@ -240,23 +238,22 @@ impl AppFlowyCollabBuilder {
{ {
let collab_object = self.collab_object(uid, object_id, object_type)?; let collab_object = self.collab_object(uid, object_id, object_type)?;
if build_config.sync_enable { if build_config.sync_enable {
let provider_type = self.plugin_provider.read().await.provider_type(); let provider_type = self.plugin_provider.read().provider_type();
let span = tracing::span!(tracing::Level::TRACE, "collab_builder", object_id = %object_id); let span = tracing::span!(tracing::Level::TRACE, "collab_builder", object_id = %object_id);
let _enter = span.enter(); let _enter = span.enter();
match provider_type { match provider_type {
CollabPluginProviderType::AppFlowyCloud => { CollabPluginProviderType::AppFlowyCloud => {
trace!("init appflowy cloud collab plugins"); trace!("init appflowy cloud collab plugins");
let local_collab = Arc::downgrade(&collab); let local_collab = Arc::downgrade(&collab);
let plugins = self let plugins =
.plugin_provider self
.read() .plugin_provider
.await .read()
.get_plugins(CollabPluginProviderContext::AppFlowyCloud { .get_plugins(CollabPluginProviderContext::AppFlowyCloud {
uid, uid,
collab_object, collab_object,
local_collab, local_collab,
}) });
.await;
trace!("add appflowy cloud collab plugins: {}", plugins.len()); trace!("add appflowy cloud collab plugins: {}", plugins.len());
for plugin in plugins { for plugin in plugins {
@ -269,17 +266,16 @@ impl AppFlowyCollabBuilder {
trace!("init supabase collab plugins"); trace!("init supabase collab plugins");
let local_collab = Arc::downgrade(&collab); let local_collab = Arc::downgrade(&collab);
let local_collab_db = collab_db.clone(); let local_collab_db = collab_db.clone();
let plugins = self let plugins =
.plugin_provider self
.read() .plugin_provider
.await .read()
.get_plugins(CollabPluginProviderContext::Supabase { .get_plugins(CollabPluginProviderContext::Supabase {
uid, uid,
collab_object, collab_object,
local_collab, local_collab,
local_collab_db, local_collab_db,
}) });
.await;
for plugin in plugins { for plugin in plugins {
collab.lock().add_plugin(plugin); collab.lock().add_plugin(plugin);
} }
@ -291,7 +287,7 @@ impl AppFlowyCollabBuilder {
} }
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
collab.lock().initialize().await; futures::executor::block_on(collab.lock().initialize());
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
collab.lock().initialize(); collab.lock().initialize();

View File

@ -1,12 +1,11 @@
use crate::collab_builder::{CollabPluginProviderContext, CollabPluginProviderType}; use crate::collab_builder::{CollabPluginProviderContext, CollabPluginProviderType};
use collab::preclude::CollabPlugin; use collab::preclude::CollabPlugin;
use lib_infra::future::Fut;
use std::sync::Arc; use std::sync::Arc;
pub trait CollabCloudPluginProvider: Send + Sync + 'static { pub trait CollabCloudPluginProvider: Send + Sync + 'static {
fn provider_type(&self) -> CollabPluginProviderType; fn provider_type(&self) -> CollabPluginProviderType;
fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut<Vec<Box<dyn CollabPlugin>>>; fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>>;
fn is_sync_enabled(&self) -> bool; fn is_sync_enabled(&self) -> bool;
} }
@ -19,7 +18,7 @@ where
(**self).provider_type() (**self).provider_type()
} }
fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut<Vec<Box<dyn CollabPlugin>>> { fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>> {
(**self).get_plugins(context) (**self).get_plugins(context)
} }

View File

@ -2,12 +2,11 @@ use crate::collab_builder::{CollabPluginProviderContext, CollabPluginProviderTyp
use collab::preclude::CollabPlugin; use collab::preclude::CollabPlugin;
use lib_infra::future::Fut; use lib_infra::future::Fut;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc;
pub trait CollabCloudPluginProvider: 'static { pub trait CollabCloudPluginProvider: 'static {
fn provider_type(&self) -> CollabPluginProviderType; fn provider_type(&self) -> CollabPluginProviderType;
fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut<Vec<Box<dyn CollabPlugin>>>; fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>>;
fn is_sync_enabled(&self) -> bool; fn is_sync_enabled(&self) -> bool;
} }
@ -20,7 +19,7 @@ where
(**self).provider_type() (**self).provider_type()
} }
fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut<Vec<Box<dyn CollabPlugin>>> { fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>> {
(**self).get_plugins(context) (**self).get_plugins(context)
} }

View File

@ -1,4 +1,4 @@
use collab::core::collab::CollabDocState; use collab::core::collab::DocStateSource;
use collab::core::origin::CollabOrigin; use collab::core::origin::CollabOrigin;
use collab_document::blocks::DocumentData; use collab_document::blocks::DocumentData;
use collab_document::document::Document; use collab_document::document::Document;
@ -108,31 +108,34 @@ impl EventIntegrationTest {
pub async fn get_collab_doc_state( pub async fn get_collab_doc_state(
&self, &self,
oid: &str, oid: &str,
collay_type: CollabType, collab_type: CollabType,
) -> Result<CollabDocState, FlowyError> { ) -> Result<Vec<u8>, FlowyError> {
let server = self.server_provider.get_server().unwrap(); let server = self.server_provider.get_server().unwrap();
let workspace_id = self.get_current_workspace().await.id; let workspace_id = self.get_current_workspace().await.id;
let uid = self.get_user_profile().await?.id; let uid = self.get_user_profile().await?.id;
let doc_state = server let doc_state = server
.folder_service() .folder_service()
.get_folder_doc_state(&workspace_id, uid, collay_type, oid) .get_folder_doc_state(&workspace_id, uid, collab_type, oid)
.await?; .await?;
Ok(doc_state) Ok(doc_state)
} }
} }
pub fn document_data_from_document_doc_state( pub fn document_data_from_document_doc_state(doc_id: &str, doc_state: Vec<u8>) -> DocumentData {
doc_id: &str,
doc_state: CollabDocState,
) -> DocumentData {
document_from_document_doc_state(doc_id, doc_state) document_from_document_doc_state(doc_id, doc_state)
.get_document_data() .get_document_data()
.unwrap() .unwrap()
} }
pub fn document_from_document_doc_state(doc_id: &str, doc_state: CollabDocState) -> Document { pub fn document_from_document_doc_state(doc_id: &str, doc_state: Vec<u8>) -> Document {
Document::from_doc_state(CollabOrigin::Empty, doc_state, doc_id, vec![]).unwrap() Document::from_doc_state(
CollabOrigin::Empty,
DocStateSource::FromDocState(doc_state),
doc_id,
vec![],
)
.unwrap()
} }
async fn init_core(config: AppFlowyCoreConfig) -> AppFlowyCore { async fn init_core(config: AppFlowyCoreConfig) -> AppFlowyCore {

View File

@ -3,7 +3,7 @@ use std::sync::Arc;
use anyhow::Error; use anyhow::Error;
use client_api::collab_sync::{SinkConfig, SyncObject, SyncPlugin}; use client_api::collab_sync::{SinkConfig, SyncObject, SyncPlugin};
use collab::core::collab::CollabDocState;
use collab::core::origin::{CollabClient, CollabOrigin}; use collab::core::origin::{CollabClient, CollabOrigin};
use collab::preclude::CollabPlugin; use collab::preclude::CollabPlugin;
use collab_entity::CollabType; use collab_entity::CollabType;
@ -26,7 +26,7 @@ use flowy_server_pub::supabase_config::SupabaseConfiguration;
use flowy_storage::ObjectValue; use flowy_storage::ObjectValue;
use flowy_user_pub::cloud::{UserCloudService, UserCloudServiceProvider}; use flowy_user_pub::cloud::{UserCloudService, UserCloudServiceProvider};
use flowy_user_pub::entities::{Authenticator, UserTokenState}; use flowy_user_pub::entities::{Authenticator, UserTokenState};
use lib_infra::future::{to_fut, Fut, FutureResult}; use lib_infra::future::FutureResult;
use crate::integrate::server::{Server, ServerProvider}; use crate::integrate::server::{Server, ServerProvider};
@ -184,7 +184,7 @@ impl FolderCloudService for ServerProvider {
uid: i64, uid: i64,
collab_type: CollabType, collab_type: CollabType,
object_id: &str, object_id: &str,
) -> FutureResult<CollabDocState, Error> { ) -> FutureResult<Vec<u8>, Error> {
let object_id = object_id.to_string(); let object_id = object_id.to_string();
let workspace_id = workspace_id.to_string(); let workspace_id = workspace_id.to_string();
let server = self.get_server(); let server = self.get_server();
@ -225,7 +225,7 @@ impl DatabaseCloudService for ServerProvider {
object_id: &str, object_id: &str,
collab_type: CollabType, collab_type: CollabType,
workspace_id: &str, workspace_id: &str,
) -> FutureResult<CollabDocState, Error> { ) -> FutureResult<Vec<u8>, Error> {
let workspace_id = workspace_id.to_string(); let workspace_id = workspace_id.to_string();
let server = self.get_server(); let server = self.get_server();
let database_id = object_id.to_string(); let database_id = object_id.to_string();
@ -274,7 +274,7 @@ impl DocumentCloudService for ServerProvider {
&self, &self,
document_id: &str, document_id: &str,
workspace_id: &str, workspace_id: &str,
) -> FutureResult<CollabDocState, FlowyError> { ) -> FutureResult<Vec<u8>, FlowyError> {
let workspace_id = workspace_id.to_string(); let workspace_id = workspace_id.to_string();
let document_id = document_id.to_string(); let document_id = document_id.to_string();
let server = self.get_server(); let server = self.get_server();
@ -326,61 +326,58 @@ impl CollabCloudPluginProvider for ServerProvider {
} }
#[instrument(level = "debug", skip(self, context), fields(server_type = %self.get_server_type()))] #[instrument(level = "debug", skip(self, context), fields(server_type = %self.get_server_type()))]
fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut<Vec<Box<dyn CollabPlugin>>> { fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>> {
// If the user is local, we don't need to create a sync plugin. // If the user is local, we don't need to create a sync plugin.
if self.get_server_type().is_local() { if self.get_server_type().is_local() {
debug!( debug!(
"User authenticator is local, skip create sync plugin for: {}", "User authenticator is local, skip create sync plugin for: {}",
context context
); );
return to_fut(async move { vec![] }); return vec![];
} }
match context { match context {
CollabPluginProviderContext::Local => to_fut(async move { vec![] }), CollabPluginProviderContext::Local => vec![],
CollabPluginProviderContext::AppFlowyCloud { CollabPluginProviderContext::AppFlowyCloud {
uid: _, uid: _,
collab_object, collab_object,
local_collab, local_collab,
} => { } => {
if let Ok(server) = self.get_server() { if let Ok(server) = self.get_server() {
to_fut(async move { // to_fut(async move {
let mut plugins: Vec<Box<dyn CollabPlugin>> = vec![]; let mut plugins: Vec<Box<dyn CollabPlugin>> = vec![];
// If the user is local, we don't need to create a sync plugin.
// If the user is local, we don't need to create a sync plugin. match server.collab_ws_channel(&collab_object.object_id) {
Ok(Some((channel, ws_connect_state, is_connected))) => {
match server.collab_ws_channel(&collab_object.object_id).await { let origin = CollabOrigin::Client(CollabClient::new(
Ok(Some((channel, ws_connect_state, is_connected))) => { collab_object.uid,
let origin = CollabOrigin::Client(CollabClient::new( collab_object.device_id.clone(),
collab_object.uid, ));
collab_object.device_id.clone(), let sync_object = SyncObject::from(collab_object);
)); let (sink, stream) = (channel.sink(), channel.stream());
let sync_object = SyncObject::from(collab_object); let sink_config = SinkConfig::new().send_timeout(8);
let (sink, stream) = (channel.sink(), channel.stream()); let sync_plugin = SyncPlugin::new(
let sink_config = SinkConfig::new().send_timeout(8); origin,
let sync_plugin = SyncPlugin::new( sync_object,
origin, local_collab,
sync_object, sink,
local_collab, sink_config,
sink, stream,
sink_config, Some(channel),
stream, !is_connected,
Some(channel), ws_connect_state,
!is_connected, );
ws_connect_state, plugins.push(Box::new(sync_plugin));
); },
plugins.push(Box::new(sync_plugin)); Ok(None) => {
}, tracing::error!("🔴Failed to get collab ws channel: channel is none");
Ok(None) => { },
tracing::error!("🔴Failed to get collab ws channel: channel is none"); Err(err) => tracing::error!("🔴Failed to get collab ws channel: {:?}", err),
}, }
Err(err) => tracing::error!("🔴Failed to get collab ws channel: {:?}", err), plugins
}
plugins
})
} else { } else {
to_fut(async move { vec![] }) vec![]
} }
}, },
CollabPluginProviderContext::Supabase { CollabPluginProviderContext::Supabase {
@ -404,8 +401,7 @@ impl CollabCloudPluginProvider for ServerProvider {
local_collab_db, local_collab_db,
))); )));
} }
plugins
to_fut(async move { plugins })
}, },
} }
} }

View File

@ -1,12 +1,10 @@
use anyhow::Error;
use collab::core::collab::DocStateSource;
use collab_entity::CollabType;
use lib_infra::future::FutureResult;
use std::collections::HashMap; use std::collections::HashMap;
use anyhow::Error; pub type CollabDocStateByOid = HashMap<String, DocStateSource>;
use collab::core::collab::CollabDocState;
use collab_entity::CollabType;
use lib_infra::future::FutureResult;
pub type CollabDocStateByOid = HashMap<String, CollabDocState>;
/// A trait for database cloud service. /// A trait for database cloud service.
/// Each kind of server should implement this trait. Check out the [AppFlowyServerProvider] of /// Each kind of server should implement this trait. Check out the [AppFlowyServerProvider] of
@ -17,7 +15,7 @@ pub trait DatabaseCloudService: Send + Sync {
object_id: &str, object_id: &str,
collab_type: CollabType, collab_type: CollabType,
workspace_id: &str, workspace_id: &str,
) -> FutureResult<CollabDocState, Error>; ) -> FutureResult<Vec<u8>, Error>;
fn batch_get_database_object_doc_state( fn batch_get_database_object_doc_state(
&self, &self,

View File

@ -2,7 +2,7 @@ use std::collections::HashMap;
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use collab::core::collab::{CollabDocState, MutexCollab}; use collab::core::collab::{DocStateSource, MutexCollab};
use collab_database::blocks::BlockEvent; use collab_database::blocks::BlockEvent;
use collab_database::database::{get_inline_view_id, DatabaseData, MutexDatabase}; use collab_database::database::{get_inline_view_id, DatabaseData, MutexDatabase};
use collab_database::error::DatabaseError; use collab_database::error::DatabaseError;
@ -12,7 +12,7 @@ use collab_database::user::{
use collab_database::views::{CreateDatabaseParams, CreateViewParams, DatabaseLayout}; use collab_database::views::{CreateDatabaseParams, CreateViewParams, DatabaseLayout};
use collab_entity::CollabType; use collab_entity::CollabType;
use collab_plugins::local_storage::kv::KVTransactionDB; use collab_plugins::local_storage::kv::KVTransactionDB;
use futures::executor::block_on;
use lru::LruCache; use lru::LruCache;
use tokio::sync::{Mutex, RwLock}; use tokio::sync::{Mutex, RwLock};
use tracing::{event, instrument, trace}; use tracing::{event, instrument, trace};
@ -98,7 +98,7 @@ impl DatabaseManager {
}; };
let config = CollabPersistenceConfig::new().snapshot_per_update(100); let config = CollabPersistenceConfig::new().snapshot_per_update(100);
let mut workspace_database_doc_state = CollabDocState::default(); let mut workspace_database_doc_state = DocStateSource::FromDisk;
// If the workspace database not exist in disk, try to fetch from remote. // If the workspace database not exist in disk, try to fetch from remote.
if !self.is_collab_exist(uid, &collab_db, &workspace_database_object_id) { if !self.is_collab_exist(uid, &collab_db, &workspace_database_object_id) {
trace!("workspace database not exist, try to fetch from remote"); trace!("workspace database not exist, try to fetch from remote");
@ -111,8 +111,8 @@ impl DatabaseManager {
) )
.await .await
{ {
Ok(remote_doc_state) => { Ok(doc_state) => {
workspace_database_doc_state = remote_doc_state; workspace_database_doc_state = DocStateSource::FromDocState(doc_state);
}, },
Err(err) => { Err(err) => {
return Err(FlowyError::record_not_found().with_context(format!( return Err(FlowyError::record_not_found().with_context(format!(
@ -423,7 +423,7 @@ impl DatabaseCollabService for UserDatabaseCollabServiceImpl {
&self, &self,
object_id: &str, object_id: &str,
object_ty: CollabType, object_ty: CollabType,
) -> CollabFuture<Result<CollabDocState, DatabaseError>> { ) -> CollabFuture<Result<DocStateSource, DatabaseError>> {
let workspace_id = self.workspace_id.clone(); let workspace_id = self.workspace_id.clone();
let object_id = object_id.to_string(); let object_id = object_id.to_string();
let weak_cloud_service = Arc::downgrade(&self.cloud_service); let weak_cloud_service = Arc::downgrade(&self.cloud_service);
@ -431,13 +431,13 @@ impl DatabaseCollabService for UserDatabaseCollabServiceImpl {
match weak_cloud_service.upgrade() { match weak_cloud_service.upgrade() {
None => { None => {
tracing::warn!("Cloud service is dropped"); tracing::warn!("Cloud service is dropped");
Ok(vec![]) Ok(DocStateSource::FromDocState(vec![]))
}, },
Some(cloud_service) => { Some(cloud_service) => {
let updates = cloud_service let doc_state = cloud_service
.get_database_object_doc_state(&object_id, object_ty, &workspace_id) .get_database_object_doc_state(&object_id, object_ty, &workspace_id)
.await?; .await?;
Ok(updates) Ok(DocStateSource::FromDocState(doc_state))
}, },
} }
}) })
@ -472,18 +472,20 @@ impl DatabaseCollabService for UserDatabaseCollabServiceImpl {
object_id: &str, object_id: &str,
object_type: CollabType, object_type: CollabType,
collab_db: Weak<CollabKVDB>, collab_db: Weak<CollabKVDB>,
collab_raw_data: CollabDocState, collab_raw_data: DocStateSource,
persistence_config: CollabPersistenceConfig, persistence_config: CollabPersistenceConfig,
) -> Arc<MutexCollab> { ) -> Arc<MutexCollab> {
block_on(self.collab_builder.build_with_config( self
uid, .collab_builder
object_id, .build_with_config(
object_type, uid,
collab_db, object_id,
collab_raw_data, object_type,
persistence_config, collab_db,
CollabBuilderConfig::default().sync_enable(true), collab_raw_data,
)) persistence_config,
.unwrap() CollabBuilderConfig::default().sync_enable(true),
)
.unwrap()
} }
} }

View File

@ -805,6 +805,7 @@ impl DatabaseEditor {
}?; }?;
(field, database.get_cell(field_id, &row_id).cell) (field, database.get_cell(field_id, &row_id).cell)
}; };
let new_cell = let new_cell =
apply_cell_changeset(cell_changeset, cell, &field, Some(self.cell_cache.clone()))?; apply_cell_changeset(cell_changeset, cell, &field, Some(self.cell_cache.clone()))?;
self.update_cell(view_id, row_id, field_id, new_cell).await self.update_cell(view_id, row_id, field_id, new_cell).await

View File

@ -1,5 +1,4 @@
use anyhow::Error; use anyhow::Error;
use collab::core::collab::CollabDocState;
pub use collab_document::blocks::DocumentData; pub use collab_document::blocks::DocumentData;
use flowy_error::FlowyError; use flowy_error::FlowyError;
@ -13,7 +12,7 @@ pub trait DocumentCloudService: Send + Sync + 'static {
&self, &self,
document_id: &str, document_id: &str,
workspace_id: &str, workspace_id: &str,
) -> FutureResult<CollabDocState, FlowyError>; ) -> FutureResult<Vec<u8>, FlowyError>;
fn get_document_snapshots( fn get_document_snapshots(
&self, &self,

View File

@ -2,7 +2,7 @@ use std::num::NonZeroUsize;
use std::sync::Arc; use std::sync::Arc;
use std::sync::Weak; use std::sync::Weak;
use collab::core::collab::{CollabDocState, MutexCollab}; use collab::core::collab::{DocStateSource, MutexCollab};
use collab::core::collab_plugin::EncodedCollab; use collab::core::collab_plugin::EncodedCollab;
use collab::core::origin::CollabOrigin; use collab::core::origin::CollabOrigin;
use collab::preclude::Collab; use collab::preclude::Collab;
@ -16,8 +16,6 @@ use lru::LruCache;
use parking_lot::Mutex; use parking_lot::Mutex;
use tokio::io::AsyncWriteExt; use tokio::io::AsyncWriteExt;
use tracing::error; use tracing::error;
use tracing::info;
use tracing::warn;
use tracing::{event, instrument}; use tracing::{event, instrument};
use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig}; use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig};
@ -122,7 +120,7 @@ impl DocumentManager {
.doc_state .doc_state
.to_vec(); .to_vec();
let collab = self let collab = self
.collab_for_document(uid, doc_id, doc_state, false) .collab_for_document(uid, doc_id, DocStateSource::FromDocState(doc_state), false)
.await?; .await?;
collab.lock().flush(); collab.lock().flush();
Ok(()) Ok(())
@ -138,14 +136,16 @@ impl DocumentManager {
return Ok(doc); return Ok(doc);
} }
let mut doc_state = CollabDocState::default(); let mut doc_state = DocStateSource::FromDisk;
// If the document does not exist in local disk, try get the doc state from the cloud. This happens // If the document does not exist in local disk, try get the doc state from the cloud. This happens
// When user_device_a create a document and user_device_b open the document. // When user_device_a create a document and user_device_b open the document.
if !self.is_doc_exist(doc_id).await? { if !self.is_doc_exist(doc_id).await? {
doc_state = self doc_state = DocStateSource::FromDocState(
.cloud_service self
.get_document_doc_state(doc_id, &self.user_service.workspace_id()?) .cloud_service
.await?; .get_document_doc_state(doc_id, &self.user_service.workspace_id()?)
.await?,
);
// the doc_state should not be empty if remote return the doc state without error. // the doc_state should not be empty if remote return the doc state without error.
if doc_state.is_empty() { if doc_state.is_empty() {
@ -183,16 +183,16 @@ impl DocumentManager {
} }
pub async fn get_document_data(&self, doc_id: &str) -> FlowyResult<DocumentData> { pub async fn get_document_data(&self, doc_id: &str) -> FlowyResult<DocumentData> {
let mut updates = vec![]; let mut doc_state = vec![];
if !self.is_doc_exist(doc_id).await? { if !self.is_doc_exist(doc_id).await? {
updates = self doc_state = self
.cloud_service .cloud_service
.get_document_doc_state(doc_id, &self.user_service.workspace_id()?) .get_document_doc_state(doc_id, &self.user_service.workspace_id()?)
.await?; .await?;
} }
let uid = self.user_service.user_id()?; let uid = self.user_service.user_id()?;
let collab = self let collab = self
.collab_for_document(uid, doc_id, updates, false) .collab_for_document(uid, doc_id, DocStateSource::FromDocState(doc_state), false)
.await?; .await?;
Document::open(collab)? Document::open(collab)?
.get_document_data() .get_document_data()
@ -284,7 +284,7 @@ impl DocumentManager {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
{ {
if tokio::fs::metadata(&local_file_path).await.is_ok() { if tokio::fs::metadata(&local_file_path).await.is_ok() {
warn!("file already exist in user local disk: {}", local_file_path); tracing::warn!("file already exist in user local disk: {}", local_file_path);
return Ok(()); return Ok(());
} }
@ -298,7 +298,7 @@ impl DocumentManager {
.await?; .await?;
let n = file.write(&object_value.raw).await?; let n = file.write(&object_value.raw).await?;
info!("downloaded {} bytes to file: {}", n, local_file_path); tracing::info!("downloaded {} bytes to file: {}", n, local_file_path);
} }
Ok(()) Ok(())
} }
@ -326,22 +326,19 @@ impl DocumentManager {
&self, &self,
uid: i64, uid: i64,
doc_id: &str, doc_id: &str,
doc_state: CollabDocState, doc_state: DocStateSource,
sync_enable: bool, sync_enable: bool,
) -> FlowyResult<Arc<MutexCollab>> { ) -> FlowyResult<Arc<MutexCollab>> {
let db = self.user_service.collab_db(uid)?; let db = self.user_service.collab_db(uid)?;
let collab = self let collab = self.collab_builder.build_with_config(
.collab_builder uid,
.build_with_config( doc_id,
uid, CollabType::Document,
doc_id, db,
CollabType::Document, doc_state,
db, CollabPersistenceConfig::default().snapshot_per_update(1000),
doc_state, CollabBuilderConfig::default().sync_enable(sync_enable),
CollabPersistenceConfig::default().snapshot_per_update(1000), )?;
CollabBuilderConfig::default().sync_enable(sync_enable),
)
.await?;
Ok(collab) Ok(collab)
} }

View File

@ -2,7 +2,6 @@ use std::ops::Deref;
use std::sync::Arc; use std::sync::Arc;
use anyhow::Error; use anyhow::Error;
use collab::core::collab::CollabDocState;
use collab::preclude::CollabPlugin; use collab::preclude::CollabPlugin;
use collab_document::blocks::DocumentData; use collab_document::blocks::DocumentData;
use collab_document::document_data::default_document_data; use collab_document::document_data::default_document_data;
@ -24,7 +23,7 @@ use flowy_document_pub::cloud::*;
use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_storage::ObjectStorageService; use flowy_storage::ObjectStorageService;
use lib_infra::async_trait::async_trait; use lib_infra::async_trait::async_trait;
use lib_infra::future::{to_fut, Fut, FutureResult}; use lib_infra::future::FutureResult;
pub struct DocumentTest { pub struct DocumentTest {
inner: DocumentManager, inner: DocumentManager,
@ -135,7 +134,7 @@ impl DocumentCloudService for LocalTestDocumentCloudServiceImpl {
&self, &self,
document_id: &str, document_id: &str,
_workspace_id: &str, _workspace_id: &str,
) -> FutureResult<CollabDocState, FlowyError> { ) -> FutureResult<Vec<u8>, FlowyError> {
let document_id = document_id.to_string(); let document_id = document_id.to_string();
FutureResult::new(async move { FutureResult::new(async move {
Err(FlowyError::new( Err(FlowyError::new(
@ -197,8 +196,8 @@ impl CollabCloudPluginProvider for DefaultCollabStorageProvider {
CollabPluginProviderType::Local CollabPluginProviderType::Local
} }
fn get_plugins(&self, _context: CollabPluginProviderContext) -> Fut<Vec<Box<dyn CollabPlugin>>> { fn get_plugins(&self, _context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>> {
to_fut(async move { vec![] }) vec![]
} }
fn is_sync_enabled(&self) -> bool { fn is_sync_enabled(&self) -> bool {

View File

@ -1,5 +1,4 @@
pub use anyhow::Error; pub use anyhow::Error;
use collab::core::collab::CollabDocState;
use collab_entity::CollabType; use collab_entity::CollabType;
pub use collab_folder::{Folder, FolderData, Workspace}; pub use collab_folder::{Folder, FolderData, Workspace};
use uuid::Uuid; use uuid::Uuid;
@ -36,7 +35,7 @@ pub trait FolderCloudService: Send + Sync + 'static {
uid: i64, uid: i64,
collab_type: CollabType, collab_type: CollabType,
object_id: &str, object_id: &str,
) -> FutureResult<CollabDocState, Error>; ) -> FutureResult<Vec<u8>, Error>;
fn batch_create_folder_collab_objects( fn batch_create_folder_collab_objects(
&self, &self,

View File

@ -1,25 +1,3 @@
use std::fmt::{Display, Formatter};
use std::ops::Deref;
use std::sync::{Arc, Weak};
use collab::core::collab::{CollabDocState, MutexCollab};
use collab_entity::CollabType;
use collab_folder::error::FolderError;
use collab_folder::{
Folder, FolderData, FolderNotify, Section, SectionItem, TrashInfo, UserId, View, ViewLayout,
ViewUpdate, Workspace,
};
use parking_lot::{Mutex, RwLock};
use tracing::{error, info, instrument};
use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig};
use collab_integrate::{CollabKVDB, CollabPersistenceConfig};
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_folder_pub::cloud::{gen_view_id, FolderCloudService};
use flowy_folder_pub::folder_builder::ParentChildViews;
use lib_infra::conditional_send_sync_trait;
use crate::entities::icon::UpdateViewIconParams; use crate::entities::icon::UpdateViewIconParams;
use crate::entities::{ use crate::entities::{
view_pb_with_child_views, view_pb_without_child_views, CreateViewParams, CreateWorkspaceParams, view_pb_with_child_views, view_pb_without_child_views, CreateViewParams, CreateWorkspaceParams,
@ -38,6 +16,24 @@ use crate::util::{
folder_not_init_error, insert_parent_child_views, workspace_data_not_sync_error, folder_not_init_error, insert_parent_child_views, workspace_data_not_sync_error,
}; };
use crate::view_operation::{create_view, FolderOperationHandler, FolderOperationHandlers}; use crate::view_operation::{create_view, FolderOperationHandler, FolderOperationHandlers};
use collab::core::collab::{DocStateSource, MutexCollab};
use collab_entity::CollabType;
use collab_folder::error::FolderError;
use collab_folder::{
Folder, FolderData, FolderNotify, Section, SectionItem, TrashInfo, UserId, View, ViewLayout,
ViewUpdate, Workspace,
};
use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig};
use collab_integrate::{CollabKVDB, CollabPersistenceConfig};
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_folder_pub::cloud::{gen_view_id, FolderCloudService};
use flowy_folder_pub::folder_builder::ParentChildViews;
use lib_infra::conditional_send_sync_trait;
use parking_lot::{Mutex, RwLock};
use std::fmt::{Display, Formatter};
use std::ops::Deref;
use std::sync::{Arc, Weak};
use tracing::{error, info, instrument};
conditional_send_sync_trait! { conditional_send_sync_trait! {
"[crate::manager::FolderUser] represents the user for folder."; "[crate::manager::FolderUser] represents the user for folder.";
@ -164,24 +160,21 @@ impl FolderManager {
uid: i64, uid: i64,
workspace_id: &str, workspace_id: &str,
collab_db: Weak<CollabKVDB>, collab_db: Weak<CollabKVDB>,
collab_doc_state: CollabDocState, doc_state: DocStateSource,
folder_notifier: T, folder_notifier: T,
) -> Result<Folder, FlowyError> { ) -> Result<Folder, FlowyError> {
let folder_notifier = folder_notifier.into(); let folder_notifier = folder_notifier.into();
let collab = self let collab = self.collab_builder.build_with_config(
.collab_builder uid,
.build_with_config( workspace_id,
uid, CollabType::Folder,
workspace_id, collab_db,
CollabType::Folder, doc_state,
collab_db, CollabPersistenceConfig::new()
collab_doc_state, .enable_snapshot(true)
CollabPersistenceConfig::new() .snapshot_per_update(50),
.enable_snapshot(true) CollabBuilderConfig::default().sync_enable(true),
.snapshot_per_update(50), )?;
CollabBuilderConfig::default().sync_enable(true),
)
.await?;
let (should_clear, err) = match Folder::open(UserId::from(uid), collab, folder_notifier) { let (should_clear, err) = match Folder::open(UserId::from(uid), collab, folder_notifier) {
Ok(folder) => { Ok(folder) => {
return Ok(folder); return Ok(folder);
@ -207,20 +200,17 @@ impl FolderManager {
workspace_id: &str, workspace_id: &str,
collab_db: Weak<CollabKVDB>, collab_db: Weak<CollabKVDB>,
) -> Result<Arc<MutexCollab>, FlowyError> { ) -> Result<Arc<MutexCollab>, FlowyError> {
let collab = self let collab = self.collab_builder.build_with_config(
.collab_builder uid,
.build_with_config( workspace_id,
uid, CollabType::Folder,
workspace_id, collab_db,
CollabType::Folder, DocStateSource::FromDocState(vec![]),
collab_db, CollabPersistenceConfig::new()
vec![], .enable_snapshot(true)
CollabPersistenceConfig::new() .snapshot_per_update(50),
.enable_snapshot(true) CollabBuilderConfig::default().sync_enable(true),
.snapshot_per_update(50), )?;
CollabBuilderConfig::default().sync_enable(true),
)
.await?;
Ok(collab) Ok(collab)
} }
@ -1229,7 +1219,7 @@ pub enum FolderInitDataSource {
/// It means using the data stored on local disk to initialize the folder /// It means using the data stored on local disk to initialize the folder
LocalDisk { create_if_not_exist: bool }, LocalDisk { create_if_not_exist: bool },
/// If there is no data stored on local disk, we will use the data from the server to initialize the folder /// If there is no data stored on local disk, we will use the data from the server to initialize the folder
Cloud(CollabDocState), Cloud(Vec<u8>),
/// If the user is new, we use the [DefaultFolderBuilder] to create the default folder. /// If the user is new, we use the [DefaultFolderBuilder] to create the default folder.
FolderData(FolderData), FolderData(FolderData),
} }

View File

@ -6,6 +6,7 @@ use collab_integrate::CollabKVDB;
use flowy_error::{FlowyError, FlowyResult}; use flowy_error::{FlowyError, FlowyResult};
use collab::core::collab::DocStateSource;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use tracing::{event, Level}; use tracing::{event, Level};
@ -54,7 +55,13 @@ impl FolderManager {
if is_exist { if is_exist {
event!(Level::INFO, "Init folder from local disk"); event!(Level::INFO, "Init folder from local disk");
self self
.make_folder(uid, &workspace_id, collab_db, vec![], folder_notifier) .make_folder(
uid,
&workspace_id,
collab_db,
DocStateSource::FromDisk,
folder_notifier,
)
.await? .await?
} else if create_if_not_exist { } else if create_if_not_exist {
// 2. if the folder doesn't exist and create_if_not_exist is true, create a default folder // 2. if the folder doesn't exist and create_if_not_exist is true, create a default folder
@ -76,7 +83,7 @@ impl FolderManager {
uid, uid,
&workspace_id, &workspace_id,
collab_db.clone(), collab_db.clone(),
doc_state, DocStateSource::FromDocState(doc_state),
folder_notifier.clone(), folder_notifier.clone(),
) )
.await? .await?
@ -86,7 +93,13 @@ impl FolderManager {
if doc_state.is_empty() { if doc_state.is_empty() {
event!(Level::ERROR, "remote folder data is empty, open from local"); event!(Level::ERROR, "remote folder data is empty, open from local");
self self
.make_folder(uid, &workspace_id, collab_db, vec![], folder_notifier) .make_folder(
uid,
&workspace_id,
collab_db,
DocStateSource::FromDisk,
folder_notifier,
)
.await? .await?
} else { } else {
event!(Level::INFO, "Restore folder from remote data"); event!(Level::INFO, "Restore folder from remote data");
@ -95,7 +108,7 @@ impl FolderManager {
uid, uid,
&workspace_id, &workspace_id,
collab_db.clone(), collab_db.clone(),
doc_state, DocStateSource::FromDocState(doc_state),
folder_notifier.clone(), folder_notifier.clone(),
) )
.await? .await?

View File

@ -2,7 +2,7 @@ use anyhow::Error;
use client_api::entity::QueryCollabResult::{Failed, Success}; use client_api::entity::QueryCollabResult::{Failed, Success};
use client_api::entity::{QueryCollab, QueryCollabParams}; use client_api::entity::{QueryCollab, QueryCollabParams};
use client_api::error::ErrorCode::RecordNotFound; use client_api::error::ErrorCode::RecordNotFound;
use collab::core::collab::CollabDocState; use collab::core::collab::DocStateSource;
use collab::core::collab_plugin::EncodedCollab; use collab::core::collab_plugin::EncodedCollab;
use collab_entity::CollabType; use collab_entity::CollabType;
use tracing::error; use tracing::error;
@ -23,7 +23,7 @@ where
object_id: &str, object_id: &str,
collab_type: CollabType, collab_type: CollabType,
workspace_id: &str, workspace_id: &str,
) -> FutureResult<CollabDocState, Error> { ) -> FutureResult<Vec<u8>, Error> {
let workspace_id = workspace_id.to_string(); let workspace_id = workspace_id.to_string();
let object_id = object_id.to_string(); let object_id = object_id.to_string();
let try_get_client = self.0.try_get_client(); let try_get_client = self.0.try_get_client();
@ -73,7 +73,10 @@ where
.flat_map(|(object_id, result)| match result { .flat_map(|(object_id, result)| match result {
Success { encode_collab_v1 } => { Success { encode_collab_v1 } => {
match EncodedCollab::decode_from_bytes(&encode_collab_v1) { match EncodedCollab::decode_from_bytes(&encode_collab_v1) {
Ok(encode) => Some((object_id, encode.doc_state.to_vec())), Ok(encode) => Some((
object_id,
DocStateSource::FromDocState(encode.doc_state.to_vec()),
)),
Err(err) => { Err(err) => {
error!("Failed to decode collab: {}", err); error!("Failed to decode collab: {}", err);
None None

View File

@ -1,6 +1,6 @@
use anyhow::Error; use anyhow::Error;
use client_api::entity::{QueryCollab, QueryCollabParams}; use client_api::entity::{QueryCollab, QueryCollabParams};
use collab::core::collab::CollabDocState; use collab::core::collab::DocStateSource;
use collab::core::origin::CollabOrigin; use collab::core::origin::CollabOrigin;
use collab_document::document::Document; use collab_document::document::Document;
use collab_entity::CollabType; use collab_entity::CollabType;
@ -21,7 +21,7 @@ where
&self, &self,
document_id: &str, document_id: &str,
workspace_id: &str, workspace_id: &str,
) -> FutureResult<CollabDocState, FlowyError> { ) -> FutureResult<Vec<u8>, FlowyError> {
let workspace_id = workspace_id.to_string(); let workspace_id = workspace_id.to_string();
let try_get_client = self.0.try_get_client(); let try_get_client = self.0.try_get_client();
let document_id = document_id.to_string(); let document_id = document_id.to_string();
@ -74,8 +74,12 @@ where
.map_err(FlowyError::from)? .map_err(FlowyError::from)?
.doc_state .doc_state
.to_vec(); .to_vec();
let document = let document = Document::from_doc_state(
Document::from_doc_state(CollabOrigin::Empty, doc_state, &document_id, vec![])?; CollabOrigin::Empty,
DocStateSource::FromDocState(doc_state),
&document_id,
vec![],
)?;
Ok(document.get_document_data().ok()) Ok(document.get_document_data().ok())
}) })
} }

View File

@ -2,7 +2,7 @@ use anyhow::Error;
use client_api::entity::{ use client_api::entity::{
workspace_dto::CreateWorkspaceParam, CollabParams, QueryCollab, QueryCollabParams, workspace_dto::CreateWorkspaceParam, CollabParams, QueryCollab, QueryCollabParams,
}; };
use collab::core::collab::CollabDocState; use collab::core::collab::DocStateSource;
use collab::core::origin::CollabOrigin; use collab::core::origin::CollabOrigin;
use collab_entity::CollabType; use collab_entity::CollabType;
use collab_folder::RepeatedViewIdentifier; use collab_folder::RepeatedViewIdentifier;
@ -96,8 +96,13 @@ where
.map_err(FlowyError::from)? .map_err(FlowyError::from)?
.doc_state .doc_state
.to_vec(); .to_vec();
let folder = let folder = Folder::from_collab_doc_state(
Folder::from_collab_doc_state(uid, CollabOrigin::Empty, doc_state, &workspace_id, vec![])?; uid,
CollabOrigin::Empty,
DocStateSource::FromDocState(doc_state),
&workspace_id,
vec![],
)?;
Ok(folder.get_folder_data()) Ok(folder.get_folder_data())
}) })
} }
@ -116,7 +121,7 @@ where
_uid: i64, _uid: i64,
collab_type: CollabType, collab_type: CollabType,
object_id: &str, object_id: &str,
) -> FutureResult<CollabDocState, Error> { ) -> FutureResult<Vec<u8>, Error> {
let object_id = object_id.to_string(); let object_id = object_id.to_string();
let workspace_id = workspace_id.to_string(); let workspace_id = workspace_id.to_string();
let try_get_client = self.0.try_get_client(); let try_get_client = self.0.try_get_client();

View File

@ -7,7 +7,6 @@ use client_api::entity::workspace_dto::{
}; };
use client_api::entity::{AFRole, AFWorkspace, AuthProvider, CollabParams, CreateCollabParams}; use client_api::entity::{AFRole, AFWorkspace, AuthProvider, CollabParams, CreateCollabParams};
use client_api::{Client, ClientConfiguration}; use client_api::{Client, ClientConfiguration};
use collab::core::collab::CollabDocState;
use collab_entity::CollabObject; use collab_entity::CollabObject;
use parking_lot::RwLock; use parking_lot::RwLock;
@ -239,7 +238,7 @@ where
}) })
} }
fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult<CollabDocState, FlowyError> { fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult<Vec<u8>, FlowyError> {
FutureResult::new(async { Ok(vec![]) }) FutureResult::new(async { Ok(vec![]) })
} }

View File

@ -25,7 +25,6 @@ use flowy_server_pub::af_cloud_config::AFCloudConfiguration;
use flowy_user_pub::cloud::{UserCloudService, UserUpdate}; use flowy_user_pub::cloud::{UserCloudService, UserUpdate};
use flowy_user_pub::entities::UserTokenState; use flowy_user_pub::entities::UserTokenState;
use lib_dispatch::prelude::af_spawn; use lib_dispatch::prelude::af_spawn;
use lib_infra::future::FutureResult;
use crate::af_cloud::impls::{ use crate::af_cloud::impls::{
AFCloudDatabaseCloudServiceImpl, AFCloudDocumentCloudServiceImpl, AFCloudFileStorageServiceImpl, AFCloudDatabaseCloudServiceImpl, AFCloudDocumentCloudServiceImpl, AFCloudFileStorageServiceImpl,
@ -196,7 +195,7 @@ impl AppFlowyServer for AppFlowyCloudServer {
fn collab_ws_channel( fn collab_ws_channel(
&self, &self,
_object_id: &str, _object_id: &str,
) -> FutureResult< ) -> Result<
Option<( Option<(
Arc<WebSocketChannel<ServerCollabMessage>>, Arc<WebSocketChannel<ServerCollabMessage>>,
WSConnectStateReceiver, WSConnectStateReceiver,
@ -204,22 +203,10 @@ impl AppFlowyServer for AppFlowyCloudServer {
)>, )>,
Error, Error,
> { > {
if self.enable_sync.load(Ordering::SeqCst) { let object_id = _object_id.to_string();
let object_id = _object_id.to_string(); let channel = self.ws_client.subscribe_collab(object_id).ok();
let weak_ws_client = Arc::downgrade(&self.ws_client); let connect_state_recv = self.ws_client.subscribe_connect_state();
FutureResult::new(async move { Ok(channel.map(|c| (c, connect_state_recv, self.ws_client.is_connected())))
match weak_ws_client.upgrade() {
None => Ok(None),
Some(ws_client) => {
let channel = ws_client.subscribe_collab(object_id).ok();
let connect_state_recv = ws_client.subscribe_connect_state();
Ok(channel.map(|c| (c, connect_state_recv, ws_client.is_connected())))
},
}
})
} else {
FutureResult::new(async { Ok(None) })
}
} }
fn file_storage(&self) -> Option<Arc<dyn ObjectStorageService>> { fn file_storage(&self) -> Option<Arc<dyn ObjectStorageService>> {

View File

@ -1,5 +1,4 @@
use anyhow::Error; use anyhow::Error;
use collab::core::collab::CollabDocState;
use collab_entity::CollabType; use collab_entity::CollabType;
use flowy_database_pub::cloud::{CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot}; use flowy_database_pub::cloud::{CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot};
@ -13,7 +12,7 @@ impl DatabaseCloudService for LocalServerDatabaseCloudServiceImpl {
_object_id: &str, _object_id: &str,
_collab_type: CollabType, _collab_type: CollabType,
_workspace_id: &str, _workspace_id: &str,
) -> FutureResult<CollabDocState, Error> { ) -> FutureResult<Vec<u8>, Error> {
FutureResult::new(async move { Ok(vec![]) }) FutureResult::new(async move { Ok(vec![]) })
} }

View File

@ -1,5 +1,4 @@
use anyhow::Error; use anyhow::Error;
use collab::core::collab::CollabDocState;
use flowy_document_pub::cloud::*; use flowy_document_pub::cloud::*;
use flowy_error::{ErrorCode, FlowyError}; use flowy_error::{ErrorCode, FlowyError};
@ -12,7 +11,7 @@ impl DocumentCloudService for LocalServerDocumentCloudServiceImpl {
&self, &self,
document_id: &str, document_id: &str,
_workspace_id: &str, _workspace_id: &str,
) -> FutureResult<CollabDocState, FlowyError> { ) -> FutureResult<Vec<u8>, FlowyError> {
let document_id = document_id.to_string(); let document_id = document_id.to_string();
FutureResult::new(async move { FutureResult::new(async move {
Err(FlowyError::new( Err(FlowyError::new(

View File

@ -1,7 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use anyhow::{anyhow, Error}; use anyhow::{anyhow, Error};
use collab::core::collab::CollabDocState;
use collab_entity::CollabType; use collab_entity::CollabType;
use flowy_folder_pub::cloud::{ use flowy_folder_pub::cloud::{
@ -59,7 +58,7 @@ impl FolderCloudService for LocalServerFolderCloudServiceImpl {
_uid: i64, _uid: i64,
_collab_type: CollabType, _collab_type: CollabType,
_object_id: &str, _object_id: &str,
) -> FutureResult<CollabDocState, Error> { ) -> FutureResult<Vec<u8>, Error> {
FutureResult::new(async { FutureResult::new(async {
Err(anyhow!( Err(anyhow!(
"Local server doesn't support get collab doc state from remote" "Local server doesn't support get collab doc state from remote"

View File

@ -1,6 +1,5 @@
use std::sync::Arc; use std::sync::Arc;
use collab::core::collab::CollabDocState;
use collab_entity::CollabObject; use collab_entity::CollabObject;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use parking_lot::Mutex; use parking_lot::Mutex;
@ -149,7 +148,7 @@ impl UserCloudService for LocalServerUserAuthServiceImpl {
FutureResult::new(async { Ok(vec![]) }) FutureResult::new(async { Ok(vec![]) })
} }
fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult<CollabDocState, FlowyError> { fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult<Vec<u8>, FlowyError> {
FutureResult::new(async { Ok(vec![]) }) FutureResult::new(async { Ok(vec![]) })
} }

View File

@ -16,7 +16,6 @@ use flowy_document_pub::cloud::DocumentCloudService;
use flowy_folder_pub::cloud::FolderCloudService; use flowy_folder_pub::cloud::FolderCloudService;
use flowy_user_pub::cloud::UserCloudService; use flowy_user_pub::cloud::UserCloudService;
use flowy_user_pub::entities::UserTokenState; use flowy_user_pub::entities::UserTokenState;
use lib_infra::future::FutureResult;
pub trait AppFlowyEncryption: Send + Sync + 'static { pub trait AppFlowyEncryption: Send + Sync + 'static {
fn get_secret(&self) -> Option<String>; fn get_secret(&self) -> Option<String>;
@ -123,7 +122,7 @@ pub trait AppFlowyServer: Send + Sync + 'static {
fn collab_ws_channel( fn collab_ws_channel(
&self, &self,
_object_id: &str, _object_id: &str,
) -> FutureResult< ) -> Result<
Option<( Option<(
Arc<WebSocketChannel<ServerCollabMessage>>, Arc<WebSocketChannel<ServerCollabMessage>>,
WSConnectStateReceiver, WSConnectStateReceiver,
@ -131,7 +130,7 @@ pub trait AppFlowyServer: Send + Sync + 'static {
)>, )>,
anyhow::Error, anyhow::Error,
> { > {
FutureResult::new(async { Ok(None) }) Ok(None)
} }
fn file_storage(&self) -> Option<Arc<dyn ObjectStorageService>>; fn file_storage(&self) -> Option<Arc<dyn ObjectStorageService>>;

View File

@ -4,7 +4,7 @@ use std::sync::{Arc, Weak};
use anyhow::Error; use anyhow::Error;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use client_api::collab_sync::collab_msg::MsgId; use client_api::collab_sync::collab_msg::MsgId;
use collab::core::collab::CollabDocState; use collab::core::collab::DocStateSource;
use collab::preclude::merge_updates_v1; use collab::preclude::merge_updates_v1;
use collab_entity::CollabObject; use collab_entity::CollabObject;
use collab_plugins::cloud_storage::{ use collab_plugins::cloud_storage::{
@ -62,7 +62,7 @@ where
true true
} }
async fn get_doc_state(&self, object: &CollabObject) -> Result<CollabDocState, Error> { async fn get_doc_state(&self, object: &CollabObject) -> Result<DocStateSource, Error> {
let postgrest = self.server.try_get_weak_postgrest()?; let postgrest = self.server.try_get_weak_postgrest()?;
let action = FetchObjectUpdateAction::new( let action = FetchObjectUpdateAction::new(
object.object_id.clone(), object.object_id.clone(),
@ -70,7 +70,7 @@ where
postgrest, postgrest,
); );
let doc_state = action.run().await?; let doc_state = action.run().await?;
Ok(doc_state) Ok(DocStateSource::FromDocState(doc_state))
} }
async fn get_snapshots(&self, object_id: &str, limit: usize) -> Vec<RemoteCollabSnapshot> { async fn get_snapshots(&self, object_id: &str, limit: usize) -> Vec<RemoteCollabSnapshot> {

View File

@ -1,5 +1,4 @@
use anyhow::Error; use anyhow::Error;
use collab::core::collab::CollabDocState;
use collab_entity::CollabType; use collab_entity::CollabType;
use tokio::sync::oneshot::channel; use tokio::sync::oneshot::channel;
@ -31,7 +30,7 @@ where
object_id: &str, object_id: &str,
collab_type: CollabType, collab_type: CollabType,
_workspace_id: &str, _workspace_id: &str,
) -> FutureResult<CollabDocState, Error> { ) -> FutureResult<Vec<u8>, Error> {
let try_get_postgrest = self.server.try_get_weak_postgrest(); let try_get_postgrest = self.server.try_get_weak_postgrest();
let object_id = object_id.to_string(); let object_id = object_id.to_string();
let (tx, rx) = channel(); let (tx, rx) = channel();

View File

@ -1,5 +1,5 @@
use anyhow::Error; use anyhow::Error;
use collab::core::collab::CollabDocState; use collab::core::collab::DocStateSource;
use collab::core::origin::CollabOrigin; use collab::core::origin::CollabOrigin;
use collab_document::blocks::DocumentData; use collab_document::blocks::DocumentData;
use collab_document::document::Document; use collab_document::document::Document;
@ -33,7 +33,7 @@ where
&self, &self,
document_id: &str, document_id: &str,
workspace_id: &str, workspace_id: &str,
) -> FutureResult<CollabDocState, FlowyError> { ) -> FutureResult<Vec<u8>, FlowyError> {
let try_get_postgrest = self.server.try_get_weak_postgrest(); let try_get_postgrest = self.server.try_get_weak_postgrest();
let document_id = document_id.to_string(); let document_id = document_id.to_string();
let (tx, rx) = channel(); let (tx, rx) = channel();
@ -94,8 +94,12 @@ where
let action = let action =
FetchObjectUpdateAction::new(document_id.clone(), CollabType::Document, postgrest); FetchObjectUpdateAction::new(document_id.clone(), CollabType::Document, postgrest);
let doc_state = action.run_with_fix_interval(5, 10).await?; let doc_state = action.run_with_fix_interval(5, 10).await?;
let document = let document = Document::from_doc_state(
Document::from_doc_state(CollabOrigin::Empty, doc_state, &document_id, vec![])?; CollabOrigin::Empty,
DocStateSource::FromDocState(doc_state),
&document_id,
vec![],
)?;
Ok(document.get_document_data().ok()) Ok(document.get_document_data().ok())
} }
.await, .await,

View File

@ -2,7 +2,7 @@ use std::str::FromStr;
use anyhow::{anyhow, Error}; use anyhow::{anyhow, Error};
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use collab::core::collab::CollabDocState; use collab::core::collab::DocStateSource;
use collab::core::origin::CollabOrigin; use collab::core::origin::CollabOrigin;
use collab_entity::CollabType; use collab_entity::CollabType;
use serde_json::Value; use serde_json::Value;
@ -102,8 +102,13 @@ where
let doc_state = merge_updates_v1(&updates) let doc_state = merge_updates_v1(&updates)
.map_err(|err| anyhow::anyhow!("merge updates failed: {:?}", err))?; .map_err(|err| anyhow::anyhow!("merge updates failed: {:?}", err))?;
let folder = let folder = Folder::from_collab_doc_state(
Folder::from_collab_doc_state(uid, CollabOrigin::Empty, doc_state, &workspace_id, vec![])?; uid,
CollabOrigin::Empty,
DocStateSource::FromDocState(doc_state),
&workspace_id,
vec![],
)?;
Ok(folder.get_folder_data()) Ok(folder.get_folder_data())
}) })
} }
@ -137,7 +142,7 @@ where
_uid: i64, _uid: i64,
collab_type: CollabType, collab_type: CollabType,
object_id: &str, object_id: &str,
) -> FutureResult<CollabDocState, Error> { ) -> FutureResult<Vec<u8>, Error> {
let try_get_postgrest = self.server.try_get_weak_postgrest(); let try_get_postgrest = self.server.try_get_weak_postgrest();
let object_id = object_id.to_string(); let object_id = object_id.to_string();
let (tx, rx) = channel(); let (tx, rx) = channel();

View File

@ -7,7 +7,7 @@ use std::time::Duration;
use anyhow::Error; use anyhow::Error;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use collab::core::collab::CollabDocState; use collab::core::collab::DocStateSource;
use collab_entity::{CollabObject, CollabType}; use collab_entity::{CollabObject, CollabType};
use collab_plugins::cloud_storage::RemoteCollabSnapshot; use collab_plugins::cloud_storage::RemoteCollabSnapshot;
use serde_json::Value; use serde_json::Value;
@ -60,7 +60,7 @@ impl FetchObjectUpdateAction {
impl Action for FetchObjectUpdateAction { impl Action for FetchObjectUpdateAction {
type Future = Pin<Box<dyn Future<Output = Result<Self::Item, Self::Error>> + Send>>; type Future = Pin<Box<dyn Future<Output = Result<Self::Item, Self::Error>> + Send>>;
type Item = CollabDocState; type Item = Vec<u8>;
type Error = anyhow::Error; type Error = anyhow::Error;
fn run(&mut self) -> Self::Future { fn run(&mut self) -> Self::Future {
@ -284,7 +284,7 @@ pub async fn batch_get_updates_from_server(
match parser_updates_form_json(record.clone(), &postgrest.secret()) { match parser_updates_form_json(record.clone(), &postgrest.secret()) {
Ok(items) => { Ok(items) => {
if items.is_empty() { if items.is_empty() {
updates_by_oid.insert(oid.to_string(), vec![]); updates_by_oid.insert(oid.to_string(), DocStateSource::FromDocState(vec![]));
} else { } else {
let updates = items let updates = items
.iter() .iter()
@ -293,7 +293,7 @@ pub async fn batch_get_updates_from_server(
let doc_state = merge_updates_v1(&updates) let doc_state = merge_updates_v1(&updates)
.map_err(|err| anyhow::anyhow!("merge updates failed: {:?}", err))?; .map_err(|err| anyhow::anyhow!("merge updates failed: {:?}", err))?;
updates_by_oid.insert(oid.to_string(), doc_state); updates_by_oid.insert(oid.to_string(), DocStateSource::FromDocState(doc_state));
} }
}, },
Err(e) => { Err(e) => {

View File

@ -6,7 +6,7 @@ use std::sync::{Arc, Weak};
use std::time::Duration; use std::time::Duration;
use anyhow::Error; use anyhow::Error;
use collab::core::collab::{CollabDocState, MutexCollab}; use collab::core::collab::MutexCollab;
use collab::core::origin::CollabOrigin; use collab::core::origin::CollabOrigin;
use collab_entity::{CollabObject, CollabType}; use collab_entity::{CollabObject, CollabType};
use parking_lot::RwLock; use parking_lot::RwLock;
@ -249,7 +249,7 @@ where
}) })
} }
fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult<CollabDocState, FlowyError> { fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult<Vec<u8>, FlowyError> {
let try_get_postgrest = self.server.try_get_weak_postgrest(); let try_get_postgrest = self.server.try_get_weak_postgrest();
let awareness_id = uid.to_string(); let awareness_id = uid.to_string();
let (tx, rx) = channel(); let (tx, rx) = channel();

View File

@ -1,3 +1,4 @@
use collab::core::collab::DocStateSource;
use collab_entity::{CollabObject, CollabType}; use collab_entity::{CollabObject, CollabType};
use uuid::Uuid; use uuid::Uuid;
@ -50,7 +51,12 @@ async fn supabase_create_database_test() {
.unwrap(); .unwrap();
assert_eq!(updates_by_oid.len(), 3); assert_eq!(updates_by_oid.len(), 3);
for (_, update) in updates_by_oid { for (_, source) in updates_by_oid {
assert_eq!(update.len(), 2); match source {
DocStateSource::FromDisk => panic!("should not be from disk"),
DocStateSource::FromDocState(doc_state) => {
assert_eq!(doc_state.len(), 2);
},
}
} }
} }

View File

@ -2,7 +2,7 @@ use flowy_storage::ObjectStorageService;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use collab::core::collab::MutexCollab; use collab::core::collab::{DocStateSource, MutexCollab};
use collab::core::origin::CollabOrigin; use collab::core::origin::CollabOrigin;
use collab_plugins::cloud_storage::RemoteCollabStorage; use collab_plugins::cloud_storage::RemoteCollabStorage;
use uuid::Uuid; use uuid::Uuid;
@ -122,8 +122,14 @@ pub async fn print_encryption_folder_snapshot(
.pop() .pop()
.unwrap(); .unwrap();
let collab = Arc::new( let collab = Arc::new(
MutexCollab::new_with_doc_state(CollabOrigin::Empty, folder_id, snapshot.blob, vec![], false) MutexCollab::new_with_doc_state(
.unwrap(), CollabOrigin::Empty,
folder_id,
DocStateSource::FromDocState(snapshot.blob),
vec![],
false,
)
.unwrap(),
); );
let folder_data = Folder::open(uid, collab, None) let folder_data = Folder::open(uid, collab, None)
.unwrap() .unwrap()

View File

@ -1,4 +1,3 @@
use collab::core::collab::CollabDocState;
use collab_entity::{CollabObject, CollabType}; use collab_entity::{CollabObject, CollabType};
use flowy_error::{internal_error, ErrorCode, FlowyError}; use flowy_error::{internal_error, ErrorCode, FlowyError};
use lib_infra::box_any::BoxAny; use lib_infra::box_any::BoxAny;
@ -213,7 +212,7 @@ pub trait UserCloudService: Send + Sync + 'static {
FutureResult::new(async { Ok(vec![]) }) FutureResult::new(async { Ok(vec![]) })
} }
fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult<CollabDocState, FlowyError>; fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult<Vec<u8>, FlowyError>;
fn receive_realtime_event(&self, _json: Value) {} fn receive_realtime_event(&self, _json: Value) {}

View File

@ -3,7 +3,7 @@ use std::ops::{Deref, DerefMut};
use std::sync::Arc; use std::sync::Arc;
use anyhow::anyhow; use anyhow::anyhow;
use collab::core::collab::MutexCollab; use collab::core::collab::{DocStateSource, MutexCollab};
use collab::core::origin::{CollabClient, CollabOrigin}; use collab::core::origin::{CollabClient, CollabOrigin};
use collab::preclude::Collab; use collab::preclude::Collab;
use collab_database::database::{ use collab_database::database::{
@ -305,9 +305,14 @@ where
} }
let origin = CollabOrigin::Client(CollabClient::new(new_uid, "phantom")); let origin = CollabOrigin::Client(CollabClient::new(new_uid, "phantom"));
let new_folder_collab = let new_folder_collab = Collab::new_with_doc_state(
Collab::new_with_doc_state(origin, new_workspace_id, vec![], vec![], false) origin,
.map_err(|err| PersistenceError::Internal(err.into()))?; new_workspace_id,
DocStateSource::FromDisk,
vec![],
false,
)
.map_err(|err| PersistenceError::Internal(err.into()))?;
let mutex_collab = Arc::new(MutexCollab::from_collab(new_folder_collab)); let mutex_collab = Arc::new(MutexCollab::from_collab(new_folder_collab));
let new_user_id = UserId::from(new_uid); let new_user_id = UserId::from(new_uid);
info!("migrated folder: {:?}", folder_data); info!("migrated folder: {:?}", folder_data);

View File

@ -5,7 +5,7 @@ use crate::services::entities::UserPaths;
use crate::services::sqlite_sql::user_sql::select_user_profile; use crate::services::sqlite_sql::user_sql::select_user_profile;
use crate::user_manager::run_collab_data_migration; use crate::user_manager::run_collab_data_migration;
use anyhow::anyhow; use anyhow::anyhow;
use collab::core::collab::{CollabDocState, MutexCollab}; use collab::core::collab::{DocStateSource, MutexCollab};
use collab::core::origin::CollabOrigin; use collab::core::origin::CollabOrigin;
use collab::core::transaction::DocTransactionExtension; use collab::core::transaction::DocTransactionExtension;
use collab::preclude::updates::decoder::Decode; use collab::preclude::updates::decoder::Decode;
@ -447,7 +447,7 @@ where
} }
fn import_collab_object_with_doc_state<'a, W>( fn import_collab_object_with_doc_state<'a, W>(
doc_state: CollabDocState, doc_state: Vec<u8>,
new_uid: i64, new_uid: i64,
new_object_id: &str, new_object_id: &str,
w_txn: &'a W, w_txn: &'a W,
@ -456,8 +456,13 @@ where
W: CollabKVAction<'a>, W: CollabKVAction<'a>,
PersistenceError: From<W::Error>, PersistenceError: From<W::Error>,
{ {
let collab = let collab = Collab::new_with_doc_state(
Collab::new_with_doc_state(CollabOrigin::Empty, new_object_id, doc_state, vec![], false)?; CollabOrigin::Empty,
new_object_id,
DocStateSource::FromDocState(doc_state),
vec![],
false,
)?;
write_collab_object(&collab, new_uid, new_object_id, w_txn); write_collab_object(&collab, new_uid, new_object_id, w_txn);
Ok(()) Ok(())
} }

View File

@ -1,7 +1,7 @@
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use anyhow::Context; use anyhow::Context;
use collab::core::collab::{CollabDocState, MutexCollab}; use collab::core::collab::{DocStateSource, MutexCollab};
use collab_entity::reminder::Reminder; use collab_entity::reminder::Reminder;
use collab_entity::CollabType; use collab_entity::CollabType;
use collab_integrate::collab_builder::CollabBuilderConfig; use collab_integrate::collab_builder::CollabBuilderConfig;
@ -164,7 +164,7 @@ impl UserManager {
&self, &self,
session: &Session, session: &Session,
collab_db: Weak<CollabKVDB>, collab_db: Weak<CollabKVDB>,
raw_data: CollabDocState, doc_state: Vec<u8>,
) -> Result<Arc<MutexCollab>, FlowyError> { ) -> Result<Arc<MutexCollab>, FlowyError> {
let collab_builder = self.collab_builder.upgrade().ok_or(FlowyError::new( let collab_builder = self.collab_builder.upgrade().ok_or(FlowyError::new(
ErrorCode::Internal, ErrorCode::Internal,
@ -176,7 +176,7 @@ impl UserManager {
session.user_id, session.user_id,
&user_awareness_id.to_string(), &user_awareness_id.to_string(),
CollabType::UserAwareness, CollabType::UserAwareness,
raw_data, DocStateSource::FromDocState(doc_state),
collab_db, collab_db,
CollabBuilderConfig::default().sync_enable(true), CollabBuilderConfig::default().sync_enable(true),
) )