Browse Source

chore: build collab with appflowy collab builder (#2537)

Nathan.fooo 2 years ago
parent
commit
6dcf69f151

+ 7 - 8
frontend/appflowy_tauri/src-tauri/Cargo.toml

@@ -33,19 +33,18 @@ default = ["custom-protocol"]
 custom-protocol = ["tauri/custom-protocol"]
 
 [patch.crates-io]
-collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "f66084" }
-collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "f66084" }
-collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "f66084" }
-collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "f66084" }
-collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "f66084" }
-collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "f66084" }
+collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
+collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
+collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
+collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
+collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
+appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
 
 #collab = { path = "../../AppFlowy-Collab/collab" }
 #collab-folder = { path = "../../AppFlowy-Collab/collab-folder" }
-#collab-persistence = { path = "../../AppFlowy-Collab/collab-persistence" }
 #collab-document = { path = "../../AppFlowy-Collab/collab-document" }
 #collab-database= { path = "../../AppFlowy-Collab/collab-database" }
-
+#appflowy-integrate = { path = "../../AppFlowy-Collab/appflowy-integrate" }
 
 
 

+ 617 - 15
frontend/rust-lib/Cargo.lock

@@ -82,6 +82,21 @@ version = "1.0.70"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
 
+[[package]]
+name = "appflowy-integrate"
+version = "0.1.0"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
+dependencies = [
+ "collab",
+ "collab-database",
+ "collab-document",
+ "collab-folder",
+ "collab-persistence",
+ "collab-plugins",
+ "serde",
+ "serde_json",
+]
+
 [[package]]
 name = "arrayvec"
 version = "0.5.2"
@@ -159,6 +174,324 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
+[[package]]
+name = "aws-config"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc00553f5f3c06ffd4510a9d576f92143618706c45ea6ff81e84ad9be9588abd"
+dependencies = [
+ "aws-credential-types",
+ "aws-http",
+ "aws-sdk-sso",
+ "aws-sdk-sts",
+ "aws-smithy-async",
+ "aws-smithy-client",
+ "aws-smithy-http",
+ "aws-smithy-http-tower",
+ "aws-smithy-json",
+ "aws-smithy-types",
+ "aws-types",
+ "bytes",
+ "fastrand",
+ "hex",
+ "http",
+ "hyper",
+ "ring",
+ "time 0.3.21",
+ "tokio",
+ "tower",
+ "tracing",
+ "zeroize",
+]
+
+[[package]]
+name = "aws-credential-types"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cb57ac6088805821f78d282c0ba8aec809f11cbee10dda19a97b03ab040ccc2"
+dependencies = [
+ "aws-smithy-async",
+ "aws-smithy-types",
+ "fastrand",
+ "tokio",
+ "tracing",
+ "zeroize",
+]
+
+[[package]]
+name = "aws-endpoint"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c5f6f84a4f46f95a9bb71d9300b73cd67eb868bc43ae84f66ad34752299f4ac"
+dependencies = [
+ "aws-smithy-http",
+ "aws-smithy-types",
+ "aws-types",
+ "http",
+ "regex",
+ "tracing",
+]
+
+[[package]]
+name = "aws-http"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a754683c322f7dc5167484266489fdebdcd04d26e53c162cad1f3f949f2c5671"
+dependencies = [
+ "aws-credential-types",
+ "aws-smithy-http",
+ "aws-smithy-types",
+ "aws-types",
+ "bytes",
+ "http",
+ "http-body",
+ "lazy_static",
+ "percent-encoding",
+ "pin-project-lite",
+ "tracing",
+]
+
+[[package]]
+name = "aws-sdk-dynamodb"
+version = "0.27.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67fb64867fe098cffee7e34352b01bbfa2beb3aa1b2ff0e0a7bf9ff293557852"
+dependencies = [
+ "aws-credential-types",
+ "aws-endpoint",
+ "aws-http",
+ "aws-sig-auth",
+ "aws-smithy-async",
+ "aws-smithy-client",
+ "aws-smithy-http",
+ "aws-smithy-http-tower",
+ "aws-smithy-json",
+ "aws-smithy-types",
+ "aws-types",
+ "bytes",
+ "fastrand",
+ "http",
+ "regex",
+ "tokio-stream",
+ "tower",
+ "tracing",
+]
+
+[[package]]
+name = "aws-sdk-sso"
+version = "0.27.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "babfd626348836a31785775e3c08a4c345a5ab4c6e06dfd9167f2bee0e6295d6"
+dependencies = [
+ "aws-credential-types",
+ "aws-endpoint",
+ "aws-http",
+ "aws-sig-auth",
+ "aws-smithy-async",
+ "aws-smithy-client",
+ "aws-smithy-http",
+ "aws-smithy-http-tower",
+ "aws-smithy-json",
+ "aws-smithy-types",
+ "aws-types",
+ "bytes",
+ "http",
+ "regex",
+ "tokio-stream",
+ "tower",
+ "tracing",
+]
+
+[[package]]
+name = "aws-sdk-sts"
+version = "0.27.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d0fbe3c2c342bc8dfea4bb43937405a8ec06f99140a0dcb9c7b59e54dfa93a1"
+dependencies = [
+ "aws-credential-types",
+ "aws-endpoint",
+ "aws-http",
+ "aws-sig-auth",
+ "aws-smithy-async",
+ "aws-smithy-client",
+ "aws-smithy-http",
+ "aws-smithy-http-tower",
+ "aws-smithy-json",
+ "aws-smithy-query",
+ "aws-smithy-types",
+ "aws-smithy-xml",
+ "aws-types",
+ "bytes",
+ "http",
+ "regex",
+ "tower",
+ "tracing",
+]
+
+[[package]]
+name = "aws-sig-auth"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84dc92a63ede3c2cbe43529cb87ffa58763520c96c6a46ca1ced80417afba845"
+dependencies = [
+ "aws-credential-types",
+ "aws-sigv4",
+ "aws-smithy-http",
+ "aws-types",
+ "http",
+ "tracing",
+]
+
+[[package]]
+name = "aws-sigv4"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "392fefab9d6fcbd76d518eb3b1c040b84728ab50f58df0c3c53ada4bea9d327e"
+dependencies = [
+ "aws-smithy-http",
+ "form_urlencoded",
+ "hex",
+ "hmac",
+ "http",
+ "once_cell",
+ "percent-encoding",
+ "regex",
+ "sha2",
+ "time 0.3.21",
+ "tracing",
+]
+
+[[package]]
+name = "aws-smithy-async"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae23b9fe7a07d0919000116c4c5c0578303fbce6fc8d32efca1f7759d4c20faf"
+dependencies = [
+ "futures-util",
+ "pin-project-lite",
+ "tokio",
+ "tokio-stream",
+]
+
+[[package]]
+name = "aws-smithy-client"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5230d25d244a51339273b8870f0f77874cd4449fb4f8f629b21188ae10cfc0ba"
+dependencies = [
+ "aws-smithy-async",
+ "aws-smithy-http",
+ "aws-smithy-http-tower",
+ "aws-smithy-types",
+ "bytes",
+ "fastrand",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-rustls",
+ "lazy_static",
+ "pin-project-lite",
+ "rustls",
+ "tokio",
+ "tower",
+ "tracing",
+]
+
+[[package]]
+name = "aws-smithy-http"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b60e2133beb9fe6ffe0b70deca57aaeff0a35ad24a9c6fab2fd3b4f45b99fdb5"
+dependencies = [
+ "aws-smithy-types",
+ "bytes",
+ "bytes-utils",
+ "futures-core",
+ "http",
+ "http-body",
+ "hyper",
+ "once_cell",
+ "percent-encoding",
+ "pin-project-lite",
+ "pin-utils",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "aws-smithy-http-tower"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a4d94f556c86a0dd916a5d7c39747157ea8cb909ca469703e20fee33e448b67"
+dependencies = [
+ "aws-smithy-http",
+ "aws-smithy-types",
+ "bytes",
+ "http",
+ "http-body",
+ "pin-project-lite",
+ "tower",
+ "tracing",
+]
+
+[[package]]
+name = "aws-smithy-json"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ce3d6e6ebb00b2cce379f079ad5ec508f9bcc3a9510d9b9c1840ed1d6f8af39"
+dependencies = [
+ "aws-smithy-types",
+]
+
+[[package]]
+name = "aws-smithy-query"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d58edfca32ef9bfbc1ca394599e17ea329cb52d6a07359827be74235b64b3298"
+dependencies = [
+ "aws-smithy-types",
+ "urlencoding",
+]
+
+[[package]]
+name = "aws-smithy-types"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58db46fc1f4f26be01ebdb821751b4e2482cd43aa2b64a0348fb89762defaffa"
+dependencies = [
+ "base64-simd",
+ "itoa",
+ "num-integer",
+ "ryu",
+ "time 0.3.21",
+]
+
+[[package]]
+name = "aws-smithy-xml"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb557fe4995bd9ec87fb244bbb254666a971dc902a783e9da8b7711610e9664c"
+dependencies = [
+ "xmlparser",
+]
+
+[[package]]
+name = "aws-types"
+version = "0.55.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de0869598bfe46ec44ffe17e063ed33336e59df90356ca8ff0e8da6f7c1d994b"
+dependencies = [
+ "aws-credential-types",
+ "aws-smithy-async",
+ "aws-smithy-client",
+ "aws-smithy-http",
+ "aws-smithy-types",
+ "http",
+ "rustc_version",
+ "tracing",
+]
+
 [[package]]
 name = "axum"
 version = "0.6.15"
@@ -231,6 +564,16 @@ version = "0.21.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
 
+[[package]]
+name = "base64-simd"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195"
+dependencies = [
+ "outref",
+ "vsimd",
+]
+
 [[package]]
 name = "basic-toml"
 version = "0.1.2"
@@ -406,6 +749,16 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "bytes-utils"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e47d3a8076e283f3acd27400535992edb3ba4b5bb72f8891ad8fbe7932a7d4b9"
+dependencies = [
+ "bytes",
+ "either",
+]
+
 [[package]]
 name = "bzip2-sys"
 version = "0.1.11+1.0.8"
@@ -457,7 +810,8 @@ dependencies = [
  "js-sys",
  "num-integer",
  "num-traits",
- "time",
+ "serde",
+ "time 0.1.45",
  "wasm-bindgen",
  "winapi",
 ]
@@ -566,7 +920,7 @@ dependencies = [
 [[package]]
 name = "collab"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=f66084#f66084454c143418cf69155dc8cce77df2d57d0c"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
 dependencies = [
  "anyhow",
  "bytes",
@@ -583,7 +937,7 @@ dependencies = [
 [[package]]
 name = "collab-client-ws"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=f66084#f66084454c143418cf69155dc8cce77df2d57d0c"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
 dependencies = [
  "bytes",
  "collab-sync",
@@ -601,9 +955,10 @@ dependencies = [
 [[package]]
 name = "collab-database"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=f66084#f66084454c143418cf69155dc8cce77df2d57d0c"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
 dependencies = [
  "anyhow",
+ "async-trait",
  "chrono",
  "collab",
  "collab-derive",
@@ -624,7 +979,7 @@ dependencies = [
 [[package]]
 name = "collab-derive"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=f66084#f66084454c143418cf69155dc8cce77df2d57d0c"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -636,7 +991,7 @@ dependencies = [
 [[package]]
 name = "collab-document"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=f66084#f66084454c143418cf69155dc8cce77df2d57d0c"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
 dependencies = [
  "anyhow",
  "collab",
@@ -653,7 +1008,7 @@ dependencies = [
 [[package]]
 name = "collab-folder"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=f66084#f66084454c143418cf69155dc8cce77df2d57d0c"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
 dependencies = [
  "anyhow",
  "collab",
@@ -671,7 +1026,7 @@ dependencies = [
 [[package]]
 name = "collab-persistence"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=f66084#f66084454c143418cf69155dc8cce77df2d57d0c"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
 dependencies = [
  "bincode",
  "chrono",
@@ -691,12 +1046,24 @@ dependencies = [
 [[package]]
 name = "collab-plugins"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=f66084#f66084454c143418cf69155dc8cce77df2d57d0c"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
 dependencies = [
+ "anyhow",
+ "async-trait",
+ "aws-config",
+ "aws-credential-types",
+ "aws-sdk-dynamodb",
  "collab",
  "collab-client-ws",
  "collab-persistence",
  "collab-sync",
+ "futures-util",
+ "parking_lot 0.12.1",
+ "rand 0.8.5",
+ "rusoto_credential",
+ "thiserror",
+ "tokio",
+ "tokio-retry",
  "tracing",
  "y-sync",
  "yrs",
@@ -705,7 +1072,7 @@ dependencies = [
 [[package]]
 name = "collab-sync"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=f66084#f66084454c143418cf69155dc8cce77df2d57d0c"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=d074c9#d074c94471f222e2701fe451f13c51aab39d2bf8"
 dependencies = [
  "bytes",
  "collab",
@@ -1121,6 +1488,28 @@ checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
 dependencies = [
  "block-buffer 0.10.4",
  "crypto-common",
+ "subtle",
+]
+
+[[package]]
+name = "dirs-next"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
+dependencies = [
+ "cfg-if",
+ "dirs-sys-next",
+]
+
+[[package]]
+name = "dirs-sys-next"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
+dependencies = [
+ "libc",
+ "redox_users",
+ "winapi",
 ]
 
 [[package]]
@@ -1361,8 +1750,8 @@ dependencies = [
 name = "flowy-core"
 version = "0.1.0"
 dependencies = [
+ "appflowy-integrate",
  "bytes",
- "collab-persistence",
  "console-subscriber",
  "database-model",
  "flowy-client-ws",
@@ -1396,13 +1785,14 @@ name = "flowy-database2"
 version = "0.1.0"
 dependencies = [
  "anyhow",
+ "appflowy-integrate",
  "async-stream",
+ "async-trait",
  "bytes",
  "chrono",
  "chrono-tz 0.8.2",
  "collab",
  "collab-database",
- "collab-plugins",
  "dashmap",
  "database-model",
  "fancy-regex 0.10.0",
@@ -1501,10 +1891,10 @@ dependencies = [
 name = "flowy-document2"
 version = "0.1.0"
 dependencies = [
+ "appflowy-integrate",
  "bytes",
  "collab",
  "collab-document",
- "collab-plugins",
  "flowy-codegen",
  "flowy-derive",
  "flowy-error",
@@ -1552,11 +1942,11 @@ dependencies = [
 name = "flowy-folder2"
 version = "0.1.0"
 dependencies = [
+ "appflowy-integrate",
  "bytes",
  "chrono",
  "collab",
  "collab-folder",
- "collab-plugins",
  "flowy-codegen",
  "flowy-derive",
  "flowy-document",
@@ -1773,8 +2163,8 @@ dependencies = [
 name = "flowy-user"
 version = "0.1.0"
 dependencies = [
+ "appflowy-integrate",
  "bytes",
- "collab-persistence",
  "diesel",
  "diesel_derives",
  "flowy-codegen",
@@ -2117,6 +2507,21 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
 
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "hmac"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
+dependencies = [
+ "digest 0.10.6",
+]
+
 [[package]]
 name = "http"
 version = "0.2.9"
@@ -2200,6 +2605,21 @@ dependencies = [
  "want",
 ]
 
+[[package]]
+name = "hyper-rustls"
+version = "0.23.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c"
+dependencies = [
+ "http",
+ "hyper",
+ "log",
+ "rustls",
+ "rustls-native-certs",
+ "tokio",
+ "tokio-rustls",
+]
+
 [[package]]
 name = "hyper-timeout"
 version = "0.4.1"
@@ -2893,6 +3313,12 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "outref"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a"
+
 [[package]]
 name = "overload"
 version = "0.1.1"
@@ -3567,6 +3993,17 @@ dependencies = [
  "bitflags",
 ]
 
+[[package]]
+name = "redox_users"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
+dependencies = [
+ "getrandom 0.2.9",
+ "redox_syscall 0.2.16",
+ "thiserror",
+]
+
 [[package]]
 name = "regex"
 version = "1.7.3"
@@ -3649,6 +4086,21 @@ dependencies = [
  "serde_json",
 ]
 
+[[package]]
+name = "ring"
+version = "0.16.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+dependencies = [
+ "cc",
+ "libc",
+ "once_cell",
+ "spin",
+ "untrusted",
+ "web-sys",
+ "winapi",
+]
+
 [[package]]
 name = "rkyv"
 version = "0.7.41"
@@ -3684,6 +4136,24 @@ dependencies = [
  "librocksdb-sys",
 ]
 
+[[package]]
+name = "rusoto_credential"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee0a6c13db5aad6047b6a44ef023dbbc21a056b6dab5be3b79ce4283d5c02d05"
+dependencies = [
+ "async-trait",
+ "chrono",
+ "dirs-next",
+ "futures",
+ "hyper",
+ "serde",
+ "serde_json",
+ "shlex",
+ "tokio",
+ "zeroize",
+]
+
 [[package]]
 name = "rust_decimal"
 version = "1.29.1"
@@ -3747,6 +4217,39 @@ dependencies = [
  "windows-sys 0.48.0",
 ]
 
+[[package]]
+name = "rustls"
+version = "0.20.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f"
+dependencies = [
+ "log",
+ "ring",
+ "sct",
+ "webpki",
+]
+
+[[package]]
+name = "rustls-native-certs"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50"
+dependencies = [
+ "openssl-probe",
+ "rustls-pemfile",
+ "schannel",
+ "security-framework",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b"
+dependencies = [
+ "base64 0.21.0",
+]
+
 [[package]]
 name = "rustversion"
 version = "1.0.12"
@@ -3808,6 +4311,16 @@ version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1"
 
+[[package]]
+name = "sct"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
 [[package]]
 name = "seahash"
 version = "4.1.0"
@@ -4076,6 +4589,12 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "spin"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+
 [[package]]
 name = "static_assertions"
 version = "1.1.0"
@@ -4100,6 +4619,12 @@ dependencies = [
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "subtle"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
+
 [[package]]
 name = "syn"
 version = "1.0.109"
@@ -4243,6 +4768,32 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "time"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc"
+dependencies = [
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
+
+[[package]]
+name = "time-macros"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b"
+dependencies = [
+ "time-core",
+]
+
 [[package]]
 name = "tinytemplate"
 version = "1.2.1"
@@ -4330,6 +4881,17 @@ dependencies = [
  "tokio",
 ]
 
+[[package]]
+name = "tokio-rustls"
+version = "0.23.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
+dependencies = [
+ "rustls",
+ "tokio",
+ "webpki",
+]
+
 [[package]]
 name = "tokio-stream"
 version = "0.1.14"
@@ -4750,6 +5312,12 @@ version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
 
+[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
 [[package]]
 name = "url"
 version = "2.3.1"
@@ -4761,6 +5329,12 @@ dependencies = [
  "percent-encoding",
 ]
 
+[[package]]
+name = "urlencoding"
+version = "2.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9"
+
 [[package]]
 name = "user-model"
 version = "0.1.0"
@@ -4814,6 +5388,12 @@ version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 
+[[package]]
+name = "vsimd"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64"
+
 [[package]]
 name = "walkdir"
 version = "2.3.3"
@@ -4928,6 +5508,16 @@ dependencies = [
  "wasm-bindgen",
 ]
 
+[[package]]
+name = "webpki"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
 [[package]]
 name = "which"
 version = "4.4.0"
@@ -5146,6 +5736,12 @@ dependencies = [
  "serde_repr",
 ]
 
+[[package]]
+name = "xmlparser"
+version = "0.13.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d25c75bf9ea12c4040a97f829154768bbbce366287e2dc044af160cd79a13fd"
+
 [[package]]
 name = "y-sync"
 version = "0.3.1"
@@ -5180,6 +5776,12 @@ dependencies = [
  "thiserror",
 ]
 
+[[package]]
+name = "zeroize"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"
+
 [[package]]
 name = "zstd-sys"
 version = "2.0.8+zstd.1.5.5"

+ 7 - 8
frontend/rust-lib/Cargo.toml

@@ -40,16 +40,15 @@ opt-level = 3
 incremental = false
 
 [patch.crates-io]
-collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "f66084"  }
-collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "f66084"  }
-collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "f66084" }
-collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "f66084" }
-collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "f66084" }
-collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "f66084" }
-collab-sync= { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "f66084" }
+collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9"  }
+collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9"  }
+collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
+collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
+appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "d074c9" }
 
 #collab = { path = "../AppFlowy-Collab/collab" }
 #collab-folder = { path = "../AppFlowy-Collab/collab-folder" }
 #collab-database= { path = "../AppFlowy-Collab/collab-database" }
-#collab-persistence = { path = "../AppFlowy-Collab/collab-persistence" }
 #collab-document = { path = "../AppFlowy-Collab/collab-document" }
+#appflowy-integrate = { path = "../AppFlowy-Collab/appflowy-integrate" }
+

+ 1 - 1
frontend/rust-lib/flowy-core/Cargo.toml

@@ -22,7 +22,7 @@ flowy-document2 = { path = "../flowy-document2" }
 flowy-revision = { path = "../flowy-revision" }
 flowy-error = { path = "../flowy-error", features = ["adaptor_ws"] }
 flowy-task = { path = "../flowy-task" }
-collab-persistence = { version = "0.1.0" }
+appflowy-integrate = { version = "0.1.0" }
 
 tracing = { version = "0.1", features = ["log"] }
 futures-core = { version = "0.3", default-features = false }

+ 6 - 4
frontend/rust-lib/flowy-core/src/deps_resolve/database_deps.rs

@@ -1,6 +1,7 @@
 use std::sync::Arc;
 
-use collab_persistence::kv::rocks_kv::RocksCollabDB;
+use appflowy_integrate::collab_builder::AppFlowyCollabBuilder;
+use appflowy_integrate::RocksCollabDB;
 use tokio::sync::RwLock;
 
 use flowy_client_ws::FlowyWebSocketConnect;
@@ -16,9 +17,10 @@ impl Database2DepsResolver {
     _ws_conn: Arc<FlowyWebSocketConnect>,
     user_session: Arc<UserSession>,
     task_scheduler: Arc<RwLock<TaskDispatcher>>,
+    collab_builder: Arc<AppFlowyCollabBuilder>,
   ) -> Arc<DatabaseManager2> {
     let user = Arc::new(DatabaseUserImpl(user_session));
-    Arc::new(DatabaseManager2::new(user, task_scheduler))
+    Arc::new(DatabaseManager2::new(user, task_scheduler, collab_builder))
   }
 }
 
@@ -38,7 +40,7 @@ impl DatabaseUser2 for DatabaseUserImpl {
       .map_err(|e| FlowyError::internal().context(e))
   }
 
-  fn kv_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError> {
-    self.0.get_kv_db()
+  fn collab_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError> {
+    self.0.get_collab_db()
   }
 }

+ 8 - 7
frontend/rust-lib/flowy-core/src/deps_resolve/document2_deps.rs

@@ -1,9 +1,10 @@
 use std::sync::Arc;
 
-use collab_persistence::kv::rocks_kv::RocksCollabDB;
+use appflowy_integrate::collab_builder::AppFlowyCollabBuilder;
+use appflowy_integrate::RocksCollabDB;
 
 use flowy_database2::DatabaseManager2;
-use flowy_document2::manager::{DocumentManager as DocumentManager2, DocumentUser};
+use flowy_document2::manager::{DocumentManager, DocumentUser};
 use flowy_error::FlowyError;
 use flowy_user::services::UserSession;
 
@@ -12,10 +13,10 @@ impl Document2DepsResolver {
   pub fn resolve(
     user_session: Arc<UserSession>,
     _database_manager: &Arc<DatabaseManager2>,
-  ) -> Arc<DocumentManager2> {
+    collab_builder: Arc<AppFlowyCollabBuilder>,
+  ) -> Arc<DocumentManager> {
     let user: Arc<dyn DocumentUser> = Arc::new(DocumentUserImpl(user_session));
-
-    Arc::new(DocumentManager2::new(user.clone()))
+    Arc::new(DocumentManager::new(user.clone(), collab_builder))
   }
 }
 
@@ -35,7 +36,7 @@ impl DocumentUser for DocumentUserImpl {
       .map_err(|e| FlowyError::internal().context(e))
   }
 
-  fn kv_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError> {
-    self.0.get_kv_db()
+  fn collab_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError> {
+    self.0.get_collab_db()
   }
 }

+ 7 - 4
frontend/rust-lib/flowy-core/src/deps_resolve/folder2_deps.rs

@@ -1,8 +1,10 @@
 use std::collections::HashMap;
 use std::sync::Arc;
 
+use appflowy_integrate::collab_builder::AppFlowyCollabBuilder;
+use appflowy_integrate::RocksCollabDB;
 use bytes::Bytes;
-use collab_persistence::kv::rocks_kv::RocksCollabDB;
+
 use flowy_database2::entities::DatabaseLayoutPB;
 use flowy_database2::template::{make_default_board, make_default_calendar, make_default_grid};
 use flowy_database2::DatabaseManager2;
@@ -23,13 +25,14 @@ impl Folder2DepsResolver {
     user_session: Arc<UserSession>,
     document_manager: &Arc<DocumentManager>,
     database_manager: &Arc<DatabaseManager2>,
+    collab_builder: Arc<AppFlowyCollabBuilder>,
   ) -> Arc<Folder2Manager> {
     let user: Arc<dyn FolderUser> = Arc::new(FolderUserImpl(user_session.clone()));
 
     let view_data_processor =
       make_view_data_processor(document_manager.clone(), database_manager.clone());
     Arc::new(
-      Folder2Manager::new(user.clone(), view_data_processor)
+      Folder2Manager::new(user.clone(), collab_builder, view_data_processor)
         .await
         .unwrap(),
     )
@@ -68,8 +71,8 @@ impl FolderUser for FolderUserImpl {
       .map_err(|e| FlowyError::internal().context(e))
   }
 
-  fn kv_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError> {
-    self.0.get_kv_db()
+  fn collab_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError> {
+    self.0.get_collab_db()
   }
 }
 

+ 39 - 6
frontend/rust-lib/flowy-core/src/lib.rs

@@ -1,3 +1,4 @@
+use std::str::FromStr;
 use std::time::Duration;
 use std::{
   fmt,
@@ -7,6 +8,8 @@ use std::{
   },
 };
 
+use appflowy_integrate::collab_builder::AppFlowyCollabBuilder;
+use appflowy_integrate::config::{AWSDynamoDBConfig, AppFlowyCollabConfig};
 use tokio::sync::{broadcast, RwLock};
 
 use flowy_client_ws::{listen_on_websocket, FlowyWebSocketConnect, NetworkType};
@@ -19,6 +22,7 @@ use flowy_folder2::manager::Folder2Manager;
 pub use flowy_net::get_client_server_configuration;
 use flowy_net::local_server::LocalServer;
 use flowy_net::ClientServerConfiguration;
+use flowy_sqlite::kv::KV;
 use flowy_task::{TaskDispatcher, TaskRunner};
 use flowy_user::event_map::UserStatusCallback;
 use flowy_user::services::{UserSession, UserSessionConfig};
@@ -148,6 +152,10 @@ impl AppFlowyCore {
 
     init_log(&config);
     init_kv(&config.storage_path);
+    let collab_config = get_collab_config();
+    inject_aws_env(collab_config.aws_config());
+    let collab_builder = Arc::new(AppFlowyCollabBuilder::new(collab_config));
+
     tracing::debug!("🔥 {:?}", config);
     let runtime = tokio_default_runtime().unwrap();
     let task_scheduler = TaskDispatcher::new(Duration::from_secs(2));
@@ -175,15 +183,23 @@ impl AppFlowyCore {
         ws_conn.clone(),
         user_session.clone(),
         task_dispatcher.clone(),
+        collab_builder.clone(),
       )
       .await;
 
-      let folder_manager =
-        Folder2DepsResolver::resolve(user_session.clone(), &document_manager, &database_manager2)
-          .await;
+      let folder_manager = Folder2DepsResolver::resolve(
+        user_session.clone(),
+        &document_manager,
+        &database_manager2,
+        collab_builder.clone(),
+      )
+      .await;
 
-      let document_manager2 =
-        Document2DepsResolver::resolve(user_session.clone(), &database_manager2);
+      let document_manager2 = Document2DepsResolver::resolve(
+        user_session.clone(),
+        &database_manager2,
+        collab_builder.clone(),
+      );
 
       if let Some(local_server) = local_server.as_ref() {
         local_server.run();
@@ -286,12 +302,29 @@ async fn _listen_network_status(mut subscribe: broadcast::Receiver<NetworkType>)
 }
 
 fn init_kv(root: &str) {
-  match flowy_sqlite::kv::KV::init(root) {
+  match KV::init(root) {
     Ok(_) => {},
     Err(e) => tracing::error!("Init kv store failed: {}", e),
   }
 }
 
+fn get_collab_config() -> AppFlowyCollabConfig {
+  match KV::get_str("collab_config") {
+    None => AppFlowyCollabConfig::default(),
+    Some(s) => AppFlowyCollabConfig::from_str(&s).unwrap_or_default(),
+  }
+}
+
+fn inject_aws_env(aws_config: Option<&AWSDynamoDBConfig>) {
+  if let Some(aws_config) = aws_config {
+    std::env::set_var("AWS_ACCESS_KEY_ID", aws_config.access_key_id.clone());
+    std::env::set_var(
+      "AWS_SECRET_ACCESS_KEY",
+      aws_config.secret_access_key.clone(),
+    );
+  }
+}
+
 fn init_log(config: &AppFlowyCoreConfig) {
   if !INIT_LOG.load(Ordering::SeqCst) {
     INIT_LOG.store(true, Ordering::SeqCst);

+ 2 - 2
frontend/rust-lib/flowy-core/src/module.rs

@@ -1,12 +1,12 @@
+use std::sync::Arc;
+
 use flowy_client_ws::FlowyWebSocketConnect;
 use flowy_database2::DatabaseManager2;
 use flowy_document::DocumentManager;
 use flowy_document2::manager::DocumentManager as DocumentManager2;
-
 use flowy_folder2::manager::Folder2Manager;
 use flowy_user::services::UserSession;
 use lib_dispatch::prelude::AFPlugin;
-use std::sync::Arc;
 
 pub fn make_plugins(
   ws_conn: &Arc<FlowyWebSocketConnect>,

+ 2 - 1
frontend/rust-lib/flowy-database2/Cargo.toml

@@ -8,7 +8,7 @@ edition = "2021"
 [dependencies]
 collab = { version = "0.1.0" }
 collab-database = { version = "0.1.0" }
-collab-plugins = {version = "0.1.0", feature = ["disk_rocksdb", "sync"]}
+appflowy-integrate = {version = "0.1.0" }
 
 flowy-derive = { path = "../flowy-derive" }
 flowy-notification = { path = "../flowy-notification" }
@@ -39,6 +39,7 @@ async-stream = "0.3.4"
 rayon = "1.6.1"
 nanoid = "0.4.0"
 chrono-tz = "0.8.1"
+async-trait = "0.1"
 
 strum = "0.21"
 strum_macros = "0.21"

+ 29 - 6
frontend/rust-lib/flowy-database2/src/manager.rs

@@ -2,11 +2,12 @@ use std::collections::HashMap;
 use std::ops::Deref;
 use std::sync::Arc;
 
+use appflowy_integrate::collab_builder::AppFlowyCollabBuilder;
+use appflowy_integrate::{RocksCollabDB, RocksDBConfig};
+use collab::core::collab::MutexCollab;
 use collab_database::database::DatabaseData;
-use collab_database::user::UserDatabase as InnerUserDatabase;
+use collab_database::user::{UserDatabase as InnerUserDatabase, UserDatabaseCollabBuilder};
 use collab_database::views::{CreateDatabaseParams, CreateViewParams};
-use collab_plugins::disk::kv::rocks_kv::RocksCollabDB;
-use collab_plugins::disk::rocksdb::Config;
 use parking_lot::Mutex;
 use tokio::sync::RwLock;
 
@@ -19,7 +20,7 @@ use crate::services::database::{DatabaseEditor, MutexDatabase};
 pub trait DatabaseUser2: Send + Sync {
   fn user_id(&self) -> Result<i64, FlowyError>;
   fn token(&self) -> Result<String, FlowyError>;
-  fn kv_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError>;
+  fn collab_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError>;
 }
 
 pub struct DatabaseManager2 {
@@ -27,29 +28,33 @@ pub struct DatabaseManager2 {
   user_database: UserDatabase,
   task_scheduler: Arc<RwLock<TaskDispatcher>>,
   editors: RwLock<HashMap<String, Arc<DatabaseEditor>>>,
+  collab_builder: Arc<AppFlowyCollabBuilder>,
 }
 
 impl DatabaseManager2 {
   pub fn new(
     database_user: Arc<dyn DatabaseUser2>,
     task_scheduler: Arc<RwLock<TaskDispatcher>>,
+    collab_builder: Arc<AppFlowyCollabBuilder>,
   ) -> Self {
     Self {
       user: database_user,
       user_database: UserDatabase::default(),
       task_scheduler,
       editors: Default::default(),
+      collab_builder,
     }
   }
 
   pub async fn initialize(&self, user_id: i64, _token: &str) -> FlowyResult<()> {
-    let db = self.user.kv_db()?;
+    let db = self.user.collab_db()?;
     *self.user_database.lock() = Some(InnerUserDatabase::new(
       user_id,
       db,
-      Config::default()
+      RocksDBConfig::default()
         .enable_snapshot(true)
         .snapshot_per_update(10),
+      UserDatabaseCollabBuilderImpl(self.collab_builder.clone()),
     ));
     // do nothing
     Ok(())
@@ -213,3 +218,21 @@ impl Deref for UserDatabase {
 unsafe impl Sync for UserDatabase {}
 
 unsafe impl Send for UserDatabase {}
+
+struct UserDatabaseCollabBuilderImpl(Arc<AppFlowyCollabBuilder>);
+
+impl UserDatabaseCollabBuilder for UserDatabaseCollabBuilderImpl {
+  fn build(&self, uid: i64, object_id: &str, db: Arc<RocksCollabDB>) -> Arc<MutexCollab> {
+    self.0.build(uid, object_id, db)
+  }
+
+  fn build_with_config(
+    &self,
+    uid: i64,
+    object_id: &str,
+    db: Arc<RocksCollabDB>,
+    config: &RocksDBConfig,
+  ) -> Arc<MutexCollab> {
+    self.0.build_with_config(uid, object_id, db, config)
+  }
+}

+ 1 - 1
frontend/rust-lib/flowy-database2/src/services/field/type_options/number_type_option/number_type_option.rs

@@ -248,7 +248,7 @@ impl TypeOptionCellDataCompare for NumberTypeOption {
       NumberCellFormat::from_format_str(&other_cell_data.0, self.sign_positive, &self.format);
     match (left, right) {
       (Ok(left), Ok(right)) => {
-        return left.decimal().cmp(&right.decimal());
+        return left.decimal().cmp(right.decimal());
       },
       (Ok(_), Err(_)) => Ordering::Greater,
       (Err(_), Ok(_)) => Ordering::Less,

+ 1 - 1
frontend/rust-lib/flowy-document2/Cargo.toml

@@ -8,7 +8,7 @@ edition = "2021"
 [dependencies]
 collab = { version = "0.1.0" }
 collab-document = { version = "0.1.0" }
-collab-plugins = {version = "0.1.0", feature = ["disk_rocksdb", "sync"]}
+appflowy-integrate = {version = "0.1.0" }
 
 flowy-derive = { path = "../flowy-derive" }
 flowy-notification = { path = "../flowy-notification" }

+ 6 - 4
frontend/rust-lib/flowy-document2/src/document.rs

@@ -5,28 +5,30 @@ use std::{
   vec,
 };
 
-use collab::preclude::Collab;
+use collab::core::collab::MutexCollab;
+
 use collab_document::{
   blocks::{Block, DocumentData, DocumentMeta},
   document::Document as InnerDocument,
 };
-use flowy_error::{ErrorCode, FlowyError, FlowyResult};
 use nanoid::nanoid;
 use parking_lot::Mutex;
 
+use flowy_error::{ErrorCode, FlowyError, FlowyResult};
+
 use crate::entities::{BlockPB, ChildrenPB, DocumentDataPB2, MetaPB};
 
 #[derive(Clone)]
 pub struct Document(Arc<Mutex<InnerDocument>>);
 
 impl Document {
-  pub fn new(collab: Collab) -> FlowyResult<Self> {
+  pub fn new(collab: Arc<MutexCollab>) -> FlowyResult<Self> {
     let inner = InnerDocument::create(collab)
       .map_err(|_| FlowyError::from(ErrorCode::DocumentDataInvalid))?;
     Ok(Self(Arc::new(Mutex::new(inner))))
   }
 
-  pub fn create_with_data(collab: Collab, data: DocumentData) -> FlowyResult<Self> {
+  pub fn create_with_data(collab: Arc<MutexCollab>, data: DocumentData) -> FlowyResult<Self> {
     let inner = InnerDocument::create_with_data(collab, data)
       .map_err(|_| FlowyError::from(ErrorCode::DocumentDataInvalid))?;
     Ok(Self(Arc::new(Mutex::new(inner))))

+ 11 - 9
frontend/rust-lib/flowy-document2/src/event_handler.rs

@@ -1,5 +1,13 @@
 use std::sync::Arc;
 
+use collab_document::blocks::{
+  json_str_to_hashmap, Block, BlockAction, BlockActionPayload, BlockActionType, BlockEvent,
+  BlockEventPayload, DeltaType,
+};
+
+use flowy_error::{FlowyError, FlowyResult};
+use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataResult};
+
 use crate::{
   document::DocumentDataWrapper,
   entities::{
@@ -10,18 +18,12 @@ use crate::{
   manager::DocumentManager,
 };
 
-use collab_document::blocks::{
-  json_str_to_hashmap, Block, BlockAction, BlockActionPayload, BlockActionType, BlockEvent,
-  BlockEventPayload, DeltaType,
-};
-use flowy_error::{FlowyError, FlowyResult};
-use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataResult};
 pub(crate) async fn open_document_handler(
   data: AFPluginData<OpenDocumentPayloadPBV2>,
   manager: AFPluginState<Arc<DocumentManager>>,
 ) -> DataResult<DocumentDataPB2, FlowyError> {
   let context = data.into_inner();
-  let document = manager.open_document(context.document_id)?;
+  let document = manager.open_document(context.document_id).await?;
   let document_data = document
     .lock()
     .get_document()
@@ -35,7 +37,7 @@ pub(crate) async fn create_document_handler(
 ) -> FlowyResult<()> {
   let context = data.into_inner();
   let data = DocumentDataWrapper::default();
-  manager.create_document(context.document_id, data)?;
+  manager.create_document(context.document_id, data).await?;
   Ok(())
 }
 
@@ -59,7 +61,7 @@ pub(crate) async fn apply_action_handler(
     .into_iter()
     .map(|action| action.into())
     .collect();
-  let document = manager.open_document(doc_id)?;
+  let document = manager.open_document(doc_id).await?;
   document.lock().apply_action(actions);
   Ok(())
 }

+ 19 - 25
frontend/rust-lib/flowy-document2/src/manager.rs

@@ -1,8 +1,8 @@
 use std::{collections::HashMap, sync::Arc};
 
-use collab::preclude::{Collab, CollabBuilder};
-use collab_plugins::disk::kv::rocks_kv::RocksCollabDB;
-use collab_plugins::disk::rocksdb::RocksdbDiskPlugin;
+use appflowy_integrate::collab_builder::AppFlowyCollabBuilder;
+use appflowy_integrate::RocksCollabDB;
+
 use parking_lot::RwLock;
 
 use flowy_error::{FlowyError, FlowyResult};
@@ -16,42 +16,48 @@ use crate::{
 pub trait DocumentUser: Send + Sync {
   fn user_id(&self) -> Result<i64, FlowyError>;
   fn token(&self) -> Result<String, FlowyError>; // unused now.
-  fn kv_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError>;
+  fn collab_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError>;
 }
 
 pub struct DocumentManager {
-  documents: Arc<RwLock<HashMap<String, Arc<Document>>>>,
   user: Arc<dyn DocumentUser>,
+  collab_builder: Arc<AppFlowyCollabBuilder>,
+  documents: Arc<RwLock<HashMap<String, Arc<Document>>>>,
 }
 
-// unsafe impl Send for DocumentManager {}
-// unsafe impl Sync for DocumentManager {}
+unsafe impl Send for DocumentManager {}
+unsafe impl Sync for DocumentManager {}
 
 impl DocumentManager {
-  pub fn new(user: Arc<dyn DocumentUser>) -> Self {
+  pub fn new(user: Arc<dyn DocumentUser>, collab_builder: Arc<AppFlowyCollabBuilder>) -> Self {
     Self {
-      documents: Default::default(),
       user,
+      collab_builder,
+      documents: Default::default(),
     }
   }
 
-  pub fn create_document(
+  pub async fn create_document(
     &self,
     doc_id: String,
     data: DocumentDataWrapper,
   ) -> FlowyResult<Arc<Document>> {
-    let collab = self.get_collab_for_doc_id(&doc_id)?;
+    let uid = self.user.user_id()?;
+    let db = self.user.collab_db()?;
+    let collab = self.collab_builder.build(uid, &doc_id, db);
     let document = Arc::new(Document::create_with_data(collab, data.0)?);
     self.documents.write().insert(doc_id, document.clone());
     Ok(document)
   }
 
-  pub fn open_document(&self, doc_id: String) -> FlowyResult<Arc<Document>> {
+  pub async fn open_document(&self, doc_id: String) -> FlowyResult<Arc<Document>> {
     if let Some(doc) = self.documents.read().get(&doc_id) {
       return Ok(doc.clone());
     }
     tracing::debug!("open_document: {:?}", &doc_id);
-    let collab = self.get_collab_for_doc_id(&doc_id)?;
+    let uid = self.user.user_id()?;
+    let db = self.user.collab_db()?;
+    let collab = self.collab_builder.build(uid, &doc_id, db);
     let document = Arc::new(Document::new(collab)?);
 
     let clone_doc_id = doc_id.clone();
@@ -72,16 +78,4 @@ impl DocumentManager {
     self.documents.write().remove(&doc_id);
     Ok(())
   }
-
-  fn get_collab_for_doc_id(&self, doc_id: &str) -> Result<Collab, FlowyError> {
-    let uid = self.user.user_id()?;
-    let kv_db = self.user.kv_db()?;
-    let mut collab = CollabBuilder::new(uid, doc_id).build();
-    let disk_plugin = Arc::new(
-      RocksdbDiskPlugin::new(uid, kv_db).map_err(|err| FlowyError::internal().context(err))?,
-    );
-    collab.add_plugin(disk_plugin);
-    collab.initial();
-    Ok(collab)
-  }
 }

+ 34 - 22
frontend/rust-lib/flowy-document2/tests/document/document_test.rs

@@ -1,22 +1,26 @@
 use std::{collections::HashMap, sync::Arc, vec};
 
+use appflowy_integrate::collab_builder::AppFlowyCollabBuilder;
+use appflowy_integrate::config::AppFlowyCollabConfig;
 use collab_document::blocks::{Block, BlockAction, BlockActionPayload, BlockActionType};
-use flowy_document2::{document::DocumentDataWrapper, manager::DocumentManager};
 use nanoid::nanoid;
 use serde_json::{json, to_value, Value};
 
+use flowy_document2::{document::DocumentDataWrapper, manager::DocumentManager};
+
 use super::util::FakeUser;
 
-#[test]
-fn restore_document() {
+#[tokio::test]
+async fn restore_document() {
   let user = FakeUser::new();
-  let manager = DocumentManager::new(Arc::new(user));
+  let manager = DocumentManager::new(Arc::new(user), default_collab_builder());
 
   // create a document
   let doc_id: String = nanoid!(10);
   let data = DocumentDataWrapper::default();
   let document_a = manager
     .create_document(doc_id.clone(), data.clone())
+    .await
     .unwrap();
   let data_a = document_a.lock().get_document().unwrap();
   assert_eq!(data_a, data.0);
@@ -24,6 +28,7 @@ fn restore_document() {
   // open a document
   let data_b = manager
     .open_document(doc_id.clone())
+    .await
     .unwrap()
     .lock()
     .get_document()
@@ -33,10 +38,11 @@ fn restore_document() {
   assert_eq!(data_b, data.0);
 
   // restore
-  _ = manager.create_document(doc_id.clone(), data.clone());
+  _ = manager.create_document(doc_id.clone(), data.clone()).await;
   // open a document
   let data_b = manager
     .open_document(doc_id.clone())
+    .await
     .unwrap()
     .lock()
     .get_document()
@@ -47,19 +53,19 @@ fn restore_document() {
   assert_eq!(data_b, data.0);
 }
 
-#[test]
-fn document_apply_insert_action() {
+#[tokio::test]
+async fn document_apply_insert_action() {
   let user = FakeUser::new();
-  let manager = DocumentManager::new(Arc::new(user));
+  let manager = DocumentManager::new(Arc::new(user), default_collab_builder());
 
   let doc_id: String = nanoid!(10);
   let data = DocumentDataWrapper::default();
 
   // create a document
-  _ = manager.create_document(doc_id.clone(), data.clone());
+  _ = manager.create_document(doc_id.clone(), data.clone()).await;
 
   // open a document
-  let document = manager.open_document(doc_id.clone()).unwrap();
+  let document = manager.open_document(doc_id.clone()).await.unwrap();
   let page_block = document.lock().get_block(&data.0.page_id).unwrap();
 
   // insert a text block
@@ -88,6 +94,7 @@ fn document_apply_insert_action() {
   // re-open the document
   let data_b = manager
     .open_document(doc_id.clone())
+    .await
     .unwrap()
     .lock()
     .get_document()
@@ -98,19 +105,19 @@ fn document_apply_insert_action() {
   assert_eq!(data_b, data_a);
 }
 
-#[test]
-fn document_apply_update_page_action() {
+#[tokio::test]
+async fn document_apply_update_page_action() {
   let user = FakeUser::new();
-  let manager = DocumentManager::new(Arc::new(user));
+  let manager = DocumentManager::new(Arc::new(user), default_collab_builder());
 
   let doc_id: String = nanoid!(10);
   let data = DocumentDataWrapper::default();
 
   // create a document
-  _ = manager.create_document(doc_id.clone(), data.clone());
+  _ = manager.create_document(doc_id.clone(), data.clone()).await;
 
   // open a document
-  let document = manager.open_document(doc_id.clone()).unwrap();
+  let document = manager.open_document(doc_id.clone()).await.unwrap();
   let page_block = document.lock().get_block(&data.0.page_id).unwrap();
 
   let mut page_block_clone = page_block;
@@ -134,25 +141,25 @@ fn document_apply_update_page_action() {
   _ = manager.close_document(doc_id.clone());
 
   // re-open the document
-  let document = manager.open_document(doc_id).unwrap();
+  let document = manager.open_document(doc_id).await.unwrap();
   let page_block_new = document.lock().get_block(&data.0.page_id).unwrap();
   assert_eq!(page_block_old, page_block_new);
   assert!(page_block_new.data.contains_key("delta"));
 }
 
-#[test]
-fn document_apply_update_action() {
+#[tokio::test]
+async fn document_apply_update_action() {
   let user = FakeUser::new();
-  let manager = DocumentManager::new(Arc::new(user));
+  let manager = DocumentManager::new(Arc::new(user), default_collab_builder());
 
   let doc_id: String = nanoid!(10);
   let data = DocumentDataWrapper::default();
 
   // create a document
-  _ = manager.create_document(doc_id.clone(), data.clone());
+  _ = manager.create_document(doc_id.clone(), data.clone()).await;
 
   // open a document
-  let document = manager.open_document(doc_id.clone()).unwrap();
+  let document = manager.open_document(doc_id.clone()).await.unwrap();
   let page_block = document.lock().get_block(&data.0.page_id).unwrap();
 
   // insert a text block
@@ -202,9 +209,14 @@ fn document_apply_update_action() {
   _ = manager.close_document(doc_id.clone());
 
   // re-open the document
-  let document = manager.open_document(doc_id.clone()).unwrap();
+  let document = manager.open_document(doc_id.clone()).await.unwrap();
   let block = document.lock().get_block(&text_block_id).unwrap();
   assert_eq!(block.data, updated_text_block_data);
   // close a document
   _ = manager.close_document(doc_id);
 }
+
+fn default_collab_builder() -> Arc<AppFlowyCollabBuilder> {
+  let builder = AppFlowyCollabBuilder::new(AppFlowyCollabConfig::default());
+  Arc::new(builder)
+}

+ 2 - 2
frontend/rust-lib/flowy-document2/tests/document/util.rs

@@ -1,6 +1,6 @@
 use std::sync::Arc;
 
-use collab_plugins::disk::kv::rocks_kv::RocksCollabDB;
+use appflowy_integrate::RocksCollabDB;
 use parking_lot::Once;
 use tempfile::TempDir;
 use tracing_subscriber::{fmt::Subscriber, util::SubscriberInitExt, EnvFilter};
@@ -26,7 +26,7 @@ impl DocumentUser for FakeUser {
     Ok("1".to_string())
   }
 
-  fn kv_db(&self) -> Result<std::sync::Arc<RocksCollabDB>, flowy_error::FlowyError> {
+  fn collab_db(&self) -> Result<std::sync::Arc<RocksCollabDB>, flowy_error::FlowyError> {
     Ok(self.kv.clone())
   }
 }

+ 1 - 1
frontend/rust-lib/flowy-folder2/Cargo.toml

@@ -8,7 +8,7 @@ edition = "2021"
 [dependencies]
 collab = { version = "0.1.0" }
 collab-folder = { version = "0.1.0" }
-collab-plugins = {version = "0.1.0", feature = ["disk_rocksdb", "sync"]}
+appflowy-integrate = {version = "0.1.0" }
 
 flowy-derive = { path = "../flowy-derive" }
 flowy-notification = { path = "../flowy-notification" }

+ 9 - 13
frontend/rust-lib/flowy-folder2/src/manager.rs

@@ -2,13 +2,13 @@ use std::collections::{HashMap, HashSet};
 use std::ops::Deref;
 use std::sync::Arc;
 
-use collab::preclude::CollabBuilder;
+use appflowy_integrate::collab_builder::AppFlowyCollabBuilder;
+use appflowy_integrate::RocksCollabDB;
+
 use collab_folder::core::{
   Folder as InnerFolder, FolderContext, TrashChange, TrashChangeReceiver, TrashInfo, TrashRecord,
   View, ViewChange, ViewChangeReceiver, ViewLayout, Workspace,
 };
-use collab_plugins::disk::kv::rocks_kv::RocksCollabDB;
-use collab_plugins::disk::rocksdb::RocksdbDiskPlugin;
 use parking_lot::Mutex;
 use tracing::{event, Level};
 
@@ -31,11 +31,12 @@ use crate::view_ext::{
 pub trait FolderUser: Send + Sync {
   fn user_id(&self) -> Result<i64, FlowyError>;
   fn token(&self) -> Result<String, FlowyError>;
-  fn kv_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError>;
+  fn collab_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError>;
 }
 
 pub struct Folder2Manager {
   folder: Folder,
+  collab_builder: Arc<AppFlowyCollabBuilder>,
   user: Arc<dyn FolderUser>,
   view_processors: ViewDataProcessorMap,
 }
@@ -46,13 +47,14 @@ unsafe impl Sync for Folder2Manager {}
 impl Folder2Manager {
   pub async fn new(
     user: Arc<dyn FolderUser>,
+    collab_builder: Arc<AppFlowyCollabBuilder>,
     view_processors: ViewDataProcessorMap,
   ) -> FlowyResult<Self> {
-    // let folder = make_user_folder(user.clone())?;
     let folder = Folder::default();
     let manager = Self {
       user,
       folder,
+      collab_builder,
       view_processors,
     };
 
@@ -94,14 +96,8 @@ impl Folder2Manager {
     if let Ok(uid) = self.user.user_id() {
       let folder_id = FolderId::new(uid);
 
-      if let Ok(kv_db) = self.user.kv_db() {
-        let mut collab = CollabBuilder::new(uid, folder_id).build();
-        let disk_plugin = Arc::new(
-          RocksdbDiskPlugin::new(uid, kv_db).map_err(|err| FlowyError::internal().context(err))?,
-        );
-        collab.add_plugin(disk_plugin);
-        collab.initial();
-
+      if let Ok(kv_db) = self.user.collab_db() {
+        let collab = self.collab_builder.build(uid, folder_id.as_ref(), kv_db);
         let (view_tx, view_rx) = tokio::sync::broadcast::channel(100);
         let (trash_tx, trash_rx) = tokio::sync::broadcast::channel(100);
         let folder_context = FolderContext {

+ 1 - 2
frontend/rust-lib/flowy-user/Cargo.toml

@@ -13,8 +13,7 @@ user-model = { path = "../../../shared-lib/user-model" }
 lib-infra = { path = "../../../shared-lib/lib-infra" }
 flowy-notification = { path = "../flowy-notification" }
 lib-dispatch = { path = "../lib-dispatch" }
-collab-persistence = { version = "0.1.0" }
-
+appflowy-integrate = { version = "0.1.0" }
 
 tracing = { version = "0.1", features = ["log"] }
 bytes = "1.4"

+ 1 - 1
frontend/rust-lib/flowy-user/src/services/database.rs

@@ -1,7 +1,7 @@
 use std::path::PathBuf;
 use std::{collections::HashMap, sync::Arc, time::Duration};
 
-use collab_persistence::kv::rocks_kv::RocksCollabDB;
+use appflowy_integrate::RocksCollabDB;
 use lazy_static::lazy_static;
 use parking_lot::RwLock;
 

+ 19 - 48
frontend/rust-lib/flowy-user/src/services/user_session.rs

@@ -1,6 +1,9 @@
 use std::sync::Arc;
 
-use collab_persistence::kv::rocks_kv::RocksCollabDB;
+use appflowy_integrate::RocksCollabDB;
+use serde::{Deserialize, Serialize};
+use tokio::sync::RwLock;
+
 use flowy_sqlite::ConnectionPool;
 use flowy_sqlite::{
   kv::KV,
@@ -8,8 +11,6 @@ use flowy_sqlite::{
   schema::{user_table, user_table::dsl},
   DBConnection, ExpressionMethods, UserDatabaseConnection,
 };
-use serde::{Deserialize, Serialize};
-use tokio::sync::RwLock;
 use user_model::{
   SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserProfileParams, UserProfile,
 };
@@ -47,60 +48,24 @@ impl UserSessionConfig {
 
 pub struct UserSession {
   database: UserDB,
-  config: UserSessionConfig,
+  session_config: UserSessionConfig,
   cloud_service: Arc<dyn UserCloudService>,
   user_status_callback: RwLock<Option<Arc<dyn UserStatusCallback>>>,
 }
 
 impl UserSession {
-  pub fn new(config: UserSessionConfig, cloud_service: Arc<dyn UserCloudService>) -> Self {
-    let db = UserDB::new(&config.root_dir);
+  pub fn new(session_config: UserSessionConfig, cloud_service: Arc<dyn UserCloudService>) -> Self {
+    let db = UserDB::new(&session_config.root_dir);
     let user_status_callback = RwLock::new(None);
     Self {
       database: db,
-      config,
+      session_config,
       cloud_service,
       user_status_callback,
     }
   }
 
   pub async fn init<C: UserStatusCallback + 'static>(&self, user_status_callback: C) {
-    // if let Some(old_session) = self.get_old_session() {
-    //   let uid = ID_GEN.lock().next_id();
-    //   let _ = user_status_callback
-    //     .will_migrated(&old_session.token, &old_session.user_id, uid)
-    //     .await;
-    //
-    //   let new_session = Session {
-    //     user_id: uid,
-    //     token: old_session.token.clone(),
-    //     email: old_session.email.clone(),
-    //     name: old_session.name.clone(),
-    //   };
-    //   self.set_session(Some(new_session)).unwrap();
-    //
-    //   if let Ok(db) = self.db_connection() {
-    //     // Update db
-    //     let _ = db.immediate_transaction(|| {
-    //       // get the user data
-    //       let mut user = dsl::user_table
-    //         .filter(user_table::id.eq(&old_session.user_id))
-    //         .first::<UserTable>(&*db)?;
-    //
-    //       // delete the existing row
-    //       let _ = diesel::delete(dsl::user_table.filter(dsl::id.eq(&old_session.user_id)))
-    //         .execute(&*db)?;
-    //
-    //       // insert new row
-    //       user.id = uid.to_string();
-    //       let _ = diesel::insert_into(user_table::table)
-    //         .values(user)
-    //         .execute(&*db)?;
-    //       Ok::<(), FlowyError>(())
-    //     });
-    //   }
-    // }
-
     if let Ok(session) = self.get_session() {
       let _ = user_status_callback
         .did_sign_in(&session.token, session.user_id)
@@ -125,7 +90,7 @@ impl UserSession {
     self.database.get_pool(user_id)
   }
 
-  pub fn get_kv_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError> {
+  pub fn get_collab_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError> {
     let user_id = self.get_session()?.user_id;
     self.database.get_kv_db(user_id)
   }
@@ -251,7 +216,10 @@ impl UserSession {
 
   pub fn user_dir(&self) -> Result<String, FlowyError> {
     let session = self.get_session()?;
-    Ok(format!("{}/{}", self.config.root_dir, session.user_id))
+    Ok(format!(
+      "{}/{}",
+      self.session_config.root_dir, session.user_id
+    ))
   }
 
   pub fn user_setting(&self) -> Result<UserSettingPB, FlowyError> {
@@ -323,15 +291,18 @@ impl UserSession {
   fn set_session(&self, session: Option<Session>) -> Result<(), FlowyError> {
     tracing::debug!("Set user session: {:?}", session);
     match &session {
-      None => KV::remove(&self.config.session_cache_key)
+      None => KV::remove(&self.session_config.session_cache_key)
         .map_err(|e| FlowyError::new(ErrorCode::Internal, &e))?,
-      Some(session) => KV::set_str(&self.config.session_cache_key, session.clone().into()),
+      Some(session) => KV::set_str(
+        &self.session_config.session_cache_key,
+        session.clone().into(),
+      ),
     }
     Ok(())
   }
 
   fn get_session(&self) -> Result<Session, FlowyError> {
-    match KV::get_str(&self.config.session_cache_key) {
+    match KV::get_str(&self.session_config.session_cache_key) {
       None => Err(FlowyError::unauthorized()),
       Some(s) => Ok(Session::from(s)),
     }