diff --git a/.github/workflows/rust_ci.yaml b/.github/workflows/rust_ci.yaml index c722565cb5..3abfa67ad0 100644 --- a/.github/workflows/rust_ci.yaml +++ b/.github/workflows/rust_ci.yaml @@ -78,7 +78,7 @@ jobs: af_cloud_test_base_url: http://localhost af_cloud_test_ws_url: ws://localhost/ws af_cloud_test_gotrue_url: http://localhost/gotrue - run: cargo test --no-default-features --features="rev-sqlite" -- --nocapture + run: cargo test --no-default-features --features="rev-sqlite,dart" -- --nocapture - name: rustfmt rust-lib diff --git a/.github/workflows/web_ci.yaml b/.github/workflows/web_ci.yaml index 5bb14bbf40..943a778b12 100644 --- a/.github/workflows/web_ci.yaml +++ b/.github/workflows/web_ci.yaml @@ -79,4 +79,4 @@ jobs: working-directory: frontend/appflowy_web run: | pnpm install - pnpm run wasm + pnpm run build_release_wasm diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index 48aefac8fd..5d97e78bc0 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -49,6 +49,7 @@ LIB_EXT = "a" APP_ENVIRONMENT = "local" FLUTTER_FLOWY_SDK_PATH = "appflowy_flutter/packages/appflowy_backend" TAURI_BACKEND_SERVICE_PATH = "appflowy_tauri/src/services/backend" +WEB_BACKEND_SERVICE_PATH = "appflowy_web/src/services/backend" # Test default config TEST_CRATE_TYPE = "cdylib" TEST_LIB_EXT = "dylib" diff --git a/frontend/appflowy_tauri/package.json b/frontend/appflowy_tauri/package.json index 4cc3b04a1b..120b822199 100644 --- a/frontend/appflowy_tauri/package.json +++ b/frontend/appflowy_tauri/package.json @@ -35,7 +35,7 @@ "emoji-mart": "^5.5.2", "emoji-regex": "^10.2.1", "events": "^3.3.0", - "google-protobuf": "^3.21.2", + "google-protobuf": "^3.15.12", "i18next": "^22.4.10", "i18next-browser-languagedetector": "^7.0.1", "i18next-resources-to-backend": "^1.1.4", @@ -46,7 +46,7 @@ "lodash-es": "^4.17.21", "nanoid": "^4.0.0", "prismjs": "^1.29.0", - "protoc-gen-ts": "^0.8.5", + "protoc-gen-ts": "0.8.7", "quill": "^1.3.7", "quill-delta": "^5.1.0", "react": "^18.2.0", @@ -80,7 +80,7 @@ "devDependencies": { "@svgr/plugin-svgo": "^8.0.1", "@tauri-apps/cli": "^1.5.6", - "@types/google-protobuf": "^3.15.6", + "@types/google-protobuf": "^3.15.12", "@types/is-hotkey": "^0.1.7", "@types/jest": "^29.5.3", "@types/katex": "^0.16.0", diff --git a/frontend/appflowy_tauri/pnpm-lock.yaml b/frontend/appflowy_tauri/pnpm-lock.yaml index 18b6eedbb7..ba9fb26574 100644 --- a/frontend/appflowy_tauri/pnpm-lock.yaml +++ b/frontend/appflowy_tauri/pnpm-lock.yaml @@ -53,7 +53,7 @@ dependencies: specifier: ^3.3.0 version: 3.3.0 google-protobuf: - specifier: ^3.21.2 + specifier: ^3.15.12 version: 3.21.2 i18next: specifier: ^22.4.10 @@ -86,8 +86,8 @@ dependencies: specifier: ^1.29.0 version: 1.29.0 protoc-gen-ts: - specifier: ^0.8.5 - version: 0.8.6(google-protobuf@3.21.2)(typescript@4.9.5) + specifier: 0.8.7 + version: 0.8.7 quill: specifier: ^1.3.7 version: 1.3.7 @@ -184,8 +184,8 @@ devDependencies: specifier: ^1.5.6 version: 1.5.6 '@types/google-protobuf': - specifier: ^3.15.6 - version: 3.15.6 + specifier: ^3.15.12 + version: 3.15.12 '@types/is-hotkey': specifier: ^0.1.7 version: 0.1.7 @@ -2241,8 +2241,8 @@ packages: resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} dev: true - /@types/google-protobuf@3.15.6: - resolution: {integrity: sha512-pYVNNJ+winC4aek+lZp93sIKxnXt5qMkuKmaqS3WGuTq0Bw1ZDYNBgzG5kkdtwcv+GmYJGo3yEg6z2cKKAiEdw==} + /@types/google-protobuf@3.15.12: + resolution: {integrity: sha512-40um9QqwHjRS92qnOaDpL7RmDK15NuZYo9HihiJRbYkMQZlWnuH8AdvbMy8/o6lgLmKbDUKa+OALCltHdbOTpQ==} dev: true /@types/graceful-fs@4.1.6: @@ -5629,15 +5629,9 @@ packages: object-assign: 4.1.1 react-is: 16.13.1 - /protoc-gen-ts@0.8.6(google-protobuf@3.21.2)(typescript@4.9.5): - resolution: {integrity: sha512-66oeorGy4QBvYjQGd/gaeOYyFqKyRmRgTpofmnw8buMG0P7A0jQjoKSvKJz5h5tNUaVkIzvGBUTRVGakrhhwpA==} + /protoc-gen-ts@0.8.7: + resolution: {integrity: sha512-jr4VJey2J9LVYCV7EVyVe53g1VMw28cCmYJhBe5e3YX5wiyiDwgxWxeDf9oTqAe4P1bN/YGAkW2jhlH8LohwiQ==} hasBin: true - peerDependencies: - google-protobuf: ^3.13.0 - typescript: 4.x.x - dependencies: - google-protobuf: 3.21.2 - typescript: 4.9.5 dev: false /proxy-compare@2.5.1: @@ -6835,6 +6829,7 @@ packages: resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} engines: {node: '>=4.2.0'} hasBin: true + dev: true /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 293332ea12..63734c7d0c 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -64,6 +64,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "again" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05802a5ad4d172eaf796f7047b42d0af9db513585d16d4169660a21613d34b93" +dependencies = [ + "log", + "rand 0.7.3", + "wasm-timer", +] + [[package]] name = "ahash" version = "0.7.6" @@ -151,7 +162,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "bincode", @@ -171,9 +182,13 @@ name = "appflowy_tauri" version = "0.0.0" dependencies = [ "bytes", + "flowy-config", "flowy-core", + "flowy-date", + "flowy-document", "flowy-error", "flowy-notification", + "flowy-user", "lib-dispatch", "serde", "serde_json", @@ -618,9 +633,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" dependencies = [ "android-tzdata", "iana-time-zone", @@ -628,7 +643,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.0", + "windows-targets 0.52.0", ] [[package]] @@ -699,8 +714,9 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ + "again", "anyhow", "app-error", "async-trait", @@ -718,7 +734,7 @@ dependencies = [ "gotrue-entity", "mime", "mime_guess", - "parking_lot", + "parking_lot 0.12.1", "prost", "realtime-entity", "realtime-protocol", @@ -727,15 +743,16 @@ dependencies = [ "serde", "serde_json", "serde_repr", - "shared_entity", + "shared-entity", "thiserror", "tokio", "tokio-retry", "tokio-stream", - "tokio-tungstenite", "tracing", "url", "uuid", + "wasm-bindgen-futures", + "websocket", "workspace-template", "yrs", ] @@ -799,14 +816,14 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3eef93f35f606edef2541888cb91cd6686d77225#3eef93f35f606edef2541888cb91cd6686d77225" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" dependencies = [ "anyhow", "async-trait", "bincode", "bytes", "js-sys", - "parking_lot", + "parking_lot 0.12.1", "serde", "serde_json", "serde_repr", @@ -821,7 +838,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3eef93f35f606edef2541888cb91cd6686d77225#3eef93f35f606edef2541888cb91cd6686d77225" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" dependencies = [ "anyhow", "async-trait", @@ -833,7 +850,7 @@ dependencies = [ "lazy_static", "lru", "nanoid", - "parking_lot", + "parking_lot 0.12.1", "serde", "serde_json", "serde_repr", @@ -849,13 +866,13 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3eef93f35f606edef2541888cb91cd6686d77225#3eef93f35f606edef2541888cb91cd6686d77225" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" dependencies = [ "anyhow", "collab", "collab-entity", "nanoid", - "parking_lot", + "parking_lot 0.12.1", "serde", "serde_json", "thiserror", @@ -867,7 +884,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3eef93f35f606edef2541888cb91cd6686d77225#3eef93f35f606edef2541888cb91cd6686d77225" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" dependencies = [ "anyhow", "bytes", @@ -881,13 +898,13 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3eef93f35f606edef2541888cb91cd6686d77225#3eef93f35f606edef2541888cb91cd6686d77225" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" dependencies = [ "anyhow", "chrono", "collab", "collab-entity", - "parking_lot", + "parking_lot 0.12.1", "serde", "serde_json", "serde_repr", @@ -907,7 +924,7 @@ dependencies = [ "collab-entity", "collab-plugins", "lib-infra", - "parking_lot", + "parking_lot 0.12.1", "serde", "serde_json", "tokio", @@ -917,7 +934,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3eef93f35f606edef2541888cb91cd6686d77225#3eef93f35f606edef2541888cb91cd6686d77225" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" dependencies = [ "anyhow", "async-stream", @@ -932,7 +949,7 @@ dependencies = [ "indexed_db_futures", "js-sys", "lazy_static", - "parking_lot", + "parking_lot 0.12.1", "rand 0.8.5", "rocksdb", "serde", @@ -955,12 +972,12 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3eef93f35f606edef2541888cb91cd6686d77225#3eef93f35f606edef2541888cb91cd6686d77225" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" dependencies = [ "anyhow", "collab", "collab-entity", - "parking_lot", + "parking_lot 0.12.1", "serde", "serde_json", "tokio", @@ -1276,7 +1293,7 @@ dependencies = [ "hashbrown 0.12.3", "lock_api", "once_cell", - "parking_lot_core", + "parking_lot_core 0.9.8", ] [[package]] @@ -1288,7 +1305,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "app-error", @@ -1715,7 +1732,7 @@ dependencies = [ "lib-dispatch", "lib-infra", "lib-log", - "parking_lot", + "parking_lot 0.12.1", "serde", "serde_json", "serde_repr", @@ -1766,7 +1783,7 @@ dependencies = [ "lib-infra", "lru", "nanoid", - "parking_lot", + "parking_lot 0.12.1", "protobuf", "rayon", "rust_decimal", @@ -1837,7 +1854,7 @@ dependencies = [ "lib-infra", "lru", "nanoid", - "parking_lot", + "parking_lot 0.12.1", "protobuf", "scraper 0.18.1", "serde", @@ -1922,7 +1939,7 @@ dependencies = [ "lib-dispatch", "lib-infra", "nanoid", - "parking_lot", + "parking_lot 0.12.1", "protobuf", "serde_json", "strum_macros 0.21.1", @@ -1988,7 +2005,7 @@ dependencies = [ "lib-dispatch", "lib-infra", "mime_guess", - "parking_lot", + "parking_lot 0.12.1", "postgrest", "reqwest", "serde", @@ -2022,7 +2039,7 @@ dependencies = [ "diesel_derives", "diesel_migrations", "libsqlite3-sys", - "parking_lot", + "parking_lot 0.12.1", "r2d2", "scheduled-thread-pool", "serde", @@ -2082,7 +2099,7 @@ dependencies = [ "lib-dispatch", "lib-infra", "once_cell", - "parking_lot", + "parking_lot 0.12.1", "protobuf", "serde", "serde_json", @@ -2102,6 +2119,7 @@ name = "flowy-user-pub" version = "0.1.0" dependencies = [ "anyhow", + "base64 0.21.5", "chrono", "collab", "collab-entity", @@ -2113,6 +2131,7 @@ dependencies = [ "serde_repr", "tokio", "tokio-stream", + "tracing", "uuid", ] @@ -2549,7 +2568,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "futures-util", @@ -2566,10 +2585,11 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "app-error", + "chrono", "jsonwebtoken", "lazy_static", "serde", @@ -3002,7 +3022,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "reqwest", @@ -3109,9 +3129,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -3193,7 +3213,7 @@ dependencies = [ "futures-util", "getrandom 0.2.10", "nanoid", - "parking_lot", + "parking_lot 0.12.1", "pin-project", "protobuf", "serde", @@ -3204,6 +3224,7 @@ dependencies = [ "tracing", "validator", "wasm-bindgen", + "wasm-bindgen-futures", ] [[package]] @@ -3873,6 +3894,17 @@ dependencies = [ "system-deps 6.1.1", ] +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -3880,7 +3912,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core", + "parking_lot_core 0.9.8", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", ] [[package]] @@ -4532,7 +4578,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" dependencies = [ "log", - "parking_lot", + "parking_lot 0.12.1", "scheduled-thread-pool", ] @@ -4654,7 +4700,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "bincode", @@ -4670,13 +4716,14 @@ dependencies = [ "serde_json", "thiserror", "tokio-tungstenite", + "websocket", "yrs", ] [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "bincode", @@ -5017,7 +5064,7 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" dependencies = [ - "parking_lot", + "parking_lot 0.12.1", ] [[package]] @@ -5322,9 +5369,9 @@ dependencies = [ ] [[package]] -name = "shared_entity" +name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "app-error", @@ -5507,7 +5554,7 @@ checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ "new_debug_unreachable", "once_cell", - "parking_lot", + "parking_lot 0.12.1", "phf_shared 0.10.0", "precomputed-hash", "serde", @@ -5671,7 +5718,7 @@ dependencies = [ "ndk-sys", "objc", "once_cell", - "parking_lot", + "parking_lot 0.12.1", "png", "raw-window-handle", "scopeguard", @@ -6061,7 +6108,7 @@ dependencies = [ "libc", "mio", "num_cpus", - "parking_lot", + "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", "socket2 0.5.5", @@ -6646,9 +6693,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -6656,9 +6703,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", @@ -6671,9 +6718,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" dependencies = [ "cfg-if", "js-sys", @@ -6683,9 +6730,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6693,9 +6740,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", @@ -6706,9 +6753,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "wasm-streams" @@ -6723,6 +6770,21 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasm-timer" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.11.2", + "pin-utils", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "web-sys" version = "0.3.64" @@ -6786,6 +6848,23 @@ version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +[[package]] +name = "websocket" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" +dependencies = [ + "futures-channel", + "futures-util", + "http", + "httparse", + "js-sys", + "thiserror", + "tokio", + "tokio-tungstenite", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "webview2-com" version = "0.19.1" @@ -7172,7 +7251,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 850b0fa8c7..9aa9052e04 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -40,8 +40,12 @@ bytes.workspace = true tracing.workspace = true lib-dispatch = { path = "../../rust-lib/lib-dispatch", features = ["use_serde"] } flowy-core = { path = "../../rust-lib/flowy-core", features = ["rev-sqlite", "ts"] } -flowy-error = { path = "../../rust-lib/flowy-error", features = ["impl_from_sqlite", "impl_from_dispatch_error", "impl_from_appflowy_cloud", "impl_from_reqwest", "impl_from_serde"] } -flowy-notification = { path = "../../rust-lib/flowy-notification", features = ["ts"] } +flowy-user = { path = "../../rust-lib/flowy-user", features = ["tauri_ts"] } +flowy-config = { path = "../../rust-lib/flowy-config", features = ["tauri_ts"] } +flowy-date = { path = "../../rust-lib/flowy-date", features = ["tauri_ts"] } +flowy-error = { path = "../../rust-lib/flowy-error", features = ["impl_from_sqlite", "impl_from_dispatch_error", "impl_from_appflowy_cloud", "impl_from_reqwest", "impl_from_serde", "tauri_ts"] } +flowy-document = { path = "../../rust-lib/flowy-document", features = ["tauri_ts"] } +flowy-notification = { path = "../../rust-lib/flowy-notification", features = ["tauri_ts"] } uuid = "1.5.0" [features] @@ -58,7 +62,7 @@ custom-protocol = ["tauri/custom-protocol"] # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ee3abdb27a2d056e7399b486354d26e802720c00" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "69c69f6474eaa531fd822e9353cc5955b98e45eb" } # Please use the following script to update collab. # Working directory: frontend # @@ -68,10 +72,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ee3 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3eef93f35f606edef2541888cb91cd6686d77225" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3eef93f35f606edef2541888cb91cd6686d77225" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3eef93f35f606edef2541888cb91cd6686d77225" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3eef93f35f606edef2541888cb91cd6686d77225" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3eef93f35f606edef2541888cb91cd6686d77225" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3eef93f35f606edef2541888cb91cd6686d77225" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3eef93f35f606edef2541888cb91cd6686d77225" } \ No newline at end of file +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } diff --git a/frontend/appflowy_tauri/src-tauri/src/request.rs b/frontend/appflowy_tauri/src-tauri/src/request.rs index 4f88885a51..029e71c18c 100644 --- a/frontend/appflowy_tauri/src-tauri/src/request.rs +++ b/frontend/appflowy_tauri/src-tauri/src/request.rs @@ -40,6 +40,6 @@ pub async fn invoke_request( let request: AFPluginRequest = request.into(); let state: State = app_handler.state(); let dispatcher = state.inner().dispatcher(); - let response = AFPluginDispatcher::async_send(dispatcher, request).await; + let response = AFPluginDispatcher::async_send(dispatcher.as_ref(), request).await; response.into() } diff --git a/frontend/appflowy_web/.eslintignore b/frontend/appflowy_web/.eslintignore new file mode 100644 index 0000000000..e0ff674834 --- /dev/null +++ b/frontend/appflowy_web/.eslintignore @@ -0,0 +1,7 @@ +src/services +src/styles +node_modules/ +dist/ +src-tauri/ +.eslintrc.cjs +tsconfig.json \ No newline at end of file diff --git a/frontend/appflowy_web/.gitignore b/frontend/appflowy_web/.gitignore index aa0740f9f3..d347429756 100644 --- a/frontend/appflowy_web/.gitignore +++ b/frontend/appflowy_web/.gitignore @@ -23,4 +23,7 @@ dist-ssr *.sln *.sw? -appflowy-wasm/target \ No newline at end of file +wasm-libs/**/target +**/src/services/backend/models/ +**/src/services/backend/events/ +**/src/appflowy_app/i18n/translations/ diff --git a/frontend/appflowy_web/.prettierignore b/frontend/appflowy_web/.prettierignore new file mode 100644 index 0000000000..d515c1c2f2 --- /dev/null +++ b/frontend/appflowy_web/.prettierignore @@ -0,0 +1,19 @@ +.DS_Store +node_modules +/build +/public +/.svelte-kit +/package +/.vscode +.env +.env.* +!.env.example + +# rust and generated ts code +/src-tauri +/src/services + +# Ignore files for PNPM, NPM and YARN +pnpm-lock.yaml +package-lock.json +yarn.lock diff --git a/frontend/appflowy_web/.prettierrc.cjs b/frontend/appflowy_web/.prettierrc.cjs new file mode 100644 index 0000000000..f283db53a2 --- /dev/null +++ b/frontend/appflowy_web/.prettierrc.cjs @@ -0,0 +1,20 @@ +module.exports = { + arrowParens: 'always', + bracketSpacing: true, + endOfLine: 'lf', + htmlWhitespaceSensitivity: 'css', + insertPragma: false, + jsxBracketSameLine: false, + jsxSingleQuote: true, + printWidth: 121, + plugins: [require('prettier-plugin-tailwindcss')], + proseWrap: 'preserve', + quoteProps: 'as-needed', + requirePragma: false, + semi: true, + singleQuote: true, + tabWidth: 2, + trailingComma: 'es5', + useTabs: false, + vueIndentScriptAndStyle: false, +}; diff --git a/frontend/appflowy_web/README.md b/frontend/appflowy_web/README.md index 3d801cfa42..b92a4c4960 100644 --- a/frontend/appflowy_web/README.md +++ b/frontend/appflowy_web/README.md @@ -20,4 +20,26 @@ pnpm run build # generate wasm pnpm run wasm +``` + + + +## Run tests in Chrome + +> Before executing the test, you need to install the [Chrome Driver](https://chromedriver.chromium.org/downloads). If +> you are using a Mac, you can easily install it using Homebrew. +> +> ```shell +> brew install chromedriver +> ``` + + +Go to `frontend/appflowy_web/wasm-libs` and run: +```shell +wasm-pack test --chrome +``` + +Run tests in headless Chrome +```shell +wasm-pack test --headless --chrome ``` \ No newline at end of file diff --git a/frontend/appflowy_web/appflowy-wasm/Cargo.lock b/frontend/appflowy_web/appflowy-wasm/Cargo.lock deleted file mode 100644 index 5a0da8efe2..0000000000 --- a/frontend/appflowy_web/appflowy-wasm/Cargo.lock +++ /dev/null @@ -1,2042 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "appflowy-wasm" -version = "0.1.0" -dependencies = [ - "flowy-notification", - "lazy_static", - "lib-dispatch", - "parking_lot", - "serde", - "tracing", - "tracing-core", - "tracing-wasm", - "wasm-bindgen", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "backtrace" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bstr" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "bumpalo" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" - -[[package]] -name = "bytes" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" -dependencies = [ - "serde", -] - -[[package]] -name = "cc" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "windows-targets 0.48.5", -] - -[[package]] -name = "chrono-tz" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d7b79e99bfaa0d47da0687c43aa3b7381938a62ad3a6498599039321f660b7" -dependencies = [ - "chrono", - "chrono-tz-build", - "phf 0.11.2", -] - -[[package]] -name = "chrono-tz-build" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f" -dependencies = [ - "parse-zoneinfo", - "phf 0.11.2", - "phf_codegen", -] - -[[package]] -name = "cmd_lib" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f4cbdcab51ca635c5b19c85ece4072ea42e0d2360242826a6fc96fb11f0d40" -dependencies = [ - "cmd_lib_macros", - "env_logger", - "faccess", - "lazy_static", - "log", - "os_pipe", -] - -[[package]] -name = "cmd_lib_macros" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae881960f7e2a409f91ef0b1c09558cf293031a1d6e8b45f908311f2a43f5fdf" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "console" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "regex", - "terminal_size", - "unicode-width", - "winapi", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "cpufeatures" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" -dependencies = [ - "libc", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if", - "hashbrown", - "lock_api", - "once_cell", - "parking_lot_core", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "deunicode" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae2a35373c5c74340b79ae6780b498b2b183915ec5dacf263aac5a099bf485a" - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "dyn-clone" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" - -[[package]] -name = "either" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "env_logger" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "faccess" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ae66425802d6a903e268ae1a08b8c38ba143520f227a205edf4e9c7e3e26d5" -dependencies = [ - "bitflags 1.3.2", - "libc", - "winapi", -] - -[[package]] -name = "fancy-regex" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0678ab2d46fa5195aaf59ad034c083d351377d4af57f3e073c074d0da3e3c766" -dependencies = [ - "bit-set", - "regex", -] - -[[package]] -name = "fastrand" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" - -[[package]] -name = "flowy-ast" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "flowy-codegen" -version = "0.1.0" -dependencies = [ - "cmd_lib", - "console", - "fancy-regex", - "flowy-ast", - "itertools", - "lazy_static", - "log", - "phf 0.8.0", - "protoc-bin-vendored", - "protoc-rust", - "quote", - "serde", - "serde_json", - "similar", - "syn 1.0.109", - "tera", - "toml", - "walkdir", -] - -[[package]] -name = "flowy-derive" -version = "0.1.0" -dependencies = [ - "dashmap", - "flowy-ast", - "flowy-codegen", - "lazy_static", - "proc-macro2", - "quote", - "serde_json", - "syn 1.0.109", - "walkdir", -] - -[[package]] -name = "flowy-notification" -version = "0.1.0" -dependencies = [ - "bytes", - "flowy-codegen", - "flowy-derive", - "lazy_static", - "lib-dispatch", - "protobuf", - "serde", - "tracing", -] - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.47", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - -[[package]] -name = "globset" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "globwalk" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" -dependencies = [ - "bitflags 1.3.2", - "ignore", - "walkdir", -] - -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" - -[[package]] -name = "hermit-abi" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" - -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "humansize" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" -dependencies = [ - "libm", -] - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "iana-time-zone" -version = "0.1.59" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "idna" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "ignore" -version = "0.4.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747ad1b4ae841a78e8aba0d63adbfbeaea26b517b63705d47856b73015d27060" -dependencies = [ - "crossbeam-deque", - "globset", - "log", - "memchr", - "regex-automata", - "same-file", - "walkdir", - "winapi-util", -] - -[[package]] -name = "is-terminal" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" - -[[package]] -name = "js-sys" -version = "0.3.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "lib-dispatch" -version = "0.1.0" -dependencies = [ - "bytes", - "derivative", - "dyn-clone", - "futures", - "futures-channel", - "futures-core", - "futures-util", - "getrandom 0.2.11", - "nanoid", - "parking_lot", - "pin-project", - "protobuf", - "thread-id", - "tokio", - "tracing", - "validator", - "wasm-bindgen", -] - -[[package]] -name = "libc" -version = "0.2.151" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" - -[[package]] -name = "libm" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" - -[[package]] -name = "linux-raw-sys" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" - -[[package]] -name = "lock_api" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "memchr" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - -[[package]] -name = "nanoid" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" -dependencies = [ - "rand 0.8.5", -] - -[[package]] -name = "num-traits" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "os_pipe" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.4.1", - "smallvec", - "windows-targets 0.48.5", -] - -[[package]] -name = "parse-zoneinfo" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" -dependencies = [ - "regex", -] - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pest" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" -dependencies = [ - "memchr", - "thiserror", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn 2.0.47", -] - -[[package]] -name = "pest_meta" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" -dependencies = [ - "once_cell", - "pest", - "sha2", -] - -[[package]] -name = "phf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" -dependencies = [ - "phf_macros", - "phf_shared 0.8.0", - "proc-macro-hack", -] - -[[package]] -name = "phf" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" -dependencies = [ - "phf_shared 0.11.2", -] - -[[package]] -name = "phf_codegen" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" -dependencies = [ - "phf_generator 0.11.2", - "phf_shared 0.11.2", -] - -[[package]] -name = "phf_generator" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" -dependencies = [ - "phf_shared 0.8.0", - "rand 0.7.3", -] - -[[package]] -name = "phf_generator" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" -dependencies = [ - "phf_shared 0.11.2", - "rand 0.8.5", -] - -[[package]] -name = "phf_macros" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" -dependencies = [ - "phf_generator 0.8.0", - "phf_shared 0.8.0", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "phf_shared" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" -dependencies = [ - "siphasher", -] - -[[package]] -name = "phf_shared" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pin-project" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.47", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - -[[package]] -name = "proc-macro2" -version = "1.0.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "protobuf" -version = "2.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" - -[[package]] -name = "protobuf-codegen" -version = "2.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "033460afb75cf755fcfc16dfaed20b86468082a2ea24e05ac35ab4a099a017d6" -dependencies = [ - "protobuf", -] - -[[package]] -name = "protoc" -version = "2.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0218039c514f9e14a5060742ecd50427f8ac4f85a6dc58f2ddb806e318c55ee" -dependencies = [ - "log", - "which", -] - -[[package]] -name = "protoc-bin-vendored" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "005ca8623e5633e298ad1f917d8be0a44bcf406bf3cde3b80e63003e49a3f27d" -dependencies = [ - "protoc-bin-vendored-linux-aarch_64", - "protoc-bin-vendored-linux-ppcle_64", - "protoc-bin-vendored-linux-x86_32", - "protoc-bin-vendored-linux-x86_64", - "protoc-bin-vendored-macos-x86_64", - "protoc-bin-vendored-win32", -] - -[[package]] -name = "protoc-bin-vendored-linux-aarch_64" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb9fc9cce84c8694b6ea01cc6296617b288b703719b725b8c9c65f7c5874435" - -[[package]] -name = "protoc-bin-vendored-linux-ppcle_64" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d2a07dcf7173a04d49974930ccbfb7fd4d74df30ecfc8762cf2f895a094516" - -[[package]] -name = "protoc-bin-vendored-linux-x86_32" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54fef0b04fcacba64d1d80eed74a20356d96847da8497a59b0a0a436c9165b0" - -[[package]] -name = "protoc-bin-vendored-linux-x86_64" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8782f2ce7d43a9a5c74ea4936f001e9e8442205c244f7a3d4286bd4c37bc924" - -[[package]] -name = "protoc-bin-vendored-macos-x86_64" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5de656c7ee83f08e0ae5b81792ccfdc1d04e7876b1d9a38e6876a9e09e02537" - -[[package]] -name = "protoc-bin-vendored-win32" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9653c3ed92974e34c5a6e0a510864dab979760481714c172e0a34e437cb98804" - -[[package]] -name = "protoc-rust" -version = "2.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22f8a182bb17c485f20bdc4274a8c39000a61024cfe461c799b50fec77267838" -dependencies = [ - "protobuf", - "protobuf-codegen", - "protoc", - "tempfile", -] - -[[package]] -name = "quote" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", - "rand_pcg", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.11", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "regex" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustix" -version = "0.38.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" -dependencies = [ - "bitflags 2.4.1", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "ryu" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "serde" -version = "1.0.194" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.194" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.47", -] - -[[package]] -name = "serde_json" -version = "1.0.111" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "similar" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad1d488a557b235fc46dae55512ffbfc429d2482b08b4d9435ab07384ca8aec" - -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "slug" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4" -dependencies = [ - "deunicode", - "wasm-bindgen", -] - -[[package]] -name = "smallvec" -version = "1.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1726efe18f42ae774cc644f330953a5e7b3c3003d3edcecf18850fe9d4dd9afb" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tempfile" -version = "3.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall 0.4.1", - "rustix", - "windows-sys", -] - -[[package]] -name = "tera" -version = "1.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "970dff17c11e884a4a09bc76e3a17ef71e01bb13447a11e85226e254fe6d10b8" -dependencies = [ - "chrono", - "chrono-tz", - "globwalk", - "humansize", - "lazy_static", - "percent-encoding", - "pest", - "pest_derive", - "rand 0.8.5", - "regex", - "serde", - "serde_json", - "slug", - "unic-segment", -] - -[[package]] -name = "termcolor" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "terminal_size" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "thiserror" -version = "1.0.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.47", -] - -[[package]] -name = "thread-id" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" -dependencies = [ - "libc", - "redox_syscall 0.1.57", - "winapi", -] - -[[package]] -name = "thread_local" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.35.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" -dependencies = [ - "backtrace", - "pin-project-lite", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.47", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "sharded-slab", - "thread_local", - "tracing-core", -] - -[[package]] -name = "tracing-wasm" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" -dependencies = [ - "tracing", - "tracing-subscriber", - "wasm-bindgen", -] - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - -[[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-segment" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" -dependencies = [ - "unic-ucd-segment", -] - -[[package]] -name = "unic-ucd-segment" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - -[[package]] -name = "url" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" -dependencies = [ - "form_urlencoded", - "idna 0.5.0", - "percent-encoding", -] - -[[package]] -name = "validator" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b92f40481c04ff1f4f61f304d61793c7b56ff76ac1469f1beb199b1445b253bd" -dependencies = [ - "idna 0.4.0", - "lazy_static", - "regex", - "serde", - "serde_derive", - "serde_json", - "url", -] - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "walkdir" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.47", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.47", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" -dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" diff --git a/frontend/appflowy_web/appflowy-wasm/Cargo.toml b/frontend/appflowy_web/appflowy-wasm/Cargo.toml deleted file mode 100644 index a618399ea4..0000000000 --- a/frontend/appflowy_web/appflowy-wasm/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "appflowy-wasm" -version = "0.1.0" -edition = "2021" - -[lib] -crate-type = ["cdylib", "rlib"] -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -wasm-bindgen = { version = "0.2.89" } -lazy_static = "1.4.0" -lib-dispatch = { workspace = true, features = ["single_thread"] } -parking_lot.workspace = true -tracing.workspace = true -tracing-core = { version = "0.1.32" } -tracing-wasm = "0.2.1" -flowy-notification = { workspace = true, features = ["ts"] } -serde.workspace = true - -[workspace.dependencies] -lib-dispatch = { path = "../../rust-lib/lib-dispatch" } -parking_lot = { version = "0.12.1" } -tracing = { version = "0.1.22" } -flowy-notification = { path = "../../rust-lib/flowy-notification" } -serde = { version = "1.0.194", features = ["derive"] } \ No newline at end of file diff --git a/frontend/appflowy_web/appflowy-wasm/src/lib.rs b/frontend/appflowy_web/appflowy-wasm/src/lib.rs deleted file mode 100644 index f54a699fdb..0000000000 --- a/frontend/appflowy_web/appflowy-wasm/src/lib.rs +++ /dev/null @@ -1,60 +0,0 @@ -use crate::notification::TSNotificationSender; -use flowy_notification::{register_notification_sender, unregister_all_notification_sender}; - -pub mod notification; -pub mod request; - -use crate::request::{MutexDispatcher, WasmRequest}; -use lazy_static::lazy_static; -use lib_dispatch::prelude::AFPluginDispatcher; -use lib_dispatch::runtime::AFPluginRuntime; -use std::sync::Arc; -use tracing::trace; -use wasm_bindgen::prelude::wasm_bindgen; -use wasm_bindgen::JsValue; - -lazy_static! { - pub(crate) static ref DISPATCHER: MutexDispatcher = MutexDispatcher::new(); -} - -#[wasm_bindgen] -pub fn init_sdk(_data: String) -> i64 { - let runtime = Arc::new(AFPluginRuntime::new().unwrap()); - *DISPATCHER.0.lock() = Some(Arc::new(AFPluginDispatcher::new(runtime, vec![]))); - 0 -} - -#[wasm_bindgen] -pub fn init_tracing() { - tracing_wasm::set_as_global_default(); -} - -#[wasm_bindgen] -pub fn async_event(name: String, payload: Vec) { - trace!("[WASM]: receives event: {}", name); - - let dispatcher = DISPATCHER.0.lock().as_ref().unwrap().clone(); - AFPluginDispatcher::boxed_async_send_with_callback( - dispatcher, - WasmRequest::new(name, payload), - |_| Box::pin(async {}), - ); -} - -#[wasm_bindgen] -extern "C" { - #[wasm_bindgen(js_namespace = console)] - pub fn log(s: &str); - #[wasm_bindgen(js_namespace = window)] - fn onFlowyNotify(event_name: &str, payload: JsValue); -} - -#[wasm_bindgen] -pub fn register_listener() { - unregister_all_notification_sender(); - register_notification_sender(TSNotificationSender::new()); -} - -pub fn on_event(event_name: &str, args: JsValue) { - onFlowyNotify(event_name, args); -} diff --git a/frontend/appflowy_web/appflowy-wasm/src/request.rs b/frontend/appflowy_web/appflowy-wasm/src/request.rs deleted file mode 100644 index f54831a979..0000000000 --- a/frontend/appflowy_web/appflowy-wasm/src/request.rs +++ /dev/null @@ -1,64 +0,0 @@ - -use lib_dispatch::prelude::{AFPluginDispatcher, AFPluginRequest}; - -use parking_lot::Mutex; -use std::sync::Arc; - -use wasm_bindgen::prelude::wasm_bindgen; - -pub(crate) struct MutexDispatcher(pub Arc>>>); - -impl MutexDispatcher { - pub(crate) fn new() -> Self { - Self(Arc::new(Mutex::new(None))) - } -} - -unsafe impl Sync for MutexDispatcher {} -unsafe impl Send for MutexDispatcher {} - -#[wasm_bindgen] -pub struct WasmRequest { - name: String, - payload: Vec, -} - -impl WasmRequest { - pub fn new(name: String, payload: Vec) -> Self { - Self { name, payload } - } -} - -impl From for AFPluginRequest { - fn from(request: WasmRequest) -> Self { - AFPluginRequest::new(request.name).payload(request.payload) - } -} - -#[wasm_bindgen] -impl WasmRequest { - pub fn name(&self) -> String { - self.name.clone() - } - - // Setter for the name - #[wasm_bindgen(setter)] - pub fn set_name(&mut self, name: String) { - self.name = name; - } - - // Getter for payload that returns a pointer to the data - pub fn get_payload_ptr(&self) -> *const u8 { - self.payload.as_ptr() - } - - // Getter for the length of the payload - pub fn get_payload_len(&self) -> usize { - self.payload.len() - } - - // Setter or method to update payload - pub fn set_payload(&mut self, payload: &[u8]) { - self.payload = payload.to_vec(); - } -} diff --git a/frontend/appflowy_web/package.json b/frontend/appflowy_web/package.json index 9d986f5e1e..97789f0f82 100644 --- a/frontend/appflowy_web/package.json +++ b/frontend/appflowy_web/package.json @@ -4,17 +4,22 @@ "version": "0.0.0", "type": "module", "scripts": { - "wasm": "cd appflowy-wasm && wasm-pack build", - "dev": "pnpm run wasm && vite", + "build_release_wasm": "cd wasm-libs/af-wasm && wasm-pack build", + "build_dev_wasm": "cd wasm-libs/af-wasm && wasm-pack build --features=\"localhost_dev\"", + "dev": "pnpm run build_dev_wasm && vite", "build": "tsc && vite build", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "clean": "cargo make --cwd .. web_clean", "preview": "vite preview" }, "dependencies": { "events": "^3.3.0", "google-protobuf": "^3.21.2", + "protoc-gen-ts": "^0.8.5", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "ts-results": "^3.3.0", + "uuid": "^9.0.1" }, "devDependencies": { "@types/events": "^3.0.3", diff --git a/frontend/appflowy_web/pnpm-lock.yaml b/frontend/appflowy_web/pnpm-lock.yaml index 87e4fce1e1..19299b3caf 100644 --- a/frontend/appflowy_web/pnpm-lock.yaml +++ b/frontend/appflowy_web/pnpm-lock.yaml @@ -7,12 +7,21 @@ dependencies: google-protobuf: specifier: ^3.21.2 version: 3.21.2 + protoc-gen-ts: + specifier: ^0.8.5 + version: 0.8.7 react: specifier: ^18.2.0 version: 18.2.0 react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) + ts-results: + specifier: ^3.3.0 + version: 3.3.0 + uuid: + specifier: ^9.0.1 + version: 9.0.1 devDependencies: '@types/events': @@ -1669,6 +1678,11 @@ packages: engines: {node: '>= 0.8.0'} dev: true + /protoc-gen-ts@0.8.7: + resolution: {integrity: sha512-jr4VJey2J9LVYCV7EVyVe53g1VMw28cCmYJhBe5e3YX5wiyiDwgxWxeDf9oTqAe4P1bN/YGAkW2jhlH8LohwiQ==} + hasBin: true + dev: false + /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -1836,6 +1850,10 @@ packages: typescript: 5.2.2 dev: true + /ts-results@3.3.0: + resolution: {integrity: sha512-FWqxGX2NHp5oCyaMd96o2y2uMQmSu8Dey6kvyuFdRJ2AzfmWo3kWa4UsPlCGlfQ/qu03m09ZZtppMoY8EMHuiA==} + dev: false + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -1875,6 +1893,11 @@ packages: punycode: 2.3.1 dev: true + /uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + dev: false + /vite-plugin-wasm@3.3.0(vite@5.0.8): resolution: {integrity: sha512-tVhz6w+W9MVsOCHzxo6SSMSswCeIw4HTrXEi6qL3IRzATl83jl09JVO1djBqPSwfjgnpVHNLYcaMbaDX5WB/pg==} peerDependencies: diff --git a/frontend/appflowy_web/src/App.tsx b/frontend/appflowy_web/src/App.tsx index 65086f5fe3..72ffe19fdb 100644 --- a/frontend/appflowy_web/src/App.tsx +++ b/frontend/appflowy_web/src/App.tsx @@ -1,19 +1,17 @@ import reactLogo from "./assets/react.svg"; import viteLogo from "/vite.svg"; import "./App.css"; -import {async_event, init_sdk, init_tracing} from "../appflowy-wasm/pkg/appflowy_wasm"; import { useEffect } from "react"; -import { initApp } from "./application/init_app.ts"; -import { subscribeNotification } from "./application/notification.ts"; +import { initApp } from "@/application/app.ts"; +import { subscribeNotification } from "@/application/notification.ts"; import { NotifyArgs } from "./@types/global"; +import {init_tracing_log, init_wasm_core} from "../wasm-libs/af-wasm/pkg"; +import { v4 as uuidv4 } from 'uuid'; +import {AddUserPB, UserWasmEventAddUser} from "@/services/backend/events/af-user"; - -async function runWasm() { - init_tracing(); - init_sdk("sdk config"); // Call your exported Wasm function. -} -runWasm(); - +init_tracing_log(); +// FIXME: handle the promise that init_wasm_core returns +init_wasm_core(); function App() { useEffect(() => { @@ -24,9 +22,13 @@ function App() { }, []); const handleClick = async () => { - const payload = new TextEncoder().encode("someString"); - const res = await async_event("add", payload); - console.log(res); + let email = `${uuidv4()}@example.com`; + let password = "AppFlowy!2024"; + const payload = AddUserPB.fromObject({email: email, password: password }) + let result = await UserWasmEventAddUser(payload); + if (!result.ok) { + + } }; return ( diff --git a/frontend/appflowy_web/src/application/app.ts b/frontend/appflowy_web/src/application/app.ts new file mode 100644 index 0000000000..918d5583b1 --- /dev/null +++ b/frontend/appflowy_web/src/application/app.ts @@ -0,0 +1,35 @@ + + +import { initEventBus } from "./event_bus.ts"; +import {async_event, register_listener} from "../../wasm-libs/af-wasm/pkg"; + +export function initApp() { + initEventBus(); + register_listener(); +} + +type InvokeArgs = Record; + +export async function invoke(cmd: string, args?: InvokeArgs): Promise { + switch (cmd) { + case "invoke_request": + const request = args?.request as { ty?: unknown, payload?: unknown } | undefined; + if (!request || typeof request !== 'object') { + throw new Error("Invalid or missing 'request' argument in 'invoke_request'"); + } + + const { ty, payload } = request; + + if (typeof ty !== 'string') { + throw new Error("Invalid 'ty' in request for 'invoke_request'"); + } + + if (!(payload instanceof Array)) { + throw new Error("Invalid 'payload' in request for 'invoke_request'"); + } + + return async_event(ty, new Uint8Array(payload)); + default: + throw new Error(`Unknown command: ${cmd}`); + } +} diff --git a/frontend/appflowy_web/src/application/init_app.ts b/frontend/appflowy_web/src/application/init_app.ts deleted file mode 100644 index 0ab89d63d4..0000000000 --- a/frontend/appflowy_web/src/application/init_app.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { initEventBus } from "./event_bus.ts"; -import { register_listener } from "../../appflowy-wasm/pkg"; - -export function initApp() { - initEventBus(); - register_listener(); -} diff --git a/frontend/appflowy_web/src/services/backend/index.ts b/frontend/appflowy_web/src/services/backend/index.ts new file mode 100644 index 0000000000..1b3fa9424a --- /dev/null +++ b/frontend/appflowy_web/src/services/backend/index.ts @@ -0,0 +1,2 @@ +export * from "./models/af-user"; +export * from "./models/flowy-error"; diff --git a/frontend/appflowy_web/tsconfig.json b/frontend/appflowy_web/tsconfig.json index 21ecd083eb..67609fa96f 100644 --- a/frontend/appflowy_web/tsconfig.json +++ b/frontend/appflowy_web/tsconfig.json @@ -19,9 +19,13 @@ "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, - "typeRoots": ["./node_modules/@types", "./src/@types"], + + "baseUrl": "./", + "paths": { + "@/*": ["src/*"], + } }, - "include": ["src"], + "include": ["src", "vite.config.ts"], "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/frontend/appflowy_web/vite.config.ts b/frontend/appflowy_web/vite.config.ts index f35af5b212..49a8c2b3ad 100644 --- a/frontend/appflowy_web/vite.config.ts +++ b/frontend/appflowy_web/vite.config.ts @@ -5,4 +5,11 @@ import wasm from "vite-plugin-wasm"; // https://vitejs.dev/config/ export default defineConfig({ plugins: [react(), wasm()], + resolve: { + alias: [ + { find: 'src/', replacement: `${__dirname}/src/` }, + { find: '@/', replacement: `${__dirname}/src/` }, + { find: '$app/', replacement: `${__dirname}/src/application/` }, + ], + }, }) diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock new file mode 100644 index 0000000000..4eae41bedc --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -0,0 +1,4892 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "accessory" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "850bb534b9dc04744fbbb71d30ad6d25a7e4cf6dc33e223c81ef3a92ebab4e0b" +dependencies = [ + "macroific", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "af-persistence" +version = "0.1.0" +dependencies = [ + "anyhow", + "flowy-error", + "futures-util", + "indexed_db_futures", + "js-sys", + "serde", + "serde_json", + "thiserror", + "tokio", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "af-user" +version = "0.1.0" +dependencies = [ + "af-persistence", + "anyhow", + "bytes", + "collab", + "collab-entity", + "collab-integrate", + "collab-user", + "flowy-codegen", + "flowy-derive", + "flowy-error", + "flowy-user-pub", + "lib-dispatch", + "lib-infra", + "protobuf", + "strum_macros 0.25.3", + "tokio", + "tracing", + "wasm-bindgen-futures", +] + +[[package]] +name = "af-wasm" +version = "0.1.0" +dependencies = [ + "af-user", + "collab", + "collab-integrate", + "flowy-document", + "flowy-error", + "flowy-notification", + "flowy-server", + "flowy-server-pub", + "flowy-user-pub", + "js-sys", + "lazy_static", + "lib-dispatch", + "lib-infra", + "parking_lot 0.12.1", + "serde", + "serde-wasm-bindgen", + "tokio", + "tokio-stream", + "tracing", + "tracing-core", + "tracing-wasm", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "again" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05802a5ad4d172eaf796f7047b42d0af9db513585d16d4169660a21613d34b93" +dependencies = [ + "log", + "rand 0.7.3", + "wasm-timer", +] + +[[package]] +name = "ahash" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +dependencies = [ + "cfg-if", + "getrandom 0.2.12", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" + +[[package]] +name = "app-error" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" +dependencies = [ + "anyhow", + "bincode", + "getrandom 0.2.12", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tokio", + "url", + "uuid", +] + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "async-trait" +version = "0.1.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "atomic_refcell" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41e67cd8309bbd06cd603a9e693a784ac2e5d1e955f11286e355089fcab3047c" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.65.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.48", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brotli" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bstr" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +dependencies = [ + "serde", +] + +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.0", +] + +[[package]] +name = "chrono-tz" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91d7b79e99bfaa0d47da0687c43aa3b7381938a62ad3a6498599039321f660b7" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf 0.11.2", +] + +[[package]] +name = "chrono-tz-build" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f" +dependencies = [ + "parse-zoneinfo", + "phf 0.11.2", + "phf_codegen 0.11.2", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clang-sys" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "client-api" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" +dependencies = [ + "again", + "anyhow", + "app-error", + "async-trait", + "bincode", + "brotli", + "bytes", + "chrono", + "collab", + "collab-entity", + "database-entity", + "futures-core", + "futures-util", + "getrandom 0.2.12", + "gotrue", + "gotrue-entity", + "mime", + "mime_guess", + "parking_lot 0.12.1", + "prost", + "realtime-entity", + "realtime-protocol", + "reqwest", + "scraper 0.17.1", + "serde", + "serde_json", + "serde_repr", + "shared-entity", + "thiserror", + "tokio", + "tokio-retry", + "tokio-stream", + "tracing", + "url", + "uuid", + "wasm-bindgen-futures", + "websocket", + "yrs", +] + +[[package]] +name = "cmd_lib" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5f4cbdcab51ca635c5b19c85ece4072ea42e0d2360242826a6fc96fb11f0d40" +dependencies = [ + "cmd_lib_macros", + "env_logger", + "faccess", + "lazy_static", + "log", + "os_pipe", +] + +[[package]] +name = "cmd_lib_macros" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae881960f7e2a409f91ef0b1c09558cf293031a1d6e8b45f908311f2a43f5fdf" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "collab" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" +dependencies = [ + "anyhow", + "async-trait", + "bincode", + "bytes", + "js-sys", + "parking_lot 0.12.1", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "web-sys", + "yrs", +] + +[[package]] +name = "collab-document" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" +dependencies = [ + "anyhow", + "collab", + "collab-entity", + "getrandom 0.2.12", + "nanoid", + "parking_lot 0.12.1", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "collab-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" +dependencies = [ + "anyhow", + "bytes", + "collab", + "serde", + "serde_json", + "serde_repr", + "uuid", +] + +[[package]] +name = "collab-folder" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" +dependencies = [ + "anyhow", + "chrono", + "collab", + "collab-entity", + "parking_lot 0.12.1", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "collab-integrate" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "collab", + "collab-entity", + "collab-plugins", + "lib-infra", + "parking_lot 0.12.1", + "serde", + "serde_json", + "tokio", + "tracing", +] + +[[package]] +name = "collab-plugins" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" +dependencies = [ + "anyhow", + "async-stream", + "async-trait", + "bincode", + "bytes", + "chrono", + "collab", + "collab-entity", + "futures", + "futures-util", + "getrandom 0.2.12", + "indexed_db_futures", + "js-sys", + "lazy_static", + "parking_lot 0.12.1", + "rocksdb", + "serde", + "serde_json", + "similar 2.4.0", + "smallvec", + "thiserror", + "tokio", + "tokio-retry", + "tokio-stream", + "tracing", + "tracing-wasm", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "yrs", +] + +[[package]] +name = "collab-user" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" +dependencies = [ + "anyhow", + "collab", + "collab-entity", + "parking_lot 0.12.1", + "serde", + "serde_json", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "console" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "regex", + "terminal_size", + "unicode-width", + "winapi", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "cookie" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d606d0fba62e13cf04db20536c05cb7f13673c161cb47a47a82b9b9e7d3f1daa" +dependencies = [ + "cookie", + "idna 0.2.3", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "cssparser" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b3df4f93e5fbbe73ec01ec8d3f68bba73107993a5b1e7519273c32db9b0d5be" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa", + "phf 0.11.2", + "smallvec", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.48", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "data-encoding" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" + +[[package]] +name = "database-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" +dependencies = [ + "anyhow", + "app-error", + "bincode", + "chrono", + "collab-entity", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tracing", + "uuid", + "validator", +] + +[[package]] +name = "delegate-display" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98a85201f233142ac819bbf6226e36d0b5e129a47bd325084674261c82d4cd66" +dependencies = [ + "macroific", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "deunicode" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae2a35373c5c74340b79ae6780b498b2b183915ec5dacf263aac5a099bf485a" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "dtoa-short" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbaceec3c6e4211c79e7b1800fb9680527106beb2f9c51904a3210c03a448c74" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dyn-clone" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" + +[[package]] +name = "ego-tree" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591" + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "env_logger" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "faccess" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ae66425802d6a903e268ae1a08b8c38ba143520f227a205edf4e9c7e3e26d5" +dependencies = [ + "bitflags 1.3.2", + "libc", + "winapi", +] + +[[package]] +name = "fancy-regex" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0678ab2d46fa5195aaf59ad034c083d351377d4af57f3e073c074d0da3e3c766" +dependencies = [ + "bit-set", + "regex", +] + +[[package]] +name = "fancy-regex" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2" +dependencies = [ + "bit-set", + "regex", +] + +[[package]] +name = "fancy_constructor" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f71f317e4af73b2f8f608fac190c52eac4b1879d2145df1db2fe48881ca69435" +dependencies = [ + "macroific", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flowy-ast" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "flowy-codegen" +version = "0.1.0" +dependencies = [ + "cmd_lib", + "console", + "fancy-regex 0.10.0", + "flowy-ast", + "itertools", + "lazy_static", + "log", + "phf 0.8.0", + "protoc-bin-vendored", + "protoc-rust", + "quote", + "serde", + "serde_json", + "similar 1.3.0", + "syn 1.0.109", + "tera", + "toml", + "walkdir", +] + +[[package]] +name = "flowy-database-pub" +version = "0.1.0" +dependencies = [ + "anyhow", + "collab", + "collab-entity", + "lib-infra", +] + +[[package]] +name = "flowy-derive" +version = "0.1.0" +dependencies = [ + "dashmap", + "flowy-ast", + "flowy-codegen", + "lazy_static", + "proc-macro2", + "quote", + "serde_json", + "syn 1.0.109", + "walkdir", +] + +[[package]] +name = "flowy-document" +version = "0.1.0" +dependencies = [ + "anyhow", + "bytes", + "collab", + "collab-document", + "collab-entity", + "collab-integrate", + "collab-plugins", + "flowy-codegen", + "flowy-derive", + "flowy-document-pub", + "flowy-error", + "flowy-notification", + "flowy-storage", + "futures", + "getrandom 0.2.12", + "indexmap", + "lib-dispatch", + "lib-infra", + "lru", + "nanoid", + "parking_lot 0.12.1", + "protobuf", + "scraper 0.18.1", + "serde", + "serde_json", + "strum_macros 0.21.1", + "tokio", + "tokio-stream", + "tracing", + "uuid", + "validator", +] + +[[package]] +name = "flowy-document-pub" +version = "0.1.0" +dependencies = [ + "anyhow", + "collab", + "collab-document", + "flowy-error", + "lib-infra", +] + +[[package]] +name = "flowy-encrypt" +version = "0.1.0" +dependencies = [ + "aes-gcm", + "anyhow", + "base64 0.21.7", + "getrandom 0.2.12", + "hmac", + "pbkdf2 0.12.2", + "rand 0.8.5", + "sha2", +] + +[[package]] +name = "flowy-error" +version = "0.1.0" +dependencies = [ + "anyhow", + "bytes", + "client-api", + "collab-document", + "collab-plugins", + "fancy-regex 0.11.0", + "flowy-codegen", + "flowy-derive", + "lib-dispatch", + "protobuf", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "tokio", + "url", + "validator", +] + +[[package]] +name = "flowy-folder-pub" +version = "0.1.0" +dependencies = [ + "anyhow", + "collab", + "collab-entity", + "collab-folder", + "lib-infra", + "uuid", +] + +[[package]] +name = "flowy-notification" +version = "0.1.0" +dependencies = [ + "bytes", + "flowy-codegen", + "flowy-derive", + "lazy_static", + "lib-dispatch", + "protobuf", + "serde", + "tracing", +] + +[[package]] +name = "flowy-server" +version = "0.1.0" +dependencies = [ + "anyhow", + "bytes", + "chrono", + "client-api", + "collab", + "collab-document", + "collab-entity", + "collab-plugins", + "flowy-database-pub", + "flowy-document-pub", + "flowy-encrypt", + "flowy-error", + "flowy-folder-pub", + "flowy-server-pub", + "flowy-storage", + "flowy-user-pub", + "futures", + "futures-util", + "hex", + "hyper", + "lazy_static", + "lib-dispatch", + "lib-infra", + "mime_guess", + "parking_lot 0.12.1", + "postgrest", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-retry", + "tokio-stream", + "tokio-util", + "tracing", + "url", + "uuid", + "yrs", +] + +[[package]] +name = "flowy-server-pub" +version = "0.1.0" +dependencies = [ + "flowy-error", + "serde", + "serde_repr", +] + +[[package]] +name = "flowy-storage" +version = "0.1.0" +dependencies = [ + "async-trait", + "bytes", + "flowy-error", + "fxhash", + "lib-infra", + "mime", + "mime_guess", + "reqwest", + "serde", + "serde_json", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "flowy-user-pub" +version = "0.1.0" +dependencies = [ + "anyhow", + "base64 0.21.7", + "chrono", + "collab", + "collab-entity", + "flowy-error", + "flowy-folder-pub", + "lib-infra", + "serde", + "serde_json", + "serde_repr", + "tokio", + "tokio-stream", + "tracing", + "uuid", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags 1.3.2", + "ignore", + "walkdir", +] + +[[package]] +name = "gotrue" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" +dependencies = [ + "anyhow", + "futures-util", + "getrandom 0.2.12", + "gotrue-entity", + "infra", + "reqwest", + "serde", + "serde_json", + "tokio", + "tracing", +] + +[[package]] +name = "gotrue-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" +dependencies = [ + "anyhow", + "app-error", + "chrono", + "jsonwebtoken", + "lazy_static", + "serde", + "serde_json", +] + +[[package]] +name = "h2" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" + +[[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", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "html5ever" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humansize" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" +dependencies = [ + "libm", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "if_chain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" + +[[package]] +name = "ignore" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata", + "same-file", + "walkdir", + "winapi-util", +] + +[[package]] +name = "indexed_db_futures" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cc2083760572ee02385ab8b7c02c20925d2dd1f97a1a25a8737a238608f1152" +dependencies = [ + "accessory", + "cfg-if", + "delegate-display", + "fancy_constructor", + "js-sys", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown", + "serde", +] + +[[package]] +name = "infra" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" +dependencies = [ + "anyhow", + "reqwest", + "serde", + "serde_json", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is-terminal" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonwebtoken" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +dependencies = [ + "base64 0.21.7", + "pem", + "ring 0.16.20", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "lib-dispatch" +version = "0.1.0" +dependencies = [ + "bincode", + "bytes", + "derivative", + "dyn-clone", + "futures", + "futures-channel", + "futures-core", + "futures-util", + "getrandom 0.2.12", + "nanoid", + "parking_lot 0.12.1", + "pin-project", + "protobuf", + "serde", + "serde_json", + "serde_repr", + "thread-id", + "tokio", + "tracing", + "validator", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "lib-infra" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "atomic_refcell", + "bytes", + "chrono", + "futures-core", + "md5", + "pin-project", + "tempfile", + "tokio", + "tracing", + "validator", + "walkdir", + "zip", +] + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "libloading" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "librocksdb-sys" +version = "0.11.0+8.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" +dependencies = [ + "bindgen", + "bzip2-sys", + "cc", + "glob", + "libc", + "libz-sys", + "zstd-sys", +] + +[[package]] +name = "libz-sys" +version = "1.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "295c17e837573c8c821dbaeb3cceb3d745ad082f7572191409e69cbc1b3fd050" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "lru" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2c024b41519440580066ba82aab04092b333e09066a5eb86c7c4890df31f22" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "macroific" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05c00ac596022625d01047c421a0d97d7f09a18e429187b341c201cb631b9dd" +dependencies = [ + "macroific_attr_parse", + "macroific_core", + "macroific_macro", +] + +[[package]] +name = "macroific_attr_parse" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd94d5da95b30ae6e10621ad02340909346ad91661f3f8c0f2b62345e46a2f67" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "macroific_core" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13198c120864097a565ccb3ff947672d969932b7975ebd4085732c9f09435e55" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "macroific_macro" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c9853143cbed7f1e41dc39fee95f9b361bec65c8dc2a01bf609be01b61f5ae" +dependencies = [ + "macroific_attr_parse", + "macroific_core", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "markup5ever" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" +dependencies = [ + "log", + "phf 0.10.1", + "phf_codegen 0.10.0", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "nanoid" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" +dependencies = [ + "rand 0.8.5", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl" +version = "0.10.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" +dependencies = [ + "bitflags 2.4.2", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-src" +version = "300.2.1+3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fe476c29791a5ca0d1273c697e96085bbabbbea2ef7afd5617e78a4b40332d3" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "os_pipe" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] + +[[package]] +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest", + "hmac", + "password-hash", + "sha2", +] + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "pest_meta" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_shared 0.10.0", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros 0.11.2", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_codegen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.5", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" + +[[package]] +name = "polyval" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "postgrest" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a966c650b47a064e7082170b4be74fca08c088d893244fc4b70123e3c1f3ee7" +dependencies = [ + "reqwest", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "prettyplease" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +dependencies = [ + "proc-macro2", + "syn 2.0.48", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" +dependencies = [ + "bytes", + "heck 0.4.1", + "itertools", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.48", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "prost-types" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +dependencies = [ + "prost", +] + +[[package]] +name = "protobuf" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" + +[[package]] +name = "protobuf-codegen" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "033460afb75cf755fcfc16dfaed20b86468082a2ea24e05ac35ab4a099a017d6" +dependencies = [ + "protobuf", +] + +[[package]] +name = "protoc" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0218039c514f9e14a5060742ecd50427f8ac4f85a6dc58f2ddb806e318c55ee" +dependencies = [ + "log", + "which", +] + +[[package]] +name = "protoc-bin-vendored" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "005ca8623e5633e298ad1f917d8be0a44bcf406bf3cde3b80e63003e49a3f27d" +dependencies = [ + "protoc-bin-vendored-linux-aarch_64", + "protoc-bin-vendored-linux-ppcle_64", + "protoc-bin-vendored-linux-x86_32", + "protoc-bin-vendored-linux-x86_64", + "protoc-bin-vendored-macos-x86_64", + "protoc-bin-vendored-win32", +] + +[[package]] +name = "protoc-bin-vendored-linux-aarch_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb9fc9cce84c8694b6ea01cc6296617b288b703719b725b8c9c65f7c5874435" + +[[package]] +name = "protoc-bin-vendored-linux-ppcle_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d2a07dcf7173a04d49974930ccbfb7fd4d74df30ecfc8762cf2f895a094516" + +[[package]] +name = "protoc-bin-vendored-linux-x86_32" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54fef0b04fcacba64d1d80eed74a20356d96847da8497a59b0a0a436c9165b0" + +[[package]] +name = "protoc-bin-vendored-linux-x86_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8782f2ce7d43a9a5c74ea4936f001e9e8442205c244f7a3d4286bd4c37bc924" + +[[package]] +name = "protoc-bin-vendored-macos-x86_64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5de656c7ee83f08e0ae5b81792ccfdc1d04e7876b1d9a38e6876a9e09e02537" + +[[package]] +name = "protoc-bin-vendored-win32" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9653c3ed92974e34c5a6e0a510864dab979760481714c172e0a34e437cb98804" + +[[package]] +name = "protoc-rust" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22f8a182bb17c485f20bdc4274a8c39000a61024cfe461c799b50fec77267838" +dependencies = [ + "protobuf", + "protobuf-codegen", + "protoc", + "tempfile", +] + +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "publicsuffix" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" +dependencies = [ + "idna 0.3.0", + "psl-types", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.12", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "realtime-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" +dependencies = [ + "anyhow", + "bincode", + "bytes", + "collab", + "collab-entity", + "database-entity", + "prost", + "prost-build", + "protoc-bin-vendored", + "realtime-protocol", + "serde", + "serde_json", + "thiserror", + "tokio-tungstenite", + "websocket", + "yrs", +] + +[[package]] +name = "realtime-protocol" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" +dependencies = [ + "anyhow", + "bincode", + "collab", + "serde", + "thiserror", + "yrs", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "reqwest" +version = "0.11.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +dependencies = [ + "base64 0.21.7", + "bytes", + "cookie", + "cookie_store", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "mime_guess", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", + "winreg", +] + +[[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 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom 0.2.12", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "rocksdb" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" +dependencies = [ + "libc", + "librocksdb-sys", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +dependencies = [ + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "log", + "ring 0.17.7", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scraper" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c95a930e03325234c18c7071fd2b60118307e025d6fff3e12745ffbf63a3d29c" +dependencies = [ + "ahash", + "cssparser", + "ego-tree", + "getopts", + "html5ever", + "once_cell", + "selectors", + "smallvec", + "tendril", +] + +[[package]] +name = "scraper" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585480e3719b311b78a573db1c9d9c4c1f8010c2dee4cc59c2efe58ea4dbc3e1" +dependencies = [ + "ahash", + "cssparser", + "ego-tree", + "getopts", + "html5ever", + "once_cell", + "selectors", + "tendril", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "selectors" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06" +dependencies = [ + "bitflags 2.4.2", + "cssparser", + "derive_more", + "fxhash", + "log", + "new_debug_unreachable", + "phf 0.10.1", + "phf_codegen 0.10.0", + "precomputed-hash", + "servo_arc", + "smallvec", +] + +[[package]] +name = "serde" +version = "1.0.195" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.195" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_json" +version = "1.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "servo_arc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d036d71a959e00c77a63538b90a6c2390969f9772b096ea837205c6bd0491a44" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shared-entity" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" +dependencies = [ + "anyhow", + "app-error", + "chrono", + "collab-entity", + "database-entity", + "gotrue-entity", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "uuid", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "similar" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad1d488a557b235fc46dae55512ffbfc429d2482b08b4d9435ab07384ca8aec" + +[[package]] +name = "similar" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21" + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slug" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4" +dependencies = [ + "deunicode", + "wasm-bindgen", +] + +[[package]] +name = "smallstr" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b1aefdf380735ff8ded0b15f31aab05daf1f70216c01c02a12926badd1df9d" +dependencies = [ + "smallvec", +] + +[[package]] +name = "smallvec" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot 0.12.1", + "phf_shared 0.10.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro2", + "quote", +] + +[[package]] +name = "strum_macros" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.48", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.4.1", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "tera" +version = "1.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "970dff17c11e884a4a09bc76e3a17ef71e01bb13447a11e85226e254fe6d10b8" +dependencies = [ + "chrono", + "chrono-tz", + "globwalk", + "humansize", + "lazy_static", + "percent-encoding", + "pest", + "pest_derive", + "rand 0.8.5", + "regex", + "serde", + "serde_json", + "slug", + "unic-segment", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "thiserror" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "thread-id" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" +dependencies = [ + "libc", + "redox_syscall 0.1.57", + "winapi", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +dependencies = [ + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.35.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-retry" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" +dependencies = [ + "pin-project", + "rand 0.8.5", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "native-tls", + "tokio", + "tokio-native-tls", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "sharded-slab", + "thread_local", + "tracing-core", +] + +[[package]] +name = "tracing-wasm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" +dependencies = [ + "tracing", + "tracing-subscriber", + "wasm-bindgen", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "native-tls", + "rand 0.8.5", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" +dependencies = [ + "unic-ucd-segment", +] + +[[package]] +name = "unic-ucd-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna 0.5.0", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +dependencies = [ + "getrandom 0.2.12", + "serde", + "sha1_smol", + "wasm-bindgen", +] + +[[package]] +name = "validator" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b92f40481c04ff1f4f61f304d61793c7b56ff76ac1469f1beb199b1445b253bd" +dependencies = [ + "idna 0.4.0", + "lazy_static", + "regex", + "serde", + "serde_derive", + "serde_json", + "url", + "validator_derive", +] + +[[package]] +name = "validator_derive" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc44ca3088bb3ba384d9aecf40c6a23a676ce23e09bdaca2073d99c207f864af" +dependencies = [ + "if_chain", + "lazy_static", + "proc-macro-error", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", + "validator_types", +] + +[[package]] +name = "validator_types" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "111abfe30072511849c5910134e8baf8dc05de4c0e5903d681cbd5c9c4d611e3" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.48", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139bd73305d50e1c1c4333210c0db43d989395b64a237bd35c10ef3832a7f70c" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70072aebfe5da66d2716002c729a14e4aec4da0e23cc2ea66323dac541c93928" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "wasm-streams" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wasm-timer" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.11.2", + "pin-utils", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" + +[[package]] +name = "websocket" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" +dependencies = [ + "futures-channel", + "futures-util", + "http", + "httparse", + "js-sys", + "thiserror", + "tokio", + "tokio-tungstenite", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "yrs" +version = "0.17.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4830316bfee4bec0044fe34a001cda783506d5c4c0852f8433c6041dfbfce51" +dependencies = [ + "atomic_refcell", + "rand 0.7.3", + "serde", + "serde_json", + "smallstr", + "smallvec", + "thiserror", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "aes", + "byteorder", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "flate2", + "hmac", + "pbkdf2 0.11.0", + "sha1", + "time", + "zstd", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.9+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +dependencies = [ + "cc", + "pkg-config", +] + +[[patch.unused]] +name = "collab-database" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml new file mode 100644 index 0000000000..2c27eeafd0 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -0,0 +1,81 @@ +[workspace] +members = [ + "af-wasm", + "af-user", + "af-persistence", +] +resolver = "2" + +[workspace.dependencies] +af-user = { path = "af-user" } +af-persistence = { path = "af-persistence" } + +lib-dispatch = { path = "../../rust-lib/lib-dispatch" } +parking_lot = { version = "0.12.1" } +tracing = { version = "0.1.22" } +serde = { version = "1.0.194", features = ["derive"] } +serde_json = "1.0" +collab-integrate = { path = "../../rust-lib/collab-integrate"} +flowy-notification = { path = "../../rust-lib/flowy-notification" } +flowy-user-pub = { path = "../../rust-lib/flowy-user-pub" } +flowy-server = { path = "../../rust-lib/flowy-server" } +flowy-server-pub = { path = "../../rust-lib/flowy-server-pub" } +flowy-error = { path = "../../rust-lib/flowy-error" } +flowy-derive = { path = "../../rust-lib/build-tool/flowy-derive" } +flowy-codegen = { path = "../../rust-lib/build-tool/flowy-codegen" } +flowy-document = { path = "../../rust-lib/flowy-document" } +lib-infra = { path = "../../rust-lib/lib-infra" } +collab = { version = "0.1.0" } +collab-entity = { version = "0.1.0" } +collab-user = { version = "0.1.0" } +bytes = { version = "1.5" } +protobuf = { version = "2.28.0" } +thiserror = "1.0" +anyhow = "1.0" +futures-util = "0.3" +uuid = { version = "1.5", features = ["serde", "v4", "v5"] } +tokio-stream = "0.1" +tokio = { version = "1.35", features = ["sync"] } +wasm-bindgen-futures = "0.4.40" +serde-wasm-bindgen = "0.4" + + +[profile.dev] +opt-level = 0 +lto = false +codegen-units = 16 + +[profile.release] +lto = true +opt-level = 3 +codegen-units = 1 + +[profile.profiling] +inherits = "release" +debug = true +codegen-units = 16 +lto = false + +[patch.crates-io] +# Please using the following command to update the revision id +# Current directory: frontend +# Run the script: +# scripts/tool/update_client_api_rev.sh new_rev_id +# ⚠️⚠️⚠️️ +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "69c69f6474eaa531fd822e9353cc5955b98e45eb" } +# Please use the following script to update collab. +# Working directory: frontend +# +# To update the commit ID, run: +# scripts/tool/update_collab_rev.sh new_rev_id +# +# To switch to the local path, run: +# scripts/tool/update_collab_source.sh +# ⚠️⚠️⚠️️ +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } diff --git a/frontend/appflowy_web/wasm-libs/af-persistence/Cargo.toml b/frontend/appflowy_web/wasm-libs/af-persistence/Cargo.toml new file mode 100644 index 0000000000..8ce5683877 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-persistence/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "af-persistence" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +indexed_db_futures = { version = "0.4" } +js-sys = "0.3" +wasm-bindgen = "0.2" +web-sys = { version = "0.3", features = ["console", "Window"] } +tokio = { version = "1.26.0", features = ["sync", "rt"] } +flowy-error.workspace = true +thiserror.workspace = true +anyhow.workspace = true +serde.workspace = true +serde_json.workspace = true +futures-util.workspace = true +wasm-bindgen-futures.workspace = true diff --git a/frontend/appflowy_web/wasm-libs/af-persistence/src/error.rs b/frontend/appflowy_web/wasm-libs/af-persistence/src/error.rs new file mode 100644 index 0000000000..1a6ad08d9a --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-persistence/src/error.rs @@ -0,0 +1,30 @@ +use flowy_error::FlowyError; +use web_sys::DomException; + +#[derive(Debug, thiserror::Error)] +pub enum PersistenceError { + #[error(transparent)] + Internal(#[from] anyhow::Error), + + #[error(transparent)] + SerdeError(#[from] serde_json::Error), + + #[error("{0}")] + RecordNotFound(String), +} + +impl From for PersistenceError { + fn from(value: DomException) -> Self { + PersistenceError::Internal(anyhow::anyhow!("DOMException: {:?}", value)) + } +} + +impl From for FlowyError { + fn from(value: PersistenceError) -> Self { + match value { + PersistenceError::Internal(value) => FlowyError::internal().with_context(value), + PersistenceError::SerdeError(value) => FlowyError::serde().with_context(value), + PersistenceError::RecordNotFound(value) => FlowyError::record_not_found().with_context(value), + } + } +} diff --git a/frontend/appflowy_web/wasm-libs/af-persistence/src/lib.rs b/frontend/appflowy_web/wasm-libs/af-persistence/src/lib.rs new file mode 100644 index 0000000000..4f89971020 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-persistence/src/lib.rs @@ -0,0 +1,2 @@ +pub mod error; +pub mod store; diff --git a/frontend/appflowy_web/wasm-libs/af-persistence/src/store.rs b/frontend/appflowy_web/wasm-libs/af-persistence/src/store.rs new file mode 100644 index 0000000000..92335e32b3 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-persistence/src/store.rs @@ -0,0 +1,192 @@ +use crate::error::PersistenceError; +use anyhow::anyhow; +use futures_util::future::LocalBoxFuture; +use indexed_db_futures::idb_object_store::IdbObjectStore; +use indexed_db_futures::idb_transaction::{IdbTransaction, IdbTransactionResult}; +use indexed_db_futures::prelude::IdbOpenDbRequestLike; +use indexed_db_futures::{IdbDatabase, IdbQuerySource, IdbVersionChangeEvent}; +use js_sys::Uint8Array; +use serde::de::DeserializeOwned; +use serde::Serialize; +use std::future::Future; +use std::sync::Arc; +use tokio::sync::RwLock; +use wasm_bindgen::JsValue; +use web_sys::IdbTransactionMode; + +pub trait IndexddbStore { + fn get<'a, T>(&'a self, key: &'a str) -> LocalBoxFuture, PersistenceError>> + where + T: serde::de::DeserializeOwned + Sync; + fn set<'a, T>(&'a self, key: &'a str, value: T) -> LocalBoxFuture> + where + T: serde::Serialize + Sync + 'a; + fn remove<'a>(&'a self, key: &'a str) -> LocalBoxFuture>; +} + +const APPFLOWY_STORE: &str = "appflowy_store"; +pub struct AppFlowyWASMStore { + db: Arc>, +} + +unsafe impl Send for AppFlowyWASMStore {} +unsafe impl Sync for AppFlowyWASMStore {} + +impl AppFlowyWASMStore { + pub async fn new() -> Result { + let mut db_req = IdbDatabase::open_u32("appflowy", 1)?; + db_req.set_on_upgrade_needed(Some(|evt: &IdbVersionChangeEvent| -> Result<(), JsValue> { + if !evt.db().object_store_names().any(|n| &n == APPFLOWY_STORE) { + evt.db().create_object_store(APPFLOWY_STORE)?; + } + Ok(()) + })); + let db = Arc::new(RwLock::new(db_req.await?)); + Ok(Self { db }) + } + + pub async fn begin_read_transaction(&self, f: F) -> Result<(), PersistenceError> + where + F: FnOnce(&IndexddbStoreImpl<'_>) -> Fut, + Fut: Future>, + { + let db = self.db.read().await; + let txn = db.transaction_on_one_with_mode(APPFLOWY_STORE, IdbTransactionMode::Readonly)?; + let store = store_from_transaction(&txn)?; + let operation = IndexddbStoreImpl(store); + f(&operation).await?; + transaction_result_to_result(txn.await)?; + Ok(()) + } + + pub async fn begin_write_transaction(&self, f: F) -> Result<(), PersistenceError> + where + F: FnOnce(IndexddbStoreImpl<'_>) -> LocalBoxFuture<'_, Result<(), PersistenceError>>, + { + let db = self.db.write().await; + let txn = db.transaction_on_one_with_mode(APPFLOWY_STORE, IdbTransactionMode::Readwrite)?; + let store = store_from_transaction(&txn)?; + let operation = IndexddbStoreImpl(store); + f(operation).await?; + transaction_result_to_result(txn.await)?; + Ok(()) + } +} + +pub struct IndexddbStoreImpl<'i>(IdbObjectStore<'i>); + +impl<'i> IndexddbStore for IndexddbStoreImpl<'i> { + fn get<'a, T>(&'a self, key: &'a str) -> LocalBoxFuture, PersistenceError>> + where + T: DeserializeOwned + Sync, + { + let js_key = to_js_value(key); + Box::pin(async move { + match self.0.get(&js_key)?.await? { + None => Err(PersistenceError::RecordNotFound(format!( + "Can't find the value for given key: {} ", + key + ))), + Some(value) => { + let bytes = Uint8Array::new(&value).to_vec(); + let object = serde_json::from_slice::(&bytes)?; + Ok(Some(object)) + }, + } + }) + } + + fn set<'a, T>(&'a self, key: &'a str, value: T) -> LocalBoxFuture> + where + T: Serialize + Sync + 'a, + { + let js_key = to_js_value(key); + Box::pin(async move { + let js_value = to_js_value(serde_json::to_vec(&value)?); + self.0.put_key_val(&js_key, &js_value)?.await?; + Ok(()) + }) + } + + fn remove<'a>(&'a self, key: &'a str) -> LocalBoxFuture> { + let js_key = to_js_value(key); + Box::pin(async move { + self.0.delete(&js_key)?.await?; + Ok(()) + }) + } +} + +impl IndexddbStore for AppFlowyWASMStore { + fn get<'a, T>(&'a self, key: &'a str) -> LocalBoxFuture, PersistenceError>> + where + T: serde::de::DeserializeOwned + Sync, + { + let db = Arc::downgrade(&self.db); + Box::pin(async move { + let db = db.upgrade().ok_or_else(|| { + PersistenceError::Internal(anyhow!("Failed to upgrade the database reference")) + })?; + let read_guard = db.read().await; + let txn = + read_guard.transaction_on_one_with_mode(APPFLOWY_STORE, IdbTransactionMode::Readonly)?; + let store = store_from_transaction(&txn)?; + IndexddbStoreImpl(store).get(key).await + }) + } + + fn set<'a, T>(&'a self, key: &'a str, value: T) -> LocalBoxFuture> + where + T: serde::Serialize + Sync + 'a, + { + let db = Arc::downgrade(&self.db); + Box::pin(async move { + let db = db.upgrade().ok_or_else(|| { + PersistenceError::Internal(anyhow!("Failed to upgrade the database reference")) + })?; + let read_guard = db.read().await; + let txn = + read_guard.transaction_on_one_with_mode(APPFLOWY_STORE, IdbTransactionMode::Readwrite)?; + let store = store_from_transaction(&txn)?; + IndexddbStoreImpl(store).set(key, value).await?; + transaction_result_to_result(txn.await)?; + Ok(()) + }) + } + + fn remove<'a>(&'a self, key: &'a str) -> LocalBoxFuture> { + let db = Arc::downgrade(&self.db); + Box::pin(async move { + let db = db.upgrade().ok_or_else(|| { + PersistenceError::Internal(anyhow!("Failed to upgrade the database reference")) + })?; + let read_guard = db.read().await; + let txn = + read_guard.transaction_on_one_with_mode(APPFLOWY_STORE, IdbTransactionMode::Readwrite)?; + let store = store_from_transaction(&txn)?; + IndexddbStoreImpl(store).remove(key).await?; + transaction_result_to_result(txn.await)?; + Ok(()) + }) + } +} + +fn to_js_value>(key: K) -> JsValue { + JsValue::from(Uint8Array::from(key.as_ref())) +} + +fn store_from_transaction<'a>( + txn: &'a IdbTransaction<'a>, +) -> Result, PersistenceError> { + txn + .object_store(APPFLOWY_STORE) + .map_err(PersistenceError::from) +} + +fn transaction_result_to_result(result: IdbTransactionResult) -> Result<(), PersistenceError> { + match result { + IdbTransactionResult::Success => Ok(()), + IdbTransactionResult::Error(err) => Err(PersistenceError::from(err)), + IdbTransactionResult::Abort => Err(PersistenceError::Internal(anyhow!("Transaction aborted"))), + } +} diff --git a/frontend/appflowy_web/wasm-libs/af-user/Cargo.toml b/frontend/appflowy_web/wasm-libs/af-user/Cargo.toml new file mode 100644 index 0000000000..6f2694acb5 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "af-user" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +af-persistence.workspace = true +lib-dispatch = { workspace = true } +flowy-derive = { workspace = true } +flowy-error = { workspace = true, features = ["impl_from_dispatch_error", "impl_from_collab_persistence"] } +flowy-user-pub = { workspace = true } +strum_macros = "0.25.2" +tracing.workspace = true +lib-infra = { workspace = true } +collab = { workspace = true, features = ["wasm_build", "async-plugin"] } +collab-entity.workspace = true +collab-user.workspace = true +collab-integrate = { workspace = true, features = ["enable_wasm"] } +protobuf.workspace = true +bytes.workspace = true +anyhow.workspace = true +wasm-bindgen-futures.workspace = true +tokio = { workspace = true, features = ["sync"] } + +[build-dependencies] +flowy-codegen = { workspace = true, features = ["ts"] } diff --git a/frontend/appflowy_web/wasm-libs/af-user/Flowy.toml b/frontend/appflowy_web/wasm-libs/af-user/Flowy.toml new file mode 100644 index 0000000000..593c05b741 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/Flowy.toml @@ -0,0 +1,3 @@ +# Check out the FlowyConfig (located in flowy_toml.rs) for more details. +proto_input = ["src/entities", "src/event_map.rs"] +event_files = ["src/event_map.rs"] \ No newline at end of file diff --git a/frontend/appflowy_web/wasm-libs/af-user/build.rs b/frontend/appflowy_web/wasm-libs/af-user/build.rs new file mode 100644 index 0000000000..2c47f8f2d2 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/build.rs @@ -0,0 +1,18 @@ +use flowy_codegen::Project; + +fn main() { + let crate_name = env!("CARGO_PKG_NAME"); + + flowy_codegen::protobuf_file::ts_gen( + crate_name, + Project::Web { + relative_path: "../../../".to_string(), + }, + ); + flowy_codegen::ts_event::gen( + crate_name, + Project::Web { + relative_path: "../../../".to_string(), + }, + ); +} diff --git a/frontend/appflowy_web/wasm-libs/af-user/src/define.rs b/frontend/appflowy_web/wasm-libs/af-user/src/define.rs new file mode 100644 index 0000000000..520cf21f34 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/src/define.rs @@ -0,0 +1,9 @@ +pub(crate) const AF_USER_SESSION_KEY: &str = "af-user-session"; + +pub(crate) fn user_workspace_key(uid: i64) -> String { + format!("af-user-workspaces-{}", uid) +} + +pub(crate) fn user_profile_key(uid: i64) -> String { + format!("af-user-profile-{}", uid) +} diff --git a/frontend/appflowy_web/wasm-libs/af-user/src/entities/auth.rs b/frontend/appflowy_web/wasm-libs/af-user/src/entities/auth.rs new file mode 100644 index 0000000000..96455adc5f --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/src/entities/auth.rs @@ -0,0 +1,68 @@ +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_user_pub::entities::Authenticator; +use std::collections::HashMap; + +#[derive(ProtoBuf, Default)] +pub struct OauthSignInPB { + /// Use this field to store the third party auth information. + /// Different auth type has different fields. + /// Supabase: + /// - map: { "uuid": "xxx" } + /// + #[pb(index = 1)] + pub map: HashMap, + + #[pb(index = 2)] + pub authenticator: AuthenticatorPB, +} + +#[derive(ProtoBuf_Enum, Eq, PartialEq, Debug, Clone)] +pub enum AuthenticatorPB { + Local = 0, + Supabase = 1, + AppFlowyCloud = 2, +} + +impl From for AuthenticatorPB { + fn from(auth_type: Authenticator) -> Self { + match auth_type { + Authenticator::Supabase => AuthenticatorPB::Supabase, + Authenticator::Local => AuthenticatorPB::Local, + Authenticator::AppFlowyCloud => AuthenticatorPB::AppFlowyCloud, + } + } +} + +impl From for Authenticator { + fn from(pb: AuthenticatorPB) -> Self { + match pb { + AuthenticatorPB::Supabase => Authenticator::Supabase, + AuthenticatorPB::Local => Authenticator::Local, + AuthenticatorPB::AppFlowyCloud => Authenticator::AppFlowyCloud, + } + } +} + +impl Default for AuthenticatorPB { + fn default() -> Self { + Self::AppFlowyCloud + } +} + +#[derive(ProtoBuf, Default)] +pub struct AddUserPB { + #[pb(index = 1)] + pub email: String, + + #[pb(index = 2)] + pub password: String, +} + +#[derive(ProtoBuf, Default)] +pub struct UserSignInPB { + #[pb(index = 1)] + pub email: String, + + #[pb(index = 2)] + pub password: String, +} diff --git a/frontend/appflowy_web/wasm-libs/af-user/src/entities/mod.rs b/frontend/appflowy_web/wasm-libs/af-user/src/entities/mod.rs new file mode 100644 index 0000000000..fd9d22da5d --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/src/entities/mod.rs @@ -0,0 +1,5 @@ +mod auth; +mod user; + +pub use auth::*; +pub use user::*; diff --git a/frontend/appflowy_web/wasm-libs/af-user/src/entities/user.rs b/frontend/appflowy_web/wasm-libs/af-user/src/entities/user.rs new file mode 100644 index 0000000000..0aa22d6e7a --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/src/entities/user.rs @@ -0,0 +1,69 @@ +use crate::entities::AuthenticatorPB; +use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; +use flowy_user_pub::entities::{EncryptionType, UserProfile}; + +#[derive(ProtoBuf, Default, Eq, PartialEq, Debug, Clone)] +pub struct UserProfilePB { + #[pb(index = 1)] + pub id: i64, + + #[pb(index = 2)] + pub email: String, + + #[pb(index = 3)] + pub name: String, + + #[pb(index = 4)] + pub token: String, + + #[pb(index = 5)] + pub icon_url: String, + + #[pb(index = 6)] + pub openai_key: String, + + #[pb(index = 7)] + pub authenticator: AuthenticatorPB, + + #[pb(index = 8)] + pub encryption_sign: String, + + #[pb(index = 9)] + pub workspace_id: String, + + #[pb(index = 10)] + pub stability_ai_key: String, +} + +impl From for UserProfilePB { + fn from(user_profile: UserProfile) -> Self { + let (encryption_sign, _encryption_ty) = match user_profile.encryption_type { + EncryptionType::NoEncryption => ("".to_string(), EncryptionTypePB::NoEncryption), + EncryptionType::SelfEncryption(sign) => (sign, EncryptionTypePB::Symmetric), + }; + Self { + id: user_profile.uid, + email: user_profile.email, + name: user_profile.name, + token: user_profile.token, + icon_url: user_profile.icon_url, + openai_key: user_profile.openai_key, + encryption_sign, + authenticator: user_profile.authenticator.into(), + workspace_id: user_profile.workspace_id, + stability_ai_key: user_profile.stability_ai_key, + } + } +} + +#[derive(ProtoBuf_Enum, Eq, PartialEq, Debug, Clone)] +pub enum EncryptionTypePB { + NoEncryption = 0, + Symmetric = 1, +} + +impl Default for EncryptionTypePB { + fn default() -> Self { + Self::NoEncryption + } +} diff --git a/frontend/appflowy_web/wasm-libs/af-user/src/event_handler.rs b/frontend/appflowy_web/wasm-libs/af-user/src/event_handler.rs new file mode 100644 index 0000000000..54291cc486 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/src/event_handler.rs @@ -0,0 +1,50 @@ +use crate::entities::*; +use crate::manager::UserManagerWASM; +use flowy_error::{FlowyError, FlowyResult}; +use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataResult}; +use lib_infra::box_any::BoxAny; +use std::rc::{Rc, Weak}; + +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub async fn oauth_sign_in_handler( + data: AFPluginData, + manager: AFPluginState>, +) -> DataResult { + let manager = upgrade_manager(manager)?; + let params = data.into_inner(); + let user_profile = manager.sign_up(BoxAny::new(params.map)).await?; + data_result_ok(user_profile.into()) +} + +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub async fn add_user_handler( + data: AFPluginData, + manager: AFPluginState>, +) -> Result<(), FlowyError> { + let manager = upgrade_manager(manager)?; + let params = data.into_inner(); + manager.add_user(¶ms.email, ¶ms.password).await?; + Ok(()) +} + +#[tracing::instrument(level = "debug", skip(data, manager), err)] +pub async fn sign_in_with_password_handler( + data: AFPluginData, + manager: AFPluginState>, +) -> DataResult { + let manager = upgrade_manager(manager)?; + let params = data.into_inner(); + let user_profile = manager + .sign_in_with_password(¶ms.email, ¶ms.password) + .await?; + data_result_ok(UserProfilePB::from(user_profile)) +} + +fn upgrade_manager( + manager: AFPluginState>, +) -> FlowyResult> { + let manager = manager + .upgrade() + .ok_or(FlowyError::internal().with_context("The user session is already drop"))?; + Ok(manager) +} diff --git a/frontend/appflowy_web/wasm-libs/af-user/src/event_map.rs b/frontend/appflowy_web/wasm-libs/af-user/src/event_map.rs new file mode 100644 index 0000000000..302a26aaf7 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/src/event_map.rs @@ -0,0 +1,29 @@ +use crate::event_handler::*; +use crate::manager::UserManagerWASM; +use flowy_derive::{Flowy_Event, ProtoBuf_Enum}; +use lib_dispatch::prelude::AFPlugin; +use std::rc::Weak; +use strum_macros::Display; + +#[rustfmt::skip] +pub fn init(user_manager: Weak) -> AFPlugin { + AFPlugin::new() + .name("Flowy-User") + .state(user_manager) + .event(UserWasmEvent::OauthSignIn, oauth_sign_in_handler) + .event(UserWasmEvent::AddUser, add_user_handler) + .event(UserWasmEvent::SignInPassword, sign_in_with_password_handler) +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)] +#[event_err = "FlowyError"] +pub enum UserWasmEvent { + #[event(input = "OauthSignInPB", output = "UserProfilePB")] + OauthSignIn = 0, + + #[event(input = "AddUserPB")] + AddUser = 1, + + #[event(input = "UserSignInPB", output = "UserProfilePB")] + SignInPassword = 2, +} diff --git a/frontend/appflowy_web/wasm-libs/af-user/src/lib.rs b/frontend/appflowy_web/wasm-libs/af-user/src/lib.rs new file mode 100644 index 0000000000..9d9d15ce38 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/src/lib.rs @@ -0,0 +1,6 @@ +mod define; +pub mod entities; +mod event_handler; +pub mod event_map; +pub mod manager; +mod protobuf; diff --git a/frontend/appflowy_web/wasm-libs/af-user/src/manager.rs b/frontend/appflowy_web/wasm-libs/af-user/src/manager.rs new file mode 100644 index 0000000000..2d90af078a --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/src/manager.rs @@ -0,0 +1,217 @@ +use crate::define::{user_profile_key, user_workspace_key, AF_USER_SESSION_KEY}; +use af_persistence::store::{AppFlowyWASMStore, IndexddbStore}; +use anyhow::Context; +use collab::core::collab::CollabDocState; +use collab_entity::CollabType; +use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig}; +use collab_integrate::{CollabKVDB, MutexCollab}; +use collab_user::core::{MutexUserAwareness, UserAwareness}; +use flowy_error::{ErrorCode, FlowyError, FlowyResult}; +use flowy_user_pub::cloud::{UserCloudConfig, UserCloudServiceProvider}; +use flowy_user_pub::entities::{ + awareness_oid_from_user_uuid, AuthResponse, Authenticator, UserAuthResponse, UserProfile, + UserWorkspace, +}; +use flowy_user_pub::session::Session; +use lib_infra::box_any::BoxAny; +use lib_infra::future::Fut; +use std::rc::Rc; +use std::sync::{Arc, Mutex, Weak}; +use tracing::{error, instrument, trace}; + +pub trait UserCallback { + fn did_init( + &self, + user_id: i64, + cloud_config: &Option, + user_workspace: &UserWorkspace, + device_id: &str, + ) -> Fut>; + fn did_sign_in(&self, uid: i64, workspace: &UserWorkspace, device_id: &str) -> FlowyResult<()>; + fn did_sign_up( + &self, + is_new_user: bool, + user_profile: &UserProfile, + user_workspace: &UserWorkspace, + device_id: &str, + ) -> Fut>; +} + +pub struct UserManagerWASM { + device_id: String, + pub(crate) cloud_services: Rc, + pub(crate) collab_builder: Weak, + pub(crate) store: Rc, + user_callbacks: Vec>, + + #[allow(dead_code)] + pub(crate) user_awareness: Rc>>, + pub(crate) collab_db: Arc, +} + +impl UserManagerWASM { + pub async fn new( + device_id: &str, + cloud_services: Rc, + collab_builder: Weak, + ) -> Result { + let device_id = device_id.to_string(); + let store = Rc::new(AppFlowyWASMStore::new().await?); + let collab_db = Arc::new(CollabKVDB::new().await?); + Ok(Self { + device_id, + cloud_services, + collab_builder, + store, + user_callbacks: vec![], + user_awareness: Rc::new(Default::default()), + collab_db, + }) + } + + pub async fn sign_up(&self, params: BoxAny) -> FlowyResult { + let auth_service = self.cloud_services.get_user_service()?; + let response: AuthResponse = auth_service.sign_up(params).await?; + let new_user_profile = UserProfile::from((&response, &Authenticator::AppFlowyCloud)); + let new_session = Session::from(&response); + + self.prepare_collab(&new_session); + self + .save_auth_data(&response, &new_user_profile, &new_session) + .await?; + + if let Err(err) = self.initialize_user_awareness(&new_session).await { + error!("Failed to initialize user awareness: {:?}", err); + } + + for callback in self.user_callbacks.iter() { + if let Err(e) = callback + .did_sign_up( + response.is_new_user, + &new_user_profile, + &new_session.user_workspace, + &self.device_id, + ) + .await + { + error!("Failed to call did_sign_up callback: {:?}", e); + } + } + + // TODO(nathan): send notification + // send_auth_state_notification(AuthStateChangedPB { + // state: AuthStatePB::AuthStateSignIn, + // message: "Sign in success".to_string(), + // }); + Ok(new_user_profile) + } + + pub(crate) async fn add_user(&self, email: &str, password: &str) -> Result<(), FlowyError> { + let auth_service = self.cloud_services.get_user_service()?; + auth_service.create_user(email, password).await?; + Ok(()) + } + + pub(crate) async fn sign_in_with_password( + &self, + email: &str, + password: &str, + ) -> Result { + let auth_service = self.cloud_services.get_user_service()?; + let user_profile = auth_service.sign_in_with_password(email, password).await?; + Ok(user_profile) + } + + fn prepare_collab(&self, session: &Session) { + let collab_builder = self.collab_builder.upgrade().unwrap(); + collab_builder.initialize(session.user_workspace.id.clone()); + } + + async fn initialize_user_awareness(&self, new_session: &Session) -> FlowyResult<()> { + let data = self + .cloud_services + .get_user_service()? + .get_user_awareness_doc_state(new_session.user_id) + .await?; + trace!("Get user awareness collab: {}", data.len()); + let collab = self + .collab_for_user_awareness(new_session, Arc::downgrade(&self.collab_db), data) + .await?; + MutexUserAwareness::new(UserAwareness::create(collab, None)); + Ok(()) + } + + #[instrument(level = "info", skip_all, err)] + async fn save_auth_data( + &self, + response: &impl UserAuthResponse, + user_profile: &UserProfile, + session: &Session, + ) -> Result<(), FlowyError> { + let uid = user_profile.uid; + let user_profile = user_profile.clone(); + let session = session.clone(); + let user_workspace = response.user_workspaces().to_vec(); + self + .store + .begin_write_transaction(|store| { + Box::pin(async move { + store.set(&user_workspace_key(uid), &user_workspace).await?; + store.set(AF_USER_SESSION_KEY, session).await?; + store.set(&user_profile_key(uid), user_profile).await?; + Ok(()) + }) + }) + .await?; + + Ok(()) + } + + pub async fn save_user_session(&self, session: &Session) -> FlowyResult<()> { + self.store.set(AF_USER_SESSION_KEY, session).await?; + Ok(()) + } + + pub async fn save_user_workspaces( + &self, + uid: i64, + user_workspaces: &[UserWorkspace], + ) -> FlowyResult<()> { + self + .store + .set(&user_workspace_key(uid), &user_workspaces.to_vec()) + .await?; + Ok(()) + } + + pub async fn save_user_profile(&self, user_profile: &UserProfile) -> FlowyResult<()> { + let uid = user_profile.uid; + self.store.set(&user_profile_key(uid), user_profile).await?; + Ok(()) + } + + async fn collab_for_user_awareness( + &self, + session: &Session, + collab_db: Weak, + raw_data: CollabDocState, + ) -> Result, FlowyError> { + let collab_builder = self.collab_builder.upgrade().ok_or(FlowyError::new( + ErrorCode::Internal, + "Unexpected error: collab builder is not available", + ))?; + let user_awareness_id = awareness_oid_from_user_uuid(&session.user_uuid); + let collab = collab_builder + .build( + session.user_id, + &user_awareness_id.to_string(), + CollabType::UserAwareness, + raw_data, + collab_db, + CollabBuilderConfig::default().sync_enable(true), + ) + .await + .context("Build collab for user awareness failed")?; + Ok(collab) + } +} diff --git a/frontend/appflowy_web/wasm-libs/af-user/src/protobuf/auth.rs b/frontend/appflowy_web/wasm-libs/af-user/src/protobuf/auth.rs new file mode 100644 index 0000000000..6dd0bd20f0 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/src/protobuf/auth.rs @@ -0,0 +1,689 @@ +// This file is generated by rust-protobuf 2.28.0. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `auth.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_28_0; + +#[derive(PartialEq,Clone,Default)] +pub struct OauthSignInPB { + // message fields + pub map: ::std::collections::HashMap<::std::string::String, ::std::string::String>, + pub authenticator: AuthenticatorPB, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a OauthSignInPB { + fn default() -> &'a OauthSignInPB { + ::default_instance() + } +} + +impl OauthSignInPB { + pub fn new() -> OauthSignInPB { + ::std::default::Default::default() + } + + // repeated .OauthSignInPB.MapEntry map = 1; + + + pub fn get_map(&self) -> &::std::collections::HashMap<::std::string::String, ::std::string::String> { + &self.map + } + pub fn clear_map(&mut self) { + self.map.clear(); + } + + // Param is passed by value, moved + pub fn set_map(&mut self, v: ::std::collections::HashMap<::std::string::String, ::std::string::String>) { + self.map = v; + } + + // Mutable pointer to the field. + pub fn mut_map(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, ::std::string::String> { + &mut self.map + } + + // Take field + pub fn take_map(&mut self) -> ::std::collections::HashMap<::std::string::String, ::std::string::String> { + ::std::mem::replace(&mut self.map, ::std::collections::HashMap::new()) + } + + // .AuthenticatorPB authenticator = 2; + + + pub fn get_authenticator(&self) -> AuthenticatorPB { + self.authenticator + } + pub fn clear_authenticator(&mut self) { + self.authenticator = AuthenticatorPB::Local; + } + + // Param is passed by value, moved + pub fn set_authenticator(&mut self, v: AuthenticatorPB) { + self.authenticator = v; + } +} + +impl ::protobuf::Message for OauthSignInPB { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(wire_type, is, &mut self.map)?; + }, + 2 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.authenticator, 2, &mut self.unknown_fields)? + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(1, &self.map); + if self.authenticator != AuthenticatorPB::Local { + my_size += ::protobuf::rt::enum_size(2, self.authenticator); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(1, &self.map, os)?; + if self.authenticator != AuthenticatorPB::Local { + os.write_enum(2, ::protobuf::ProtobufEnum::value(&self.authenticator))?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> OauthSignInPB { + OauthSignInPB::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>( + "map", + |m: &OauthSignInPB| { &m.map }, + |m: &mut OauthSignInPB| { &mut m.map }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "authenticator", + |m: &OauthSignInPB| { &m.authenticator }, + |m: &mut OauthSignInPB| { &mut m.authenticator }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "OauthSignInPB", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static OauthSignInPB { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(OauthSignInPB::new) + } +} + +impl ::protobuf::Clear for OauthSignInPB { + fn clear(&mut self) { + self.map.clear(); + self.authenticator = AuthenticatorPB::Local; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for OauthSignInPB { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for OauthSignInPB { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct AddUserPB { + // message fields + pub email: ::std::string::String, + pub password: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a AddUserPB { + fn default() -> &'a AddUserPB { + ::default_instance() + } +} + +impl AddUserPB { + pub fn new() -> AddUserPB { + ::std::default::Default::default() + } + + // string email = 1; + + + pub fn get_email(&self) -> &str { + &self.email + } + pub fn clear_email(&mut self) { + self.email.clear(); + } + + // Param is passed by value, moved + pub fn set_email(&mut self, v: ::std::string::String) { + self.email = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_email(&mut self) -> &mut ::std::string::String { + &mut self.email + } + + // Take field + pub fn take_email(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.email, ::std::string::String::new()) + } + + // string password = 2; + + + pub fn get_password(&self) -> &str { + &self.password + } + pub fn clear_password(&mut self) { + self.password.clear(); + } + + // Param is passed by value, moved + pub fn set_password(&mut self, v: ::std::string::String) { + self.password = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_password(&mut self) -> &mut ::std::string::String { + &mut self.password + } + + // Take field + pub fn take_password(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.password, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for AddUserPB { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.password)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.email.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.email); + } + if !self.password.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.password); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.email.is_empty() { + os.write_string(1, &self.email)?; + } + if !self.password.is_empty() { + os.write_string(2, &self.password)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> AddUserPB { + AddUserPB::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "email", + |m: &AddUserPB| { &m.email }, + |m: &mut AddUserPB| { &mut m.email }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "password", + |m: &AddUserPB| { &m.password }, + |m: &mut AddUserPB| { &mut m.password }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "AddUserPB", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static AddUserPB { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(AddUserPB::new) + } +} + +impl ::protobuf::Clear for AddUserPB { + fn clear(&mut self) { + self.email.clear(); + self.password.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for AddUserPB { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for AddUserPB { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(PartialEq,Clone,Default)] +pub struct UserSignInPB { + // message fields + pub email: ::std::string::String, + pub password: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a UserSignInPB { + fn default() -> &'a UserSignInPB { + ::default_instance() + } +} + +impl UserSignInPB { + pub fn new() -> UserSignInPB { + ::std::default::Default::default() + } + + // string email = 1; + + + pub fn get_email(&self) -> &str { + &self.email + } + pub fn clear_email(&mut self) { + self.email.clear(); + } + + // Param is passed by value, moved + pub fn set_email(&mut self, v: ::std::string::String) { + self.email = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_email(&mut self) -> &mut ::std::string::String { + &mut self.email + } + + // Take field + pub fn take_email(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.email, ::std::string::String::new()) + } + + // string password = 2; + + + pub fn get_password(&self) -> &str { + &self.password + } + pub fn clear_password(&mut self) { + self.password.clear(); + } + + // Param is passed by value, moved + pub fn set_password(&mut self, v: ::std::string::String) { + self.password = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_password(&mut self) -> &mut ::std::string::String { + &mut self.password + } + + // Take field + pub fn take_password(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.password, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for UserSignInPB { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.password)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.email.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.email); + } + if !self.password.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.password); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.email.is_empty() { + os.write_string(1, &self.email)?; + } + if !self.password.is_empty() { + os.write_string(2, &self.password)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> UserSignInPB { + UserSignInPB::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "email", + |m: &UserSignInPB| { &m.email }, + |m: &mut UserSignInPB| { &mut m.email }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "password", + |m: &UserSignInPB| { &m.password }, + |m: &mut UserSignInPB| { &mut m.password }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "UserSignInPB", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static UserSignInPB { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(UserSignInPB::new) + } +} + +impl ::protobuf::Clear for UserSignInPB { + fn clear(&mut self) { + self.email.clear(); + self.password.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for UserSignInPB { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for UserSignInPB { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum AuthenticatorPB { + Local = 0, + Supabase = 1, + AppFlowyCloud = 2, +} + +impl ::protobuf::ProtobufEnum for AuthenticatorPB { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(AuthenticatorPB::Local), + 1 => ::std::option::Option::Some(AuthenticatorPB::Supabase), + 2 => ::std::option::Option::Some(AuthenticatorPB::AppFlowyCloud), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [AuthenticatorPB] = &[ + AuthenticatorPB::Local, + AuthenticatorPB::Supabase, + AuthenticatorPB::AppFlowyCloud, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("AuthenticatorPB", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for AuthenticatorPB { +} + +impl ::std::default::Default for AuthenticatorPB { + fn default() -> Self { + AuthenticatorPB::Local + } +} + +impl ::protobuf::reflect::ProtobufValue for AuthenticatorPB { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\nauth.proto\"\xaa\x01\n\rOauthSignInPB\x12)\n\x03map\x18\x01\x20\x03(\ + \x0b2\x17.OauthSignInPB.MapEntryR\x03map\x126\n\rauthenticator\x18\x02\ + \x20\x01(\x0e2\x10.AuthenticatorPBR\rauthenticator\x1a6\n\x08MapEntry\ + \x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x14\n\x05value\x18\x02\ + \x20\x01(\tR\x05value:\x028\x01\"=\n\tAddUserPB\x12\x14\n\x05email\x18\ + \x01\x20\x01(\tR\x05email\x12\x1a\n\x08password\x18\x02\x20\x01(\tR\x08p\ + assword\"@\n\x0cUserSignInPB\x12\x14\n\x05email\x18\x01\x20\x01(\tR\x05e\ + mail\x12\x1a\n\x08password\x18\x02\x20\x01(\tR\x08password*=\n\x0fAuthen\ + ticatorPB\x12\t\n\x05Local\x10\0\x12\x0c\n\x08Supabase\x10\x01\x12\x11\n\ + \rAppFlowyCloud\x10\x02b\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/appflowy_web/wasm-libs/af-user/src/protobuf/event_map.rs b/frontend/appflowy_web/wasm-libs/af-user/src/protobuf/event_map.rs new file mode 100644 index 0000000000..f3d5173833 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/src/protobuf/event_map.rs @@ -0,0 +1,95 @@ +// This file is generated by rust-protobuf 2.28.0. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `event_map.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_28_0; + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum UserWasmEvent { + OauthSignIn = 0, + AddUser = 1, + SignInPassword = 2, +} + +impl ::protobuf::ProtobufEnum for UserWasmEvent { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(UserWasmEvent::OauthSignIn), + 1 => ::std::option::Option::Some(UserWasmEvent::AddUser), + 2 => ::std::option::Option::Some(UserWasmEvent::SignInPassword), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [UserWasmEvent] = &[ + UserWasmEvent::OauthSignIn, + UserWasmEvent::AddUser, + UserWasmEvent::SignInPassword, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("UserWasmEvent", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for UserWasmEvent { +} + +impl ::std::default::Default for UserWasmEvent { + fn default() -> Self { + UserWasmEvent::OauthSignIn + } +} + +impl ::protobuf::reflect::ProtobufValue for UserWasmEvent { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x0fevent_map.proto*A\n\rUserWasmEvent\x12\x0f\n\x0bOauthSignIn\x10\0\ + \x12\x0b\n\x07AddUser\x10\x01\x12\x12\n\x0eSignInPassword\x10\x02b\x06pr\ + oto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/appflowy_web/wasm-libs/af-user/src/protobuf/mod.rs b/frontend/appflowy_web/wasm-libs/af-user/src/protobuf/mod.rs new file mode 100644 index 0000000000..b79dbb09f6 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/src/protobuf/mod.rs @@ -0,0 +1,12 @@ +#![cfg_attr(rustfmt, rustfmt::skip)] + #![allow(ambiguous_glob_reexports)] +// Auto-generated, do not edit + +mod event_map; +pub use event_map::*; + +mod auth; +pub use auth::*; + +mod user; +pub use user::*; diff --git a/frontend/appflowy_web/wasm-libs/af-user/src/protobuf/user.rs b/frontend/appflowy_web/wasm-libs/af-user/src/protobuf/user.rs new file mode 100644 index 0000000000..52f066e2d4 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-user/src/protobuf/user.rs @@ -0,0 +1,618 @@ +// This file is generated by rust-protobuf 2.28.0. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `user.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_28_0; + +#[derive(PartialEq,Clone,Default)] +pub struct UserProfilePB { + // message fields + pub id: i64, + pub email: ::std::string::String, + pub name: ::std::string::String, + pub token: ::std::string::String, + pub icon_url: ::std::string::String, + pub openai_key: ::std::string::String, + pub authenticator: super::auth::AuthenticatorPB, + pub encryption_sign: ::std::string::String, + pub workspace_id: ::std::string::String, + pub stability_ai_key: ::std::string::String, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a UserProfilePB { + fn default() -> &'a UserProfilePB { + ::default_instance() + } +} + +impl UserProfilePB { + pub fn new() -> UserProfilePB { + ::std::default::Default::default() + } + + // int64 id = 1; + + + pub fn get_id(&self) -> i64 { + self.id + } + pub fn clear_id(&mut self) { + self.id = 0; + } + + // Param is passed by value, moved + pub fn set_id(&mut self, v: i64) { + self.id = v; + } + + // string email = 2; + + + pub fn get_email(&self) -> &str { + &self.email + } + pub fn clear_email(&mut self) { + self.email.clear(); + } + + // Param is passed by value, moved + pub fn set_email(&mut self, v: ::std::string::String) { + self.email = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_email(&mut self) -> &mut ::std::string::String { + &mut self.email + } + + // Take field + pub fn take_email(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.email, ::std::string::String::new()) + } + + // string name = 3; + + + pub fn get_name(&self) -> &str { + &self.name + } + pub fn clear_name(&mut self) { + self.name.clear(); + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + &mut self.name + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.name, ::std::string::String::new()) + } + + // string token = 4; + + + pub fn get_token(&self) -> &str { + &self.token + } + pub fn clear_token(&mut self) { + self.token.clear(); + } + + // Param is passed by value, moved + pub fn set_token(&mut self, v: ::std::string::String) { + self.token = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_token(&mut self) -> &mut ::std::string::String { + &mut self.token + } + + // Take field + pub fn take_token(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.token, ::std::string::String::new()) + } + + // string icon_url = 5; + + + pub fn get_icon_url(&self) -> &str { + &self.icon_url + } + pub fn clear_icon_url(&mut self) { + self.icon_url.clear(); + } + + // Param is passed by value, moved + pub fn set_icon_url(&mut self, v: ::std::string::String) { + self.icon_url = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_icon_url(&mut self) -> &mut ::std::string::String { + &mut self.icon_url + } + + // Take field + pub fn take_icon_url(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.icon_url, ::std::string::String::new()) + } + + // string openai_key = 6; + + + pub fn get_openai_key(&self) -> &str { + &self.openai_key + } + pub fn clear_openai_key(&mut self) { + self.openai_key.clear(); + } + + // Param is passed by value, moved + pub fn set_openai_key(&mut self, v: ::std::string::String) { + self.openai_key = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_openai_key(&mut self) -> &mut ::std::string::String { + &mut self.openai_key + } + + // Take field + pub fn take_openai_key(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.openai_key, ::std::string::String::new()) + } + + // .AuthenticatorPB authenticator = 7; + + + pub fn get_authenticator(&self) -> super::auth::AuthenticatorPB { + self.authenticator + } + pub fn clear_authenticator(&mut self) { + self.authenticator = super::auth::AuthenticatorPB::Local; + } + + // Param is passed by value, moved + pub fn set_authenticator(&mut self, v: super::auth::AuthenticatorPB) { + self.authenticator = v; + } + + // string encryption_sign = 8; + + + pub fn get_encryption_sign(&self) -> &str { + &self.encryption_sign + } + pub fn clear_encryption_sign(&mut self) { + self.encryption_sign.clear(); + } + + // Param is passed by value, moved + pub fn set_encryption_sign(&mut self, v: ::std::string::String) { + self.encryption_sign = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_encryption_sign(&mut self) -> &mut ::std::string::String { + &mut self.encryption_sign + } + + // Take field + pub fn take_encryption_sign(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.encryption_sign, ::std::string::String::new()) + } + + // string workspace_id = 9; + + + pub fn get_workspace_id(&self) -> &str { + &self.workspace_id + } + pub fn clear_workspace_id(&mut self) { + self.workspace_id.clear(); + } + + // Param is passed by value, moved + pub fn set_workspace_id(&mut self, v: ::std::string::String) { + self.workspace_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_workspace_id(&mut self) -> &mut ::std::string::String { + &mut self.workspace_id + } + + // Take field + pub fn take_workspace_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.workspace_id, ::std::string::String::new()) + } + + // string stability_ai_key = 10; + + + pub fn get_stability_ai_key(&self) -> &str { + &self.stability_ai_key + } + pub fn clear_stability_ai_key(&mut self) { + self.stability_ai_key.clear(); + } + + // Param is passed by value, moved + pub fn set_stability_ai_key(&mut self, v: ::std::string::String) { + self.stability_ai_key = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_stability_ai_key(&mut self) -> &mut ::std::string::String { + &mut self.stability_ai_key + } + + // Take field + pub fn take_stability_ai_key(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.stability_ai_key, ::std::string::String::new()) + } +} + +impl ::protobuf::Message for UserProfilePB { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int64()?; + self.id = tmp; + }, + 2 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.email)?; + }, + 3 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.name)?; + }, + 4 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.token)?; + }, + 5 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.icon_url)?; + }, + 6 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.openai_key)?; + }, + 7 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.authenticator, 7, &mut self.unknown_fields)? + }, + 8 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.encryption_sign)?; + }, + 9 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.workspace_id)?; + }, + 10 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.stability_ai_key)?; + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if self.id != 0 { + my_size += ::protobuf::rt::value_size(1, self.id, ::protobuf::wire_format::WireTypeVarint); + } + if !self.email.is_empty() { + my_size += ::protobuf::rt::string_size(2, &self.email); + } + if !self.name.is_empty() { + my_size += ::protobuf::rt::string_size(3, &self.name); + } + if !self.token.is_empty() { + my_size += ::protobuf::rt::string_size(4, &self.token); + } + if !self.icon_url.is_empty() { + my_size += ::protobuf::rt::string_size(5, &self.icon_url); + } + if !self.openai_key.is_empty() { + my_size += ::protobuf::rt::string_size(6, &self.openai_key); + } + if self.authenticator != super::auth::AuthenticatorPB::Local { + my_size += ::protobuf::rt::enum_size(7, self.authenticator); + } + if !self.encryption_sign.is_empty() { + my_size += ::protobuf::rt::string_size(8, &self.encryption_sign); + } + if !self.workspace_id.is_empty() { + my_size += ::protobuf::rt::string_size(9, &self.workspace_id); + } + if !self.stability_ai_key.is_empty() { + my_size += ::protobuf::rt::string_size(10, &self.stability_ai_key); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if self.id != 0 { + os.write_int64(1, self.id)?; + } + if !self.email.is_empty() { + os.write_string(2, &self.email)?; + } + if !self.name.is_empty() { + os.write_string(3, &self.name)?; + } + if !self.token.is_empty() { + os.write_string(4, &self.token)?; + } + if !self.icon_url.is_empty() { + os.write_string(5, &self.icon_url)?; + } + if !self.openai_key.is_empty() { + os.write_string(6, &self.openai_key)?; + } + if self.authenticator != super::auth::AuthenticatorPB::Local { + os.write_enum(7, ::protobuf::ProtobufEnum::value(&self.authenticator))?; + } + if !self.encryption_sign.is_empty() { + os.write_string(8, &self.encryption_sign)?; + } + if !self.workspace_id.is_empty() { + os.write_string(9, &self.workspace_id)?; + } + if !self.stability_ai_key.is_empty() { + os.write_string(10, &self.stability_ai_key)?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> UserProfilePB { + UserProfilePB::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>( + "id", + |m: &UserProfilePB| { &m.id }, + |m: &mut UserProfilePB| { &mut m.id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "email", + |m: &UserProfilePB| { &m.email }, + |m: &mut UserProfilePB| { &mut m.email }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "name", + |m: &UserProfilePB| { &m.name }, + |m: &mut UserProfilePB| { &mut m.name }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "token", + |m: &UserProfilePB| { &m.token }, + |m: &mut UserProfilePB| { &mut m.token }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "icon_url", + |m: &UserProfilePB| { &m.icon_url }, + |m: &mut UserProfilePB| { &mut m.icon_url }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "openai_key", + |m: &UserProfilePB| { &m.openai_key }, + |m: &mut UserProfilePB| { &mut m.openai_key }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "authenticator", + |m: &UserProfilePB| { &m.authenticator }, + |m: &mut UserProfilePB| { &mut m.authenticator }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "encryption_sign", + |m: &UserProfilePB| { &m.encryption_sign }, + |m: &mut UserProfilePB| { &mut m.encryption_sign }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "workspace_id", + |m: &UserProfilePB| { &m.workspace_id }, + |m: &mut UserProfilePB| { &mut m.workspace_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "stability_ai_key", + |m: &UserProfilePB| { &m.stability_ai_key }, + |m: &mut UserProfilePB| { &mut m.stability_ai_key }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "UserProfilePB", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static UserProfilePB { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(UserProfilePB::new) + } +} + +impl ::protobuf::Clear for UserProfilePB { + fn clear(&mut self) { + self.id = 0; + self.email.clear(); + self.name.clear(); + self.token.clear(); + self.icon_url.clear(); + self.openai_key.clear(); + self.authenticator = super::auth::AuthenticatorPB::Local; + self.encryption_sign.clear(); + self.workspace_id.clear(); + self.stability_ai_key.clear(); + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for UserProfilePB { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for UserProfilePB { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum EncryptionTypePB { + NoEncryption = 0, + Symmetric = 1, +} + +impl ::protobuf::ProtobufEnum for EncryptionTypePB { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(EncryptionTypePB::NoEncryption), + 1 => ::std::option::Option::Some(EncryptionTypePB::Symmetric), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [EncryptionTypePB] = &[ + EncryptionTypePB::NoEncryption, + EncryptionTypePB::Symmetric, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("EncryptionTypePB", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for EncryptionTypePB { +} + +impl ::std::default::Default for EncryptionTypePB { + fn default() -> Self { + EncryptionTypePB::NoEncryption + } +} + +impl ::protobuf::reflect::ProtobufValue for EncryptionTypePB { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\nuser.proto\x1a\nauth.proto\"\xc7\x02\n\rUserProfilePB\x12\x0e\n\x02i\ + d\x18\x01\x20\x01(\x03R\x02id\x12\x14\n\x05email\x18\x02\x20\x01(\tR\x05\ + email\x12\x12\n\x04name\x18\x03\x20\x01(\tR\x04name\x12\x14\n\x05token\ + \x18\x04\x20\x01(\tR\x05token\x12\x19\n\x08icon_url\x18\x05\x20\x01(\tR\ + \x07iconUrl\x12\x1d\n\nopenai_key\x18\x06\x20\x01(\tR\topenaiKey\x126\n\ + \rauthenticator\x18\x07\x20\x01(\x0e2\x10.AuthenticatorPBR\rauthenticato\ + r\x12'\n\x0fencryption_sign\x18\x08\x20\x01(\tR\x0eencryptionSign\x12!\n\ + \x0cworkspace_id\x18\t\x20\x01(\tR\x0bworkspaceId\x12(\n\x10stability_ai\ + _key\x18\n\x20\x01(\tR\x0estabilityAiKey*3\n\x10EncryptionTypePB\x12\x10\ + \n\x0cNoEncryption\x10\0\x12\r\n\tSymmetric\x10\x01b\x06proto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/appflowy_web/wasm-libs/af-wasm/Cargo.toml b/frontend/appflowy_web/wasm-libs/af-wasm/Cargo.toml new file mode 100644 index 0000000000..8e2e4ff2ed --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-wasm/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "af-wasm" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +wasm-bindgen = { version = "0.2.89" } +lazy_static = "1.4.0" +lib-dispatch = { workspace = true, features = ["use_serde"] } +parking_lot.workspace = true +tracing.workspace = true +tracing-core = { version = "0.1.32" } +tracing-wasm = "0.2.1" +serde.workspace = true +collab-integrate = { workspace = true, features = ["enable_wasm"] } +tokio-stream.workspace = true + +af-user.workspace = true +flowy-notification = { workspace = true, features = ["web_ts"] } +flowy-user-pub = { workspace = true } +flowy-server = { workspace = true, features = ["enable_wasm"] } +flowy-server-pub = { workspace = true } +flowy-error = { workspace = true, features = ["impl_from_dispatch_error", "web_ts"] } +flowy-document = { workspace = true, features = ["web_ts"] } +lib-infra = { workspace = true } +collab = { workspace = true, features = ["wasm_build", "async-plugin"] } +web-sys = "0.3" +wasm-bindgen-futures.workspace = true +uuid.workspace = true +serde-wasm-bindgen.workspace = true +js-sys = "0.3.67" + +[dev-dependencies] +wasm-bindgen-test = "0.3.40" +tokio = { version = "1.0", features = ["sync"] } + +[features] +localhost_dev = [] \ No newline at end of file diff --git a/frontend/appflowy_web/wasm-libs/af-wasm/src/core.rs b/frontend/appflowy_web/wasm-libs/af-wasm/src/core.rs new file mode 100644 index 0000000000..088d8c889e --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-wasm/src/core.rs @@ -0,0 +1,45 @@ +use crate::integrate::server::ServerProviderWASM; +use af_user::manager::UserManagerWASM; +use collab_integrate::collab_builder::AppFlowyCollabBuilder; +use flowy_error::FlowyResult; +use flowy_server_pub::af_cloud_config::AFCloudConfiguration; +use lib_dispatch::prelude::AFPluginDispatcher; +use lib_dispatch::runtime::AFPluginRuntime; +use std::rc::Rc; +use std::sync::Arc; + +pub struct AppFlowyWASMCore { + pub collab_builder: Arc, + pub event_dispatcher: Rc, + pub user_manager: Rc, +} + +impl AppFlowyWASMCore { + pub async fn new(device_id: &str, cloud_config: AFCloudConfiguration) -> FlowyResult { + let runtime = Arc::new(AFPluginRuntime::new().unwrap()); + let server_provider = Rc::new(ServerProviderWASM::new(device_id, cloud_config)); + let collab_builder = Arc::new(AppFlowyCollabBuilder::new( + server_provider.clone(), + device_id.to_string(), + )); + + let user_manager = Rc::new( + UserManagerWASM::new( + device_id, + server_provider.clone(), + Arc::downgrade(&collab_builder), + ) + .await?, + ); + + let event_dispatcher = Rc::new(AFPluginDispatcher::new( + runtime, + vec![af_user::event_map::init(Rc::downgrade(&user_manager))], + )); + Ok(Self { + collab_builder, + event_dispatcher, + user_manager, + }) + } +} diff --git a/frontend/appflowy_web/wasm-libs/af-wasm/src/integrate/mod.rs b/frontend/appflowy_web/wasm-libs/af-wasm/src/integrate/mod.rs new file mode 100644 index 0000000000..74f47ad347 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-wasm/src/integrate/mod.rs @@ -0,0 +1 @@ +pub mod server; diff --git a/frontend/appflowy_web/wasm-libs/af-wasm/src/integrate/server.rs b/frontend/appflowy_web/wasm-libs/af-wasm/src/integrate/server.rs new file mode 100644 index 0000000000..ea62fc49fb --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-wasm/src/integrate/server.rs @@ -0,0 +1,106 @@ +use collab::preclude::CollabPlugin; +use collab_integrate::collab_builder::{ + CollabCloudPluginProvider, CollabPluginProviderContext, CollabPluginProviderType, +}; +use flowy_error::FlowyError; +use flowy_server::af_cloud::AppFlowyCloudServer; +use flowy_server::AppFlowyServer; +use flowy_server_pub::af_cloud_config::AFCloudConfiguration; +use flowy_user_pub::cloud::{ + UserCloudService, UserCloudServiceProvider, UserCloudServiceProviderBase, +}; +use flowy_user_pub::entities::{Authenticator, UserTokenState}; +use lib_infra::future::{to_fut, Fut}; +use parking_lot::RwLock; +use std::rc::Rc; +use std::sync::Arc; +use tokio_stream::wrappers::WatchStream; +use tracing::{info, warn}; + +pub struct ServerProviderWASM { + device_id: String, + config: AFCloudConfiguration, + server: RwLock>>, +} + +impl ServerProviderWASM { + pub fn new(device_id: &str, config: AFCloudConfiguration) -> Self { + info!("Server config: {}", config); + Self { + device_id: device_id.to_string(), + server: RwLock::new(Default::default()), + config, + } + } + + pub fn get_server(&self) -> Rc { + let server = self.server.read().as_ref().cloned(); + match server { + Some(server) => server, + None => { + let server = Rc::new(AppFlowyCloudServer::new( + self.config.clone(), + true, + self.device_id.clone(), + )); + *self.server.write() = Some(server.clone()); + server + }, + } + } +} + +impl CollabCloudPluginProvider for ServerProviderWASM { + fn provider_type(&self) -> CollabPluginProviderType { + CollabPluginProviderType::AppFlowyCloud + } + + fn get_plugins(&self, _context: CollabPluginProviderContext) -> Fut>> { + to_fut(async move { vec![] }) + } + + fn is_sync_enabled(&self) -> bool { + true + } +} + +impl UserCloudServiceProvider for ServerProviderWASM {} + +impl UserCloudServiceProviderBase for ServerProviderWASM { + fn set_token(&self, token: &str) -> Result<(), FlowyError> { + self.get_server().set_token(token)?; + Ok(()) + } + + fn subscribe_token_state(&self) -> Option> { + self.get_server().subscribe_token_state() + } + + fn set_enable_sync(&self, _uid: i64, _enable_sync: bool) { + warn!("enable sync is not supported in wasm") + } + + fn set_user_authenticator(&self, _authenticator: &Authenticator) { + warn!("set user authenticator is not supported in wasm") + } + + fn get_user_authenticator(&self) -> Authenticator { + Authenticator::AppFlowyCloud + } + + fn set_network_reachable(&self, _reachable: bool) { + warn!("set network reachable is not supported in wasm") + } + + fn set_encrypt_secret(&self, _secret: String) { + warn!("set encrypt secret is not supported in wasm") + } + + fn get_user_service(&self) -> Result, FlowyError> { + Ok(self.get_server().user_service()) + } + + fn service_url(&self) -> String { + self.config.base_url.clone() + } +} diff --git a/frontend/appflowy_web/wasm-libs/af-wasm/src/lib.rs b/frontend/appflowy_web/wasm-libs/af-wasm/src/lib.rs new file mode 100644 index 0000000000..e0a88cc8cf --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-wasm/src/lib.rs @@ -0,0 +1,161 @@ +use crate::notification::TSNotificationSender; +use flowy_notification::{register_notification_sender, unregister_all_notification_sender}; +use std::cell::RefCell; +use std::rc::Rc; + +pub mod core; +mod integrate; +pub mod notification; + +use crate::core::AppFlowyWASMCore; +use lazy_static::lazy_static; +use lib_dispatch::prelude::{ + AFPluginDispatcher, AFPluginEventResponse, AFPluginRequest, StatusCode, +}; + +use flowy_server_pub::af_cloud_config::AFCloudConfiguration; +use tracing::{error, info}; +use wasm_bindgen::prelude::wasm_bindgen; +use wasm_bindgen::JsValue; +use wasm_bindgen_futures::{future_to_promise, js_sys}; + +lazy_static! { + static ref APPFLOWY_CORE: RefCellAppFlowyCore = RefCellAppFlowyCore::new(); +} + +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace = console)] + pub fn log(s: &str); + #[wasm_bindgen(js_namespace = window)] + fn onFlowyNotify(event_name: &str, payload: JsValue); +} +#[wasm_bindgen] +pub fn init_tracing_log() { + tracing_wasm::set_as_global_default(); +} + +#[wasm_bindgen] +pub fn init_wasm_core() -> js_sys::Promise { + #[cfg(feature = "localhost_dev")] + let config = AFCloudConfiguration { + base_url: "http://localhost".to_string(), + ws_base_url: "ws://localhost/ws".to_string(), + gotrue_url: "http://localhost/gotrue".to_string(), + }; + + #[cfg(not(feature = "localhost_dev"))] + let config = AFCloudConfiguration { + base_url: "https://beta.appflowy.cloud".to_string(), + ws_base_url: "wss://beta.appflowy.cloud/ws".to_string(), + gotrue_url: "https://beta.appflowy.cloud/gotrue".to_string(), + }; + + let future = async move { + if let Ok(core) = AppFlowyWASMCore::new("device_id", config).await { + *APPFLOWY_CORE.0.borrow_mut() = Some(core); + info!("🔥🔥🔥Initialized AppFlowyWASMCore"); + } else { + error!("Failed to initialize AppFlowyWASMCore") + } + Ok(JsValue::from_str("")) + }; + future_to_promise(future) +} + +#[wasm_bindgen] +pub fn async_event(name: String, payload: Vec) -> js_sys::Promise { + if let Some(dispatcher) = APPFLOWY_CORE.dispatcher() { + let future = async move { + let request = WasmRequest::new(name, payload); + let event_resp = + AFPluginDispatcher::boxed_async_send_with_callback(dispatcher.as_ref(), request, |_| { + Box::pin(async {}) + }) + .await; + + let response = WasmResponse::from(event_resp); + serde_wasm_bindgen::to_value(&response).map_err(error_response) + }; + + future_to_promise(future) + } else { + future_to_promise(async { Err(JsValue::from_str("Dispatcher is not initialized")) }) + } +} + +#[wasm_bindgen] +pub fn register_listener() { + unregister_all_notification_sender(); + register_notification_sender(TSNotificationSender::new()); +} + +pub fn on_event(event_name: &str, args: JsValue) { + onFlowyNotify(event_name, args); +} + +struct RefCellAppFlowyCore(RefCell>); + +/// safety: +/// In a WebAssembly, implement the Sync for RefCellAppFlowyCore is safety +/// since WASM currently operates in a single-threaded environment. +unsafe impl Sync for RefCellAppFlowyCore {} + +impl RefCellAppFlowyCore { + fn new() -> Self { + Self(RefCell::new(None)) + } + + fn dispatcher(&self) -> Option> { + self + .0 + .borrow() + .as_ref() + .map(|core| core.event_dispatcher.clone()) + } +} + +fn error_response(error: serde_wasm_bindgen::Error) -> JsValue { + error!("Error: {}", error); + serde_wasm_bindgen::to_value(&WasmResponse::error(error.to_string())).unwrap() +} + +pub struct WasmRequest { + name: String, + payload: Vec, +} + +impl WasmRequest { + pub fn new(name: String, payload: Vec) -> Self { + Self { name, payload } + } +} + +impl From for AFPluginRequest { + fn from(request: WasmRequest) -> Self { + AFPluginRequest::new(request.name).payload(request.payload) + } +} + +#[derive(serde::Serialize)] +pub struct WasmResponse { + pub code: i8, + pub payload: Vec, +} +impl WasmResponse { + pub fn error(msg: String) -> Self { + Self { + code: StatusCode::Err as i8, + payload: msg.into_bytes(), + } + } +} + +impl From for WasmResponse { + fn from(response: AFPluginEventResponse) -> Self { + Self { + code: response.status_code as i8, + payload: response.payload.to_vec(), + } + } +} diff --git a/frontend/appflowy_web/appflowy-wasm/src/notification.rs b/frontend/appflowy_web/wasm-libs/af-wasm/src/notification.rs similarity index 100% rename from frontend/appflowy_web/appflowy-wasm/src/notification.rs rename to frontend/appflowy_web/wasm-libs/af-wasm/src/notification.rs diff --git a/frontend/appflowy_web/wasm-libs/af-wasm/tests/main.rs b/frontend/appflowy_web/wasm-libs/af-wasm/tests/main.rs new file mode 100644 index 0000000000..0498e45195 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-wasm/tests/main.rs @@ -0,0 +1,4 @@ +use wasm_bindgen_test::wasm_bindgen_test_configure; +wasm_bindgen_test_configure!(run_in_browser); +mod user; +pub(crate) mod util; diff --git a/frontend/appflowy_web/wasm-libs/af-wasm/tests/user/event_test.rs b/frontend/appflowy_web/wasm-libs/af-wasm/tests/user/event_test.rs new file mode 100644 index 0000000000..d053043e7e --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-wasm/tests/user/event_test.rs @@ -0,0 +1,10 @@ +use crate::util::tester::{unique_email, WASMEventTester}; +use wasm_bindgen_test::wasm_bindgen_test; + +#[wasm_bindgen_test] +async fn sign_up_event_test() { + let tester = WASMEventTester::new().await; + let email = unique_email(); + let user_profile = tester.sign_in_with_email(&email).await.unwrap(); + assert_eq!(user_profile.email, email); +} diff --git a/frontend/appflowy_web/wasm-libs/af-wasm/tests/user/mod.rs b/frontend/appflowy_web/wasm-libs/af-wasm/tests/user/mod.rs new file mode 100644 index 0000000000..83ac8063ea --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-wasm/tests/user/mod.rs @@ -0,0 +1 @@ +mod event_test; diff --git a/frontend/appflowy_web/wasm-libs/af-wasm/tests/util/event_builder.rs b/frontend/appflowy_web/wasm-libs/af-wasm/tests/util/event_builder.rs new file mode 100644 index 0000000000..99185a6837 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-wasm/tests/util/event_builder.rs @@ -0,0 +1,132 @@ +use af_wasm::core::AppFlowyWASMCore; +use flowy_error::{internal_error, FlowyError}; +use std::rc::Rc; +use std::{ + convert::TryFrom, + fmt::{Debug, Display}, + hash::Hash, + sync::Arc, +}; + +use lib_dispatch::prelude::{ + AFPluginDispatcher, AFPluginEventResponse, AFPluginFromBytes, AFPluginRequest, ToBytes, *, +}; + +#[derive(Clone)] +pub struct EventBuilder { + context: TestContext, +} + +impl EventBuilder { + pub fn new(core: Arc) -> Self { + Self { + context: TestContext::new(core), + } + } + + pub fn payload

(mut self, payload: P) -> Self + where + P: ToBytes, + { + match payload.into_bytes() { + Ok(bytes) => { + let module_request = self.take_request(); + self.context.request = Some(module_request.payload(bytes)) + }, + Err(e) => { + tracing::error!("Set payload failed: {:?}", e); + }, + } + self + } + + pub fn event(mut self, event: Event) -> Self + where + Event: Eq + Hash + Debug + Clone + Display, + { + self.context.request = Some(AFPluginRequest::new(event)); + self + } + + pub async fn async_send(mut self) -> Self { + let request = self.take_request(); + let resp = AFPluginDispatcher::async_send(self.dispatch().as_ref(), request).await; + self.context.response = Some(resp); + self + } + + pub fn parse(self) -> R + where + R: AFPluginFromBytes, + { + let response = self.get_response(); + match response.clone().parse::() { + Ok(Ok(data)) => data, + Ok(Err(e)) => { + panic!( + "Parser {:?} failed: {:?}, response {:?}", + std::any::type_name::(), + e, + response + ) + }, + Err(e) => panic!( + "Dispatch {:?} failed: {:?}, response {:?}", + std::any::type_name::(), + e, + response + ), + } + } + + #[allow(dead_code)] + pub fn try_parse(self) -> Result + where + R: AFPluginFromBytes, + { + let response = self.get_response(); + response.parse::().map_err(internal_error)? + } + + #[allow(dead_code)] + pub fn error(self) -> Option { + let response = self.get_response(); + >::try_from(response.payload) + .ok() + .map(|data| data.into_inner()) + } + + fn dispatch(&self) -> &Rc { + &self.context.sdk.event_dispatcher + } + + fn get_response(&self) -> AFPluginEventResponse { + self + .context + .response + .as_ref() + .expect("must call sync_send/async_send first") + .clone() + } + + fn take_request(&mut self) -> AFPluginRequest { + self.context.request.take().expect("must call event first") + } +} + +#[derive(Clone)] +pub struct TestContext { + pub sdk: Arc, + request: Option, + response: Option, +} + +impl TestContext { + pub fn new(sdk: Arc) -> Self { + Self { + sdk, + request: None, + response: None, + } + } +} diff --git a/frontend/appflowy_web/wasm-libs/af-wasm/tests/util/mod.rs b/frontend/appflowy_web/wasm-libs/af-wasm/tests/util/mod.rs new file mode 100644 index 0000000000..8458398ffd --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-wasm/tests/util/mod.rs @@ -0,0 +1,2 @@ +mod event_builder; +pub mod tester; diff --git a/frontend/appflowy_web/wasm-libs/af-wasm/tests/util/tester.rs b/frontend/appflowy_web/wasm-libs/af-wasm/tests/util/tester.rs new file mode 100644 index 0000000000..3a5edde679 --- /dev/null +++ b/frontend/appflowy_web/wasm-libs/af-wasm/tests/util/tester.rs @@ -0,0 +1,62 @@ +use crate::util::event_builder::EventBuilder; +use af_user::entities::*; +use af_user::event_map::UserWasmEvent::*; +use af_wasm::core::AppFlowyWASMCore; +use flowy_error::FlowyResult; + +use flowy_server_pub::af_cloud_config::AFCloudConfiguration; +use parking_lot::Once; + +use std::sync::Arc; +use uuid::Uuid; + +pub struct WASMEventTester { + core: Arc, +} + +impl WASMEventTester { + pub async fn new() -> Self { + setup_log(); + let config = AFCloudConfiguration { + base_url: "http://localhost".to_string(), + ws_base_url: "ws://localhost/ws".to_string(), + gotrue_url: "http://localhost/gotrue".to_string(), + }; + let core = Arc::new(AppFlowyWASMCore::new("device_id", config).await.unwrap()); + Self { core } + } + + pub async fn sign_in_with_email(&self, email: &str) -> FlowyResult { + let email = email.to_string(); + let password = "AppFlowy!2024".to_string(); + let payload = AddUserPB { + email: email.clone(), + password: password.clone(), + }; + EventBuilder::new(self.core.clone()) + .event(AddUser) + .payload(payload) + .async_send() + .await; + + let payload = UserSignInPB { email, password }; + let user_profile = EventBuilder::new(self.core.clone()) + .event(SignInPassword) + .payload(payload) + .async_send() + .await + .parse::(); + Ok(user_profile) + } +} + +pub fn unique_email() -> String { + format!("{}@appflowy.io", Uuid::new_v4()) +} + +pub fn setup_log() { + static START: Once = Once::new(); + START.call_once(|| { + tracing_wasm::set_as_global_default(); + }); +} diff --git a/frontend/appflowy_web/appflowy-wasm/rust-toolchain.toml b/frontend/appflowy_web/wasm-libs/rust-toolchain.toml similarity index 100% rename from frontend/appflowy_web/appflowy-wasm/rust-toolchain.toml rename to frontend/appflowy_web/wasm-libs/rust-toolchain.toml diff --git a/frontend/appflowy_web/appflowy-wasm/rustfmt.toml b/frontend/appflowy_web/wasm-libs/rustfmt.toml similarity index 100% rename from frontend/appflowy_web/appflowy-wasm/rustfmt.toml rename to frontend/appflowy_web/wasm-libs/rustfmt.toml diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 88c9e12342..07cc1a8f34 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -64,6 +64,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "again" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05802a5ad4d172eaf796f7047b42d0af9db513585d16d4169660a21613d34b93" +dependencies = [ + "log", + "rand 0.7.3", + "wasm-timer", +] + [[package]] name = "ahash" version = "0.7.6" @@ -152,7 +163,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "bincode", @@ -603,9 +614,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" dependencies = [ "android-tzdata", "iana-time-zone", @@ -613,7 +624,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets", + "windows-targets 0.52.0", ] [[package]] @@ -662,8 +673,9 @@ dependencies = [ [[package]] name = "client-api" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ + "again", "anyhow", "app-error", "async-trait", @@ -681,7 +693,7 @@ dependencies = [ "gotrue-entity", "mime", "mime_guess", - "parking_lot", + "parking_lot 0.12.1", "prost", "realtime-entity", "realtime-protocol", @@ -690,15 +702,16 @@ dependencies = [ "serde", "serde_json", "serde_repr", - "shared_entity", + "shared-entity", "thiserror", "tokio", "tokio-retry", "tokio-stream", - "tokio-tungstenite", "tracing", "url", "uuid", + "wasm-bindgen-futures", + "websocket", "workspace-template", "yrs", ] @@ -731,14 +744,14 @@ dependencies = [ [[package]] name = "collab" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3eef93f35f606edef2541888cb91cd6686d77225#3eef93f35f606edef2541888cb91cd6686d77225" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" dependencies = [ "anyhow", "async-trait", "bincode", "bytes", "js-sys", - "parking_lot", + "parking_lot 0.12.1", "serde", "serde_json", "serde_repr", @@ -753,7 +766,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3eef93f35f606edef2541888cb91cd6686d77225#3eef93f35f606edef2541888cb91cd6686d77225" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" dependencies = [ "anyhow", "async-trait", @@ -765,7 +778,7 @@ dependencies = [ "lazy_static", "lru", "nanoid", - "parking_lot", + "parking_lot 0.12.1", "serde", "serde_json", "serde_repr", @@ -781,14 +794,14 @@ dependencies = [ [[package]] name = "collab-document" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3eef93f35f606edef2541888cb91cd6686d77225#3eef93f35f606edef2541888cb91cd6686d77225" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" dependencies = [ "anyhow", "collab", "collab-entity", "getrandom 0.2.10", "nanoid", - "parking_lot", + "parking_lot 0.12.1", "serde", "serde_json", "thiserror", @@ -800,7 +813,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3eef93f35f606edef2541888cb91cd6686d77225#3eef93f35f606edef2541888cb91cd6686d77225" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" dependencies = [ "anyhow", "bytes", @@ -814,13 +827,13 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3eef93f35f606edef2541888cb91cd6686d77225#3eef93f35f606edef2541888cb91cd6686d77225" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" dependencies = [ "anyhow", "chrono", "collab", "collab-entity", - "parking_lot", + "parking_lot 0.12.1", "serde", "serde_json", "serde_repr", @@ -840,7 +853,7 @@ dependencies = [ "collab-entity", "collab-plugins", "lib-infra", - "parking_lot", + "parking_lot 0.12.1", "serde", "serde_json", "tokio", @@ -850,7 +863,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3eef93f35f606edef2541888cb91cd6686d77225#3eef93f35f606edef2541888cb91cd6686d77225" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" dependencies = [ "anyhow", "async-stream", @@ -866,7 +879,7 @@ dependencies = [ "indexed_db_futures", "js-sys", "lazy_static", - "parking_lot", + "parking_lot 0.12.1", "rand 0.8.5", "rocksdb", "serde", @@ -889,12 +902,12 @@ dependencies = [ [[package]] name = "collab-user" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=3eef93f35f606edef2541888cb91cd6686d77225#3eef93f35f606edef2541888cb91cd6686d77225" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=e3620ae820e921955b9c3ca3ffee24aad544f972#e3620ae820e921955b9c3ca3ffee24aad544f972" dependencies = [ "anyhow", "collab", "collab-entity", - "parking_lot", + "parking_lot 0.12.1", "serde", "serde_json", "tokio", @@ -1174,15 +1187,19 @@ dependencies = [ "collab-integrate", "crossbeam-utils", "flowy-codegen", + "flowy-config", "flowy-core", + "flowy-date", "flowy-derive", + "flowy-document", "flowy-error", "flowy-notification", "flowy-server", "flowy-server-pub", + "flowy-user", "lazy_static", "lib-dispatch", - "parking_lot", + "parking_lot 0.12.1", "protobuf", "serde", "serde_json", @@ -1202,7 +1219,7 @@ dependencies = [ "hashbrown 0.14.3", "lock_api", "once_cell", - "parking_lot_core", + "parking_lot_core 0.9.8", ] [[package]] @@ -1214,7 +1231,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "app-error", @@ -1497,7 +1514,7 @@ dependencies = [ "lib-dispatch", "lib-infra", "nanoid", - "parking_lot", + "parking_lot 0.12.1", "protobuf", "rand 0.8.5", "serde", @@ -1704,7 +1721,7 @@ dependencies = [ "lib-dispatch", "lib-infra", "lib-log", - "parking_lot", + "parking_lot 0.12.1", "serde", "serde_json", "serde_repr", @@ -1756,7 +1773,7 @@ dependencies = [ "lib-infra", "lru", "nanoid", - "parking_lot", + "parking_lot 0.12.1", "protobuf", "rayon", "rust_decimal", @@ -1827,7 +1844,7 @@ dependencies = [ "lib-infra", "lru", "nanoid", - "parking_lot", + "parking_lot 0.12.1", "protobuf", "scraper 0.18.1", "serde", @@ -1914,7 +1931,7 @@ dependencies = [ "lib-dispatch", "lib-infra", "nanoid", - "parking_lot", + "parking_lot 0.12.1", "protobuf", "serde_json", "strum_macros 0.21.1", @@ -1983,7 +2000,7 @@ dependencies = [ "lib-dispatch", "lib-infra", "mime_guess", - "parking_lot", + "parking_lot 0.12.1", "postgrest", "reqwest", "serde", @@ -2020,7 +2037,7 @@ dependencies = [ "libsqlite3-sys", "openssl", "openssl-sys", - "parking_lot", + "parking_lot 0.12.1", "r2d2", "scheduled-thread-pool", "serde", @@ -2083,7 +2100,7 @@ dependencies = [ "lib-infra", "nanoid", "once_cell", - "parking_lot", + "parking_lot 0.12.1", "protobuf", "quickcheck", "quickcheck_macros", @@ -2107,6 +2124,7 @@ name = "flowy-user-pub" version = "0.1.0" dependencies = [ "anyhow", + "base64 0.21.5", "chrono", "collab", "collab-entity", @@ -2118,6 +2136,7 @@ dependencies = [ "serde_repr", "tokio", "tokio-stream", + "tracing", "uuid", ] @@ -2381,7 +2400,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "futures-util", @@ -2398,10 +2417,11 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "app-error", + "chrono", "jsonwebtoken", "lazy_static", "serde", @@ -2773,7 +2793,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "reqwest", @@ -2831,9 +2851,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -2878,7 +2898,7 @@ dependencies = [ "futures-util", "getrandom 0.2.10", "nanoid", - "parking_lot", + "parking_lot 0.12.1", "pin-project", "protobuf", "serde", @@ -2889,6 +2909,7 @@ dependencies = [ "tracing", "validator", "wasm-bindgen", + "wasm-bindgen-futures", ] [[package]] @@ -3390,6 +3411,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -3397,7 +3429,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core", + "parking_lot_core 0.9.8", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", ] [[package]] @@ -3410,7 +3456,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -4038,7 +4084,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" dependencies = [ "log", - "parking_lot", + "parking_lot 0.12.1", "scheduled-thread-pool", ] @@ -4191,7 +4237,7 @@ dependencies = [ [[package]] name = "realtime-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "bincode", @@ -4207,13 +4253,14 @@ dependencies = [ "serde_json", "thiserror", "tokio-tungstenite", + "websocket", "yrs", ] [[package]] name = "realtime-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "bincode", @@ -4229,6 +4276,15 @@ version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -4567,7 +4623,7 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" dependencies = [ - "parking_lot", + "parking_lot 0.12.1", ] [[package]] @@ -4790,9 +4846,9 @@ dependencies = [ ] [[package]] -name = "shared_entity" +name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "app-error", @@ -4932,7 +4988,7 @@ checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ "new_debug_unreachable", "once_cell", - "parking_lot", + "parking_lot 0.12.1", "phf_shared 0.10.0", "precomputed-hash", "serde", @@ -5220,7 +5276,7 @@ dependencies = [ "libc", "mio", "num_cpus", - "parking_lot", + "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", "socket2 0.5.5", @@ -5273,7 +5329,7 @@ dependencies = [ "futures-channel", "futures-util", "log", - "parking_lot", + "parking_lot 0.12.1", "percent-encoding", "phf 0.11.2", "pin-project-lite", @@ -5856,9 +5912,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -5866,9 +5922,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", @@ -5881,9 +5937,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" dependencies = [ "cfg-if", "js-sys", @@ -5893,9 +5949,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5903,9 +5959,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", @@ -5916,9 +5972,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "wasm-streams" @@ -5933,6 +5989,21 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasm-timer" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.11.2", + "pin-utils", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "web-sys" version = "0.3.64" @@ -5949,6 +6020,23 @@ version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +[[package]] +name = "websocket" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" +dependencies = [ + "futures-channel", + "futures-util", + "http", + "httparse", + "js-sys", + "thiserror", + "tokio", + "tokio-tungstenite", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "which" version = "4.4.2" @@ -6008,7 +6096,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -6017,7 +6105,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -6026,13 +6114,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] @@ -6041,42 +6144,84 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winnow" version = "0.5.30" @@ -6099,7 +6244,7 @@ dependencies = [ [[package]] name = "workspace-template" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ee3abdb27a2d056e7399b486354d26e802720c00#ee3abdb27a2d056e7399b486354d26e802720c00" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=69c69f6474eaa531fd822e9353cc5955b98e45eb#69c69f6474eaa531fd822e9353cc5955b98e45eb" dependencies = [ "anyhow", "async-trait", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index 3ecb7658fc..9bc2dcca26 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -66,7 +66,7 @@ serde_json = "1.0.108" serde = "1.0.194" protobuf = { version = "2.28.0" } diesel = { version = "2.1.0", features = ["sqlite", "chrono", "r2d2"] } -uuid = { version = "1.5.0", features = ["serde", "v4"] } +uuid = { version = "1.5.0", features = ["serde", "v4", "v5"] } serde_repr = "0.1" parking_lot = "0.12" futures = "0.3.29" @@ -105,7 +105,7 @@ incremental = false # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ee3abdb27a2d056e7399b486354d26e802720c00" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "69c69f6474eaa531fd822e9353cc5955b98e45eb" } # Please use the following script to update collab. # Working directory: frontend # @@ -115,10 +115,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ee3 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3eef93f35f606edef2541888cb91cd6686d77225" } -collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3eef93f35f606edef2541888cb91cd6686d77225" } -collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3eef93f35f606edef2541888cb91cd6686d77225" } -collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3eef93f35f606edef2541888cb91cd6686d77225" } -collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3eef93f35f606edef2541888cb91cd6686d77225" } -collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3eef93f35f606edef2541888cb91cd6686d77225" } -collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "3eef93f35f606edef2541888cb91cd6686d77225" } +collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } +collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "e3620ae820e921955b9c3ca3ffee24aad544f972" } diff --git a/frontend/rust-lib/build-tool/flowy-codegen/src/lib.rs b/frontend/rust-lib/build-tool/flowy-codegen/src/lib.rs index 4d4df0067a..bb5ef9301d 100644 --- a/frontend/rust-lib/build-tool/flowy-codegen/src/lib.rs +++ b/frontend/rust-lib/build-tool/flowy-codegen/src/lib.rs @@ -19,3 +19,55 @@ pub struct ProtoCache { pub structs: Vec, pub enums: Vec, } + +pub enum Project { + Tauri, + Web { relative_path: String }, + Native, +} + +impl Project { + pub fn dst(&self) -> String { + match self { + Project::Tauri => "appflowy_tauri/src/services/backend".to_string(), + Project::Web { .. } => "appflowy_web/src/services/backend".to_string(), + Project::Native => panic!("Native project is not supported yet."), + } + } + + pub fn event_root(&self) -> String { + match self { + Project::Tauri => "../../".to_string(), + Project::Web { relative_path } => relative_path.to_string(), + Project::Native => panic!("Native project is not supported yet."), + } + } + + pub fn model_root(&self) -> String { + match self { + Project::Tauri => "../../".to_string(), + Project::Web { relative_path } => relative_path.to_string(), + Project::Native => panic!("Native project is not supported yet."), + } + } + + pub fn event_imports(&self) -> String { + match self { + Project::Tauri => r#" +/// Auto generate. Do not edit +import { Ok, Err, Result } from "ts-results"; +import { invoke } from "@tauri-apps/api/tauri"; +import * as pb from "../.."; +"# + .to_string(), + Project::Web { .. } => r#" +/// Auto generate. Do not edit +import { Ok, Err, Result } from "ts-results"; +import { invoke } from "@/application/app.ts"; +import * as pb from "../.."; +"# + .to_string(), + Project::Native => panic!("Native project is not supported yet."), + } + } +} diff --git a/frontend/rust-lib/build-tool/flowy-codegen/src/protobuf_file/mod.rs b/frontend/rust-lib/build-tool/flowy-codegen/src/protobuf_file/mod.rs index a3c20c225f..ac0cdf0712 100644 --- a/frontend/rust-lib/build-tool/flowy-codegen/src/protobuf_file/mod.rs +++ b/frontend/rust-lib/build-tool/flowy-codegen/src/protobuf_file/mod.rs @@ -7,6 +7,7 @@ mod proto_info; mod template; use crate::util::path_string_with_component; +use crate::Project; use itertools::Itertools; use log::info; pub use proto_gen::*; @@ -17,16 +18,10 @@ use std::path::{Path, PathBuf}; use std::process::Command; use walkdir::WalkDir; -pub fn gen(crate_name: &str) { - let crate_path = std::fs::canonicalize(".") - .unwrap() - .as_path() - .display() - .to_string(); - +pub fn dart_gen(crate_name: &str) { // 1. generate the proto files to proto_file_dir #[cfg(feature = "proto_gen")] - let proto_crates = gen_proto_files(crate_name, &crate_path); + let proto_crates = gen_proto_files(crate_name); for proto_crate in proto_crates { let mut proto_file_paths = vec![]; @@ -70,6 +65,55 @@ pub fn gen(crate_name: &str) { &protoc_bin_path, ); + // 3. generate the protobuf files(Rust) + generate_rust_protobuf_files( + &protoc_bin_path, + &proto_file_paths, + &proto_file_output_path, + &protobuf_output_path, + ); + } +} + +#[allow(unused_variables)] +pub fn ts_gen(crate_name: &str, project: Project) { + // 1. generate the proto files to proto_file_dir + #[cfg(feature = "proto_gen")] + let proto_crates = gen_proto_files(crate_name); + + for proto_crate in proto_crates { + let mut proto_file_paths = vec![]; + let mut file_names = vec![]; + let proto_file_output_path = proto_crate + .proto_output_path() + .to_str() + .unwrap() + .to_string(); + let protobuf_output_path = proto_crate + .protobuf_crate_path() + .to_str() + .unwrap() + .to_string(); + + for (path, file_name) in WalkDir::new(&proto_file_output_path) + .into_iter() + .filter_map(|e| e.ok()) + .map(|e| { + let path = e.path().to_str().unwrap().to_string(); + let file_name = e.path().file_stem().unwrap().to_str().unwrap().to_string(); + (path, file_name) + }) + { + if path.ends_with(".proto") { + // https://stackoverflow.com/questions/49077147/how-can-i-force-build-rs-to-run-again-without-cleaning-my-whole-project + println!("cargo:rerun-if-changed={}", path); + proto_file_paths.push(path); + file_names.push(file_name); + } + } + let protoc_bin_path = protoc_bin_vendored::protoc_bin_path().unwrap(); + + // 2. generate the protobuf files(Dart) #[cfg(feature = "ts")] generate_ts_protobuf_files( crate_name, @@ -77,6 +121,7 @@ pub fn gen(crate_name: &str) { &proto_file_paths, &file_names, &protoc_bin_path, + &project, ); // 3. generate the protobuf files(Rust) @@ -111,14 +156,14 @@ fn generate_ts_protobuf_files( paths: &[String], file_names: &Vec, protoc_bin_path: &Path, + project: &Project, ) { - let root = std::env::var("CARGO_MAKE_WORKING_DIRECTORY").unwrap_or("../../".to_string()); - let tauri_backend_service_path = std::env::var("TAURI_BACKEND_SERVICE_PATH") - .unwrap_or("appflowy_tauri/src/services/backend".to_string()); + let root = project.model_root(); + let backend_service_path = project.dst(); let mut output = PathBuf::new(); output.push(root); - output.push(tauri_backend_service_path); + output.push(backend_service_path); output.push("models"); output.push(name); @@ -136,6 +181,7 @@ fn generate_ts_protobuf_files( // panic!("Generate ts pb file failed: {}, {:?}", path, err); // } + println!("cargo:rerun-if-changed={}", output.to_str().unwrap()); let result = cmd_lib::run_cmd! { ${protoc_bin_path} --ts_out=${output} --proto_path=${proto_file_output_path} ${path} }; @@ -211,7 +257,7 @@ fn generate_dart_protobuf_files( }); let protobuf_dart = path_string_with_component(&output, vec!["protobuf.dart"]); - + println!("cargo:rerun-if-changed={}", protobuf_dart); match std::fs::OpenOptions::new() .create(true) .write(true) @@ -282,8 +328,14 @@ pub fn check_pb_dart_plugin() { } #[cfg(feature = "proto_gen")] -fn gen_proto_files(crate_name: &str, crate_path: &str) -> Vec { - let crate_context = ProtoGenerator::gen(crate_name, crate_path); +pub fn gen_proto_files(crate_name: &str) -> Vec { + let crate_path = std::fs::canonicalize(".") + .unwrap() + .as_path() + .display() + .to_string(); + + let crate_context = ProtoGenerator::gen(crate_name, &crate_path); let proto_crates = crate_context .iter() .map(|info| info.protobuf_crate.clone()) diff --git a/frontend/rust-lib/build-tool/flowy-codegen/src/ts_event/mod.rs b/frontend/rust-lib/build-tool/flowy-codegen/src/ts_event/mod.rs index e3e4c12a2a..43087c4052 100644 --- a/frontend/rust-lib/build-tool/flowy-codegen/src/ts_event/mod.rs +++ b/frontend/rust-lib/build-tool/flowy-codegen/src/ts_event/mod.rs @@ -4,6 +4,7 @@ use crate::ast::EventASTContext; use crate::flowy_toml::{parse_crate_config_from, CrateConfig}; use crate::ts_event::event_template::{EventRenderContext, EventTemplate}; use crate::util::{is_crate_dir, is_hidden, path_string_with_component, read_file}; +use crate::Project; use flowy_ast::ASTResult; use std::collections::HashSet; use std::fs::File; @@ -12,10 +13,9 @@ use std::path::PathBuf; use syn::Item; use walkdir::WalkDir; -pub fn gen(crate_name: &str) { - let root = std::env::var("CARGO_MAKE_WORKING_DIRECTORY").unwrap_or("../../".to_string()); - let tauri_backend_service_path = std::env::var("TAURI_BACKEND_SERVICE_PATH") - .unwrap_or("appflowy_tauri/src/services/backend".to_string()); +pub fn gen(crate_name: &str, project: Project) { + let root = project.event_root(); + let backend_service_path = project.dst(); let crate_path = std::fs::canonicalize(".") .unwrap() @@ -29,7 +29,8 @@ pub fn gen(crate_name: &str) { .collect::>(); let event_render_ctx = ast_to_event_render_ctx(event_ast.as_ref()); - let mut render_result = TS_HEADER.to_string(); + let mut render_result = project.event_imports(); + for (index, render_ctx) in event_render_ctx.into_iter().enumerate() { let mut event_template = EventTemplate::new(); @@ -39,7 +40,7 @@ pub fn gen(crate_name: &str) { } render_result.push_str(TS_FOOTER); - let ts_event_folder: PathBuf = [&root, &tauri_backend_service_path, "events", crate_name] + let ts_event_folder: PathBuf = [&root, &backend_service_path, "events", crate_name] .iter() .collect(); if !ts_event_folder.as_path().exists() { @@ -196,12 +197,5 @@ pub fn ast_to_event_render_ctx(ast: &[EventASTContext]) -> Vec>() } -const TS_HEADER: &str = r#" -/// Auto generate. Do not edit -import { Ok, Err, Result } from "ts-results"; -import { invoke } from "@tauri-apps/api/tauri"; -import * as pb from "../.."; -"#; - const TS_FOOTER: &str = r#" "#; diff --git a/frontend/rust-lib/collab-integrate/Cargo.toml b/frontend/rust-lib/collab-integrate/Cargo.toml index f7fab8f34b..c96b0dfa53 100644 --- a/frontend/rust-lib/collab-integrate/Cargo.toml +++ b/frontend/rust-lib/collab-integrate/Cargo.toml @@ -22,4 +22,4 @@ lib-infra = { workspace = true } [features] default = [] -wasm_build = ["collab-plugins/wasm_build"] \ No newline at end of file +enable_wasm = ["collab-plugins/wasm_build"] \ No newline at end of file diff --git a/frontend/rust-lib/collab-integrate/src/collab_builder.rs b/frontend/rust-lib/collab-integrate/src/collab_builder.rs index 41210e9b5e..6efb41a01f 100644 --- a/frontend/rust-lib/collab-integrate/src/collab_builder.rs +++ b/frontend/rust-lib/collab-integrate/src/collab_builder.rs @@ -4,7 +4,7 @@ use std::sync::{Arc, Weak}; use crate::CollabKVDB; use anyhow::Error; use collab::core::collab::{CollabDocState, MutexCollab}; -use collab::preclude::{CollabBuilder, CollabPlugin}; +use collab::preclude::CollabBuilder; use collab_entity::{CollabObject, CollabType}; use collab_plugins::connect_state::{CollabConnectReachability, CollabConnectState}; use collab_plugins::local_storage::kv::snapshot::SnapshotPersistence; @@ -16,8 +16,9 @@ if_wasm! { use collab_plugins::local_storage::indexeddb::IndexeddbDiskPlugin; } +pub use crate::plugin_provider::CollabCloudPluginProvider; use collab_plugins::local_storage::CollabPersistenceConfig; -use lib_infra::future::Fut; + use lib_infra::{if_native, if_wasm}; use parking_lot::{Mutex, RwLock}; use tracing::trace; @@ -64,31 +65,6 @@ impl Display for CollabPluginProviderContext { } } -pub trait CollabCloudPluginProvider: Send + Sync + 'static { - fn provider_type(&self) -> CollabPluginProviderType; - - fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut>>; - - fn is_sync_enabled(&self) -> bool; -} - -impl CollabCloudPluginProvider for Arc -where - T: CollabCloudPluginProvider, -{ - fn provider_type(&self) -> CollabPluginProviderType { - (**self).provider_type() - } - - fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut>> { - (**self).get_plugins(context) - } - - fn is_sync_enabled(&self) -> bool { - (**self).is_sync_enabled() - } -} - pub struct AppFlowyCollabBuilder { network_reachability: CollabConnectReachability, workspace_id: RwLock>, diff --git a/frontend/rust-lib/collab-integrate/src/lib.rs b/frontend/rust-lib/collab-integrate/src/lib.rs index cf384e1241..a7df75d72e 100644 --- a/frontend/rust-lib/collab-integrate/src/lib.rs +++ b/frontend/rust-lib/collab-integrate/src/lib.rs @@ -2,8 +2,25 @@ pub use collab::core::collab::MutexCollab; pub use collab::preclude::Snapshot; pub use collab_plugins::local_storage::CollabPersistenceConfig; pub use collab_plugins::CollabKVDB; +use collab_plugins::{if_native, if_wasm}; + pub mod collab_builder; pub mod config; + +if_native! { + mod native; + mod plugin_provider { + pub use crate::native::plugin_provider::*; + } +} + +if_wasm! { + mod wasm; + mod plugin_provider { + pub use crate::wasm::plugin_provider::*; + } +} + pub use collab_plugins::local_storage::kv::doc::CollabKVAction; pub use collab_plugins::local_storage::kv::error::PersistenceError; pub use collab_plugins::local_storage::kv::snapshot::{CollabSnapshot, SnapshotPersistence}; diff --git a/frontend/rust-lib/collab-integrate/src/native/mod.rs b/frontend/rust-lib/collab-integrate/src/native/mod.rs new file mode 100644 index 0000000000..59b6b263d5 --- /dev/null +++ b/frontend/rust-lib/collab-integrate/src/native/mod.rs @@ -0,0 +1 @@ +pub mod plugin_provider; diff --git a/frontend/rust-lib/collab-integrate/src/native/plugin_provider.rs b/frontend/rust-lib/collab-integrate/src/native/plugin_provider.rs new file mode 100644 index 0000000000..d6b8ab8e34 --- /dev/null +++ b/frontend/rust-lib/collab-integrate/src/native/plugin_provider.rs @@ -0,0 +1,29 @@ +use crate::collab_builder::{CollabPluginProviderContext, CollabPluginProviderType}; +use collab::preclude::CollabPlugin; +use lib_infra::future::Fut; +use std::sync::Arc; + +pub trait CollabCloudPluginProvider: Send + Sync + 'static { + fn provider_type(&self) -> CollabPluginProviderType; + + fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut>>; + + fn is_sync_enabled(&self) -> bool; +} + +impl CollabCloudPluginProvider for Arc +where + T: CollabCloudPluginProvider, +{ + fn provider_type(&self) -> CollabPluginProviderType { + (**self).provider_type() + } + + fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut>> { + (**self).get_plugins(context) + } + + fn is_sync_enabled(&self) -> bool { + (**self).is_sync_enabled() + } +} diff --git a/frontend/rust-lib/collab-integrate/src/wasm/mod.rs b/frontend/rust-lib/collab-integrate/src/wasm/mod.rs new file mode 100644 index 0000000000..59b6b263d5 --- /dev/null +++ b/frontend/rust-lib/collab-integrate/src/wasm/mod.rs @@ -0,0 +1 @@ +pub mod plugin_provider; diff --git a/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs b/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs new file mode 100644 index 0000000000..9a954783ab --- /dev/null +++ b/frontend/rust-lib/collab-integrate/src/wasm/plugin_provider.rs @@ -0,0 +1,30 @@ +use crate::collab_builder::{CollabPluginProviderContext, CollabPluginProviderType}; +use collab::preclude::CollabPlugin; +use lib_infra::future::Fut; +use std::rc::Rc; +use std::sync::Arc; + +pub trait CollabCloudPluginProvider: 'static { + fn provider_type(&self) -> CollabPluginProviderType; + + fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut>>; + + fn is_sync_enabled(&self) -> bool; +} + +impl CollabCloudPluginProvider for Rc +where + T: CollabCloudPluginProvider, +{ + fn provider_type(&self) -> CollabPluginProviderType { + (**self).provider_type() + } + + fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut>> { + (**self).get_plugins(context) + } + + fn is_sync_enabled(&self) -> bool { + (**self).is_sync_enabled() + } +} diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index bbd34cdf77..97142f8e00 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -29,13 +29,17 @@ tracing.workspace = true lib-dispatch = { workspace = true } #flowy-core = { workspace = true, features = ["profiling"] } flowy-core = { workspace = true } -flowy-notification = { workspace = true } +flowy-notification = { workspace = true, features = ["dart"] } +flowy-document = { workspace = true, features = ["dart"] } +flowy-config = { workspace = true, features = ["dart"] } +flowy-user = { workspace = true, features = ["dart"] } +flowy-date = { workspace = true, features = ["dart"] } flowy-server = { workspace = true } flowy-server-pub = { workspace = true} collab-integrate = { workspace = true } flowy-derive.workspace = true serde_yaml = "0.9.27" -flowy-error = { workspace = true, features = ["impl_from_sqlite", "impl_from_dispatch_error", "impl_from_appflowy_cloud", "impl_from_reqwest", "impl_from_serde"] } +flowy-error = { workspace = true, features = ["impl_from_sqlite", "impl_from_dispatch_error", "impl_from_appflowy_cloud", "impl_from_reqwest", "impl_from_serde", "dart"] } [features] default = ["dart", "rev-sqlite"] diff --git a/frontend/rust-lib/dart-ffi/build.rs b/frontend/rust-lib/dart-ffi/build.rs index d43384c1ae..d86e7719e5 100644 --- a/frontend/rust-lib/dart-ffi/build.rs +++ b/frontend/rust-lib/dart-ffi/build.rs @@ -1,3 +1,3 @@ fn main() { - flowy_codegen::protobuf_file::gen(env!("CARGO_PKG_NAME")); + flowy_codegen::protobuf_file::dart_gen(env!("CARGO_PKG_NAME")); } diff --git a/frontend/rust-lib/dart-ffi/src/lib.rs b/frontend/rust-lib/dart-ffi/src/lib.rs index 2e0b6b137a..1640d91bb3 100644 --- a/frontend/rust-lib/dart-ffi/src/lib.rs +++ b/frontend/rust-lib/dart-ffi/src/lib.rs @@ -100,7 +100,7 @@ pub extern "C" fn async_event(port: i64, input: *const u8, len: usize) { Some(dispatcher) => dispatcher, }; AFPluginDispatcher::boxed_async_send_with_callback( - dispatcher, + dispatcher.as_ref(), request, move |resp: AFPluginEventResponse| { trace!("[FFI]: Post data to dart through {} port", port); diff --git a/frontend/rust-lib/event-integration/Cargo.toml b/frontend/rust-lib/event-integration/Cargo.toml index 0b35d019d3..d79ea67bc9 100644 --- a/frontend/rust-lib/event-integration/Cargo.toml +++ b/frontend/rust-lib/event-integration/Cargo.toml @@ -56,4 +56,4 @@ zip = "0.6.6" default = ["supabase_cloud_test"] dart = ["flowy-core/dart"] supabase_cloud_test = [] -single_thread = ["flowy-core/single_thread"] \ No newline at end of file +single_thread = ["flowy-core/enable_wasm"] \ No newline at end of file diff --git a/frontend/rust-lib/event-integration/src/event_builder.rs b/frontend/rust-lib/event-integration/src/event_builder.rs index afa4590add..fa20de726f 100644 --- a/frontend/rust-lib/event-integration/src/event_builder.rs +++ b/frontend/rust-lib/event-integration/src/event_builder.rs @@ -50,7 +50,7 @@ impl EventBuilder { pub async fn async_send(mut self) -> Self { let request = self.get_request(); - let resp = AFPluginDispatcher::async_send(self.dispatch(), request).await; + let resp = AFPluginDispatcher::async_send(self.dispatch().as_ref(), request).await; self.context.response = Some(resp); self } diff --git a/frontend/rust-lib/event-integration/src/lib.rs b/frontend/rust-lib/event-integration/src/lib.rs index 4a439c4512..dd1e697bb0 100644 --- a/frontend/rust-lib/event-integration/src/lib.rs +++ b/frontend/rust-lib/event-integration/src/lib.rs @@ -133,7 +133,7 @@ pub fn document_from_document_doc_state(doc_id: &str, doc_state: CollabDocState) Document::from_doc_state(CollabOrigin::Empty, doc_state, doc_id, vec![]).unwrap() } -#[cfg(feature = "single_thread")] +#[cfg(target_arch = "wasm32")] async fn init_core(config: AppFlowyCoreConfig) -> AppFlowyCore { // let runtime = tokio::runtime::Runtime::new().unwrap(); // let local_set = tokio::task::LocalSet::new(); @@ -141,7 +141,7 @@ async fn init_core(config: AppFlowyCoreConfig) -> AppFlowyCore { AppFlowyCore::new(config).await } -#[cfg(not(feature = "single_thread"))] +#[cfg(not(target_arch = "wasm32"))] async fn init_core(config: AppFlowyCoreConfig) -> AppFlowyCore { std::thread::spawn(|| AppFlowyCore::new(config)) .join() diff --git a/frontend/rust-lib/event-integration/src/user_event.rs b/frontend/rust-lib/event-integration/src/user_event.rs index cfc5f1b1bf..9274267f7f 100644 --- a/frontend/rust-lib/event-integration/src/user_event.rs +++ b/frontend/rust-lib/event-integration/src/user_event.rs @@ -12,7 +12,7 @@ use uuid::Uuid; use flowy_notification::entities::SubscribeObject; use flowy_notification::NotificationSender; -use flowy_server::supabase::define::{USER_DEVICE_ID, USER_EMAIL, USER_SIGN_IN_URL, USER_UUID}; +use flowy_server::af_cloud::define::{USER_DEVICE_ID, USER_EMAIL, USER_SIGN_IN_URL, USER_UUID}; use flowy_server_pub::af_cloud_config::AFCloudConfiguration; use flowy_server_pub::AuthenticatorType; use flowy_user::entities::{ @@ -69,7 +69,7 @@ impl EventIntegrationTest { .unwrap(); let request = AFPluginRequest::new(SignUp).payload(payload); - let user_profile = AFPluginDispatcher::async_send(self.appflowy_core.dispatcher(), request) + let user_profile = AFPluginDispatcher::async_send(&self.appflowy_core.dispatcher(), request) .await .parse::() .unwrap() diff --git a/frontend/rust-lib/flowy-config/Cargo.toml b/frontend/rust-lib/flowy-config/Cargo.toml index 957071cc8f..821fcda2fc 100644 --- a/frontend/rust-lib/flowy-config/Cargo.toml +++ b/frontend/rust-lib/flowy-config/Cargo.toml @@ -21,4 +21,4 @@ flowy-codegen.workspace = true [features] dart = ["flowy-codegen/dart"] -ts = ["flowy-codegen/ts"] +tauri_ts = ["flowy-codegen/ts"] diff --git a/frontend/rust-lib/flowy-config/build.rs b/frontend/rust-lib/flowy-config/build.rs index 06388d2a02..f1036a135d 100644 --- a/frontend/rust-lib/flowy-config/build.rs +++ b/frontend/rust-lib/flowy-config/build.rs @@ -1,10 +1,13 @@ fn main() { - let crate_name = env!("CARGO_PKG_NAME"); - flowy_codegen::protobuf_file::gen(crate_name); - #[cfg(feature = "dart")] - flowy_codegen::dart_event::gen(crate_name); + { + flowy_codegen::protobuf_file::dart_gen(env!("CARGO_PKG_NAME")); + flowy_codegen::dart_event::gen(env!("CARGO_PKG_NAME")); + } - #[cfg(feature = "ts")] - flowy_codegen::ts_event::gen(crate_name); + #[cfg(feature = "tauri_ts")] + { + flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + flowy_codegen::protobuf_file::ts_gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + } } diff --git a/frontend/rust-lib/flowy-core/Cargo.toml b/frontend/rust-lib/flowy-core/Cargo.toml index 3c97ee5f7d..02223469a9 100644 --- a/frontend/rust-lib/flowy-core/Cargo.toml +++ b/frontend/rust-lib/flowy-core/Cargo.toml @@ -18,7 +18,7 @@ flowy-sqlite = { workspace = true } flowy-document = { workspace = true } flowy-document-pub = { workspace = true } flowy-error = { workspace = true } -flowy-server = { workspace = true } +flowy-server = { workspace = true, features = ["enable_supabase"] } flowy-server-pub = { workspace = true } flowy-config = { workspace = true } flowy-date = { workspace = true } @@ -55,21 +55,15 @@ http_sync = [] native_sync = [] use_bunyan = ["lib-log/use_bunyan"] dart = [ - "flowy-user/dart", - "flowy-date/dart", "flowy-folder/dart", "flowy-database2/dart", - "flowy-document/dart", - "flowy-config/dart", ] ts = [ - "flowy-user/ts", - "flowy-date/ts", + "flowy-user/tauri_ts", "flowy-folder/ts", "flowy-database2/ts", - "flowy-document/ts", - "flowy-config/ts", + "flowy-config/tauri_ts", ] rev-sqlite = ["flowy-user/rev-sqlite"] openssl_vendored = ["flowy-sqlite/openssl_vendored"] -single_thread = ["collab-integrate/wasm_build"] +enable_wasm = ["collab-integrate/enable_wasm"] diff --git a/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs b/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs index a73cf9edf1..7bdb2220d7 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs @@ -24,7 +24,9 @@ use flowy_folder_pub::cloud::{ use flowy_server_pub::af_cloud_config::AFCloudConfiguration; use flowy_server_pub::supabase_config::SupabaseConfiguration; use flowy_storage::ObjectValue; -use flowy_user_pub::cloud::{UserCloudService, UserCloudServiceProvider}; +use flowy_user_pub::cloud::{ + UserCloudService, UserCloudServiceProvider, UserCloudServiceProviderBase, +}; use flowy_user_pub::entities::{Authenticator, UserTokenState}; use lib_infra::future::{to_fut, Fut, FutureResult}; @@ -63,8 +65,9 @@ impl ObjectStorageService for ServerProvider { }) } } +impl UserCloudServiceProvider for ServerProvider {} -impl UserCloudServiceProvider for ServerProvider { +impl UserCloudServiceProviderBase for ServerProvider { fn set_token(&self, token: &str) -> Result<(), FlowyError> { let server = self.get_server()?; server.set_token(token)?; diff --git a/frontend/rust-lib/flowy-core/src/integrate/user.rs b/frontend/rust-lib/flowy-core/src/integrate/user.rs index af48d79c54..d296964e73 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/user.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/user.rs @@ -10,7 +10,7 @@ use flowy_document::manager::DocumentManager; use flowy_error::FlowyResult; use flowy_folder::manager::{FolderInitDataSource, FolderManager}; use flowy_user::event_map::UserStatusCallback; -use flowy_user_pub::cloud::{UserCloudConfig, UserCloudServiceProvider}; +use flowy_user_pub::cloud::{UserCloudConfig, UserCloudServiceProviderBase}; use flowy_user_pub::entities::{Authenticator, UserProfile, UserWorkspace}; use lib_infra::future::{to_fut, Fut}; diff --git a/frontend/rust-lib/flowy-core/src/lib.rs b/frontend/rust-lib/flowy-core/src/lib.rs index 083fd0318d..8df443e115 100644 --- a/frontend/rust-lib/flowy-core/src/lib.rs +++ b/frontend/rust-lib/flowy-core/src/lib.rs @@ -53,13 +53,13 @@ pub struct AppFlowyCore { } impl AppFlowyCore { - #[cfg(feature = "single_thread")] + #[cfg(target_arch = "wasm32")] pub async fn new(config: AppFlowyCoreConfig) -> Self { let runtime = Arc::new(AFPluginRuntime::new().unwrap()); Self::init(config, runtime).await } - #[cfg(not(feature = "single_thread"))] + #[cfg(not(target_arch = "wasm32"))] pub fn new(config: AppFlowyCoreConfig) -> Self { let runtime = Arc::new(AFPluginRuntime::new().unwrap()); let cloned_runtime = runtime.clone(); diff --git a/frontend/rust-lib/flowy-database2/Cargo.toml b/frontend/rust-lib/flowy-database2/Cargo.toml index 42216e725c..f2af30c3f1 100644 --- a/frontend/rust-lib/flowy-database2/Cargo.toml +++ b/frontend/rust-lib/flowy-database2/Cargo.toml @@ -55,5 +55,5 @@ flowy-codegen.workspace = true [features] dart = ["flowy-codegen/dart", "flowy-notification/dart"] -ts = ["flowy-codegen/ts", "flowy-notification/ts"] -wasm_build = ["collab-plugins/wasm_build"] \ No newline at end of file +ts = ["flowy-codegen/ts", "flowy-notification/tauri_ts"] +enable_wasm = ["collab-plugins/wasm_build"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-database2/build.rs b/frontend/rust-lib/flowy-database2/build.rs index 06388d2a02..4a3b6113ae 100644 --- a/frontend/rust-lib/flowy-database2/build.rs +++ b/frontend/rust-lib/flowy-database2/build.rs @@ -1,10 +1,14 @@ fn main() { let crate_name = env!("CARGO_PKG_NAME"); - flowy_codegen::protobuf_file::gen(crate_name); - #[cfg(feature = "dart")] - flowy_codegen::dart_event::gen(crate_name); + { + flowy_codegen::protobuf_file::dart_gen(crate_name); + flowy_codegen::dart_event::gen(crate_name); + } #[cfg(feature = "ts")] - flowy_codegen::ts_event::gen(crate_name); + { + flowy_codegen::ts_event::gen(crate_name, flowy_codegen::Project::Tauri); + flowy_codegen::protobuf_file::ts_gen(crate_name, flowy_codegen::Project::Tauri); + } } diff --git a/frontend/rust-lib/flowy-date/Cargo.toml b/frontend/rust-lib/flowy-date/Cargo.toml index 526678099c..936199b6c2 100644 --- a/frontend/rust-lib/flowy-date/Cargo.toml +++ b/frontend/rust-lib/flowy-date/Cargo.toml @@ -21,8 +21,7 @@ fancy-regex = { version = "0.11.0" } [features] dart = ["flowy-codegen/dart"] -ts = ["flowy-codegen/ts"] -wasm_build = ["lib-dispatch/single_thread", "flowy-codegen/ts"] +tauri_ts = ["flowy-codegen/ts"] [build-dependencies] flowy-codegen.workspace = true diff --git a/frontend/rust-lib/flowy-date/build.rs b/frontend/rust-lib/flowy-date/build.rs index 06388d2a02..f1036a135d 100644 --- a/frontend/rust-lib/flowy-date/build.rs +++ b/frontend/rust-lib/flowy-date/build.rs @@ -1,10 +1,13 @@ fn main() { - let crate_name = env!("CARGO_PKG_NAME"); - flowy_codegen::protobuf_file::gen(crate_name); - #[cfg(feature = "dart")] - flowy_codegen::dart_event::gen(crate_name); + { + flowy_codegen::protobuf_file::dart_gen(env!("CARGO_PKG_NAME")); + flowy_codegen::dart_event::gen(env!("CARGO_PKG_NAME")); + } - #[cfg(feature = "ts")] - flowy_codegen::ts_event::gen(crate_name); + #[cfg(feature = "tauri_ts")] + { + flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + flowy_codegen::protobuf_file::ts_gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + } } diff --git a/frontend/rust-lib/flowy-document/Cargo.toml b/frontend/rust-lib/flowy-document/Cargo.toml index 09bb0dcb2e..efc07b5260 100644 --- a/frontend/rust-lib/flowy-document/Cargo.toml +++ b/frontend/rust-lib/flowy-document/Cargo.toml @@ -17,7 +17,7 @@ flowy-document-pub = { workspace = true } flowy-storage = { workspace = true } flowy-derive.workspace = true flowy-notification = { workspace = true } -flowy-error = { path = "../flowy-error", features = ["impl_from_serde", "impl_from_dispatch_error", "impl_from_collab_document"] } +flowy-error = { path = "../flowy-error", features = ["impl_from_serde", "impl_from_dispatch_error", "impl_from_collab_document", "impl_from_collab_persistence"] } lib-dispatch = { workspace = true } lib-infra = { workspace = true } validator = { version = "0.16.0", features = ["derive"] } @@ -50,16 +50,12 @@ collab-integrate = { workspace = true } flowy-codegen.workspace = true [features] -dart = ["flowy-codegen/dart", "flowy-notification/dart"] -ts = ["flowy-codegen/ts", "flowy-notification/ts"] -wasm_build = [ +dart = ["flowy-codegen/dart"] +tauri_ts = ["flowy-codegen/ts"] +web_ts = [ "flowy-codegen/ts", - "flowy-notification/ts", "collab-plugins/wasm_build", "collab/wasm_build", - "lib-dispatch/wasm_build", "collab-document/wasm_build", - "flowy-error/wasm_build", - "flowy-notification/wasm_build" ] diff --git a/frontend/rust-lib/flowy-document/build.rs b/frontend/rust-lib/flowy-document/build.rs index 06388d2a02..4585268158 100644 --- a/frontend/rust-lib/flowy-document/build.rs +++ b/frontend/rust-lib/flowy-document/build.rs @@ -1,10 +1,29 @@ fn main() { - let crate_name = env!("CARGO_PKG_NAME"); - flowy_codegen::protobuf_file::gen(crate_name); - #[cfg(feature = "dart")] - flowy_codegen::dart_event::gen(crate_name); + { + flowy_codegen::protobuf_file::dart_gen(env!("CARGO_PKG_NAME")); + flowy_codegen::dart_event::gen(env!("CARGO_PKG_NAME")); + } - #[cfg(feature = "ts")] - flowy_codegen::ts_event::gen(crate_name); + #[cfg(feature = "tauri_ts")] + { + flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + flowy_codegen::protobuf_file::ts_gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + } + + #[cfg(feature = "web_ts")] + { + flowy_codegen::ts_event::gen( + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::Web { + relative_path: "../../".to_string(), + }, + ); + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::Web { + relative_path: "../../".to_string(), + }, + ); + } } diff --git a/frontend/rust-lib/flowy-document/src/manager.rs b/frontend/rust-lib/flowy-document/src/manager.rs index e22debded2..04963efe37 100644 --- a/frontend/rust-lib/flowy-document/src/manager.rs +++ b/frontend/rust-lib/flowy-document/src/manager.rs @@ -25,6 +25,7 @@ use collab_integrate::CollabPersistenceConfig; use flowy_document_pub::cloud::DocumentCloudService; use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult}; use flowy_storage::ObjectStorageService; +use lib_dispatch::prelude::af_spawn; use crate::document::MutexDocument; use crate::entities::{ @@ -260,7 +261,7 @@ impl DocumentManager { // let the upload happen in the background let clone_url = url.clone(); - tokio::spawn(async move { + af_spawn(async move { if let Err(e) = storage_service.put_object(clone_url, object_value).await { error!("upload file failed: {}", e); } @@ -300,7 +301,7 @@ impl DocumentManager { // delete from cloud let storage_service = self.storage_service_upgrade()?; - tokio::spawn(async move { + af_spawn(async move { if let Err(e) = storage_service.delete_object(url).await { // TODO: add WAL to log the delete operation. // keep a list of files to be deleted, and retry later diff --git a/frontend/rust-lib/flowy-encrypt/Cargo.toml b/frontend/rust-lib/flowy-encrypt/Cargo.toml index b5cfd63eb6..2046bffc72 100644 --- a/frontend/rust-lib/flowy-encrypt/Cargo.toml +++ b/frontend/rust-lib/flowy-encrypt/Cargo.toml @@ -20,4 +20,4 @@ base64 = "0.21.2" getrandom = { version = "0.2", features = ["js"]} [features] -wasm_build = [] +enable_wasm = [] diff --git a/frontend/rust-lib/flowy-error/Cargo.toml b/frontend/rust-lib/flowy-error/Cargo.toml index 24aa8bc8c9..659e354427 100644 --- a/frontend/rust-lib/flowy-error/Cargo.toml +++ b/frontend/rust-lib/flowy-error/Cargo.toml @@ -36,15 +36,16 @@ client-api = { version = "0.1.0", optional = true } impl_from_dispatch_error = ["lib-dispatch"] impl_from_serde = [] impl_from_reqwest = ["reqwest"] +impl_from_collab_persistence = ["collab-plugins"] impl_from_collab_document = ["collab-document", "impl_from_reqwest", "collab-plugins"] impl_from_collab_database= ["collab-database"] impl_from_url = ["url"] -wasm_build = ["lib-dispatch/wasm_build"] impl_from_sqlite = ["flowy-sqlite", "r2d2"] impl_from_appflowy_cloud = ["client-api"] dart = ["flowy-codegen/dart"] -ts = ["flowy-codegen/ts"] +tauri_ts = ["flowy-codegen/ts"] +web_ts = ["flowy-codegen/ts"] [build-dependencies] flowy-codegen = { workspace = true, features = [ diff --git a/frontend/rust-lib/flowy-error/build.rs b/frontend/rust-lib/flowy-error/build.rs index 55820d5cbd..9e893a2f93 100644 --- a/frontend/rust-lib/flowy-error/build.rs +++ b/frontend/rust-lib/flowy-error/build.rs @@ -1,3 +1,15 @@ fn main() { - flowy_codegen::protobuf_file::gen("flowy-error"); + #[cfg(feature = "dart")] + flowy_codegen::protobuf_file::dart_gen(env!("CARGO_PKG_NAME")); + + #[cfg(feature = "tauri_ts")] + flowy_codegen::protobuf_file::ts_gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + + #[cfg(feature = "web_ts")] + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::Web { + relative_path: "../../".to_string(), + }, + ); } diff --git a/frontend/rust-lib/flowy-error/src/impl_from/collab.rs b/frontend/rust-lib/flowy-error/src/impl_from/collab.rs index a29559429d..3af53b1ffe 100644 --- a/frontend/rust-lib/flowy-error/src/impl_from/collab.rs +++ b/frontend/rust-lib/flowy-error/src/impl_from/collab.rs @@ -1,28 +1,10 @@ +use crate::FlowyError; #[cfg(feature = "impl_from_collab_database")] use collab_database::error::DatabaseError; #[cfg(feature = "impl_from_collab_document")] use collab_document::error::DocumentError; -#[cfg(feature = "impl_from_collab_document")] -use collab_plugins::local_storage::kv::PersistenceError; - -use crate::{ErrorCode, FlowyError}; - -#[cfg(feature = "impl_from_collab_document")] -impl From for FlowyError { - fn from(err: PersistenceError) -> Self { - match err { - PersistenceError::UnexpectedEmptyUpdates => FlowyError::new(ErrorCode::RecordNotFound, err), - #[cfg(not(target_arch = "wasm32"))] - PersistenceError::RocksdbCorruption(_) => FlowyError::new(ErrorCode::RocksdbCorruption, err), - #[cfg(not(target_arch = "wasm32"))] - PersistenceError::RocksdbIOError(_) => FlowyError::new(ErrorCode::RocksdbIOError, err), - _ => FlowyError::new(ErrorCode::RocksdbInternal, err), - } - } -} - #[cfg(feature = "impl_from_collab_database")] impl From for FlowyError { fn from(error: DatabaseError) -> Self { diff --git a/frontend/rust-lib/flowy-error/src/impl_from/collab_persistence.rs b/frontend/rust-lib/flowy-error/src/impl_from/collab_persistence.rs new file mode 100644 index 0000000000..19f49c318e --- /dev/null +++ b/frontend/rust-lib/flowy-error/src/impl_from/collab_persistence.rs @@ -0,0 +1,17 @@ +use crate::{ErrorCode, FlowyError}; +#[cfg(feature = "impl_from_collab_persistence")] +use collab_plugins::local_storage::kv::PersistenceError; + +#[cfg(feature = "impl_from_collab_persistence")] +impl From for FlowyError { + fn from(err: PersistenceError) -> Self { + match err { + PersistenceError::UnexpectedEmptyUpdates => FlowyError::new(ErrorCode::RecordNotFound, err), + #[cfg(not(target_arch = "wasm32"))] + PersistenceError::RocksdbCorruption(_) => FlowyError::new(ErrorCode::RocksdbCorruption, err), + #[cfg(not(target_arch = "wasm32"))] + PersistenceError::RocksdbIOError(_) => FlowyError::new(ErrorCode::RocksdbIOError, err), + _ => FlowyError::new(ErrorCode::RocksdbInternal, err), + } + } +} diff --git a/frontend/rust-lib/flowy-error/src/impl_from/mod.rs b/frontend/rust-lib/flowy-error/src/impl_from/mod.rs index 6fdccdb937..c52e6f7750 100644 --- a/frontend/rust-lib/flowy-error/src/impl_from/mod.rs +++ b/frontend/rust-lib/flowy-error/src/impl_from/mod.rs @@ -16,7 +16,11 @@ pub mod database; #[cfg(feature = "impl_from_collab_document")] pub mod collab; +#[cfg(feature = "impl_from_collab_persistence")] +mod collab_persistence; + #[cfg(feature = "impl_from_appflowy_cloud")] mod cloud; + #[cfg(feature = "impl_from_url")] mod url; diff --git a/frontend/rust-lib/flowy-folder/Cargo.toml b/frontend/rust-lib/flowy-folder/Cargo.toml index 93df78002c..6a5cf7c999 100644 --- a/frontend/rust-lib/flowy-folder/Cargo.toml +++ b/frontend/rust-lib/flowy-folder/Cargo.toml @@ -38,6 +38,6 @@ flowy-codegen.workspace = true [features] dart = ["flowy-codegen/dart", "flowy-notification/dart"] -ts = ["flowy-codegen/ts", "flowy-notification/ts"] +ts = ["flowy-codegen/ts", "flowy-notification/tauri_ts"] test_helper = [] -wasm_build = ["collab-plugins/wasm_build"] +enable_wasm = ["collab-plugins/wasm_build"] diff --git a/frontend/rust-lib/flowy-folder/build.rs b/frontend/rust-lib/flowy-folder/build.rs index 06388d2a02..343a1a21e3 100644 --- a/frontend/rust-lib/flowy-folder/build.rs +++ b/frontend/rust-lib/flowy-folder/build.rs @@ -1,10 +1,13 @@ fn main() { - let crate_name = env!("CARGO_PKG_NAME"); - flowy_codegen::protobuf_file::gen(crate_name); - #[cfg(feature = "dart")] - flowy_codegen::dart_event::gen(crate_name); + { + flowy_codegen::protobuf_file::dart_gen(env!("CARGO_PKG_NAME")); + flowy_codegen::dart_event::gen(env!("CARGO_PKG_NAME")); + } #[cfg(feature = "ts")] - flowy_codegen::ts_event::gen(crate_name); + { + flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + flowy_codegen::protobuf_file::ts_gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + } } diff --git a/frontend/rust-lib/flowy-notification/Cargo.toml b/frontend/rust-lib/flowy-notification/Cargo.toml index 5a721eb5ba..3853914866 100644 --- a/frontend/rust-lib/flowy-notification/Cargo.toml +++ b/frontend/rust-lib/flowy-notification/Cargo.toml @@ -22,5 +22,5 @@ flowy-codegen.workspace = true [features] dart = ["flowy-codegen/dart"] -ts = ["flowy-codegen/ts"] -wasm_build = ["lib-dispatch/wasm_build", "flowy-codegen/ts"] \ No newline at end of file +tauri_ts = ["flowy-codegen/ts"] +web_ts = ["flowy-codegen/ts"] diff --git a/frontend/rust-lib/flowy-notification/build.rs b/frontend/rust-lib/flowy-notification/build.rs index d43384c1ae..9e893a2f93 100644 --- a/frontend/rust-lib/flowy-notification/build.rs +++ b/frontend/rust-lib/flowy-notification/build.rs @@ -1,3 +1,15 @@ fn main() { - flowy_codegen::protobuf_file::gen(env!("CARGO_PKG_NAME")); + #[cfg(feature = "dart")] + flowy_codegen::protobuf_file::dart_gen(env!("CARGO_PKG_NAME")); + + #[cfg(feature = "tauri_ts")] + flowy_codegen::protobuf_file::ts_gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + + #[cfg(feature = "web_ts")] + flowy_codegen::protobuf_file::ts_gen( + env!("CARGO_PKG_NAME"), + flowy_codegen::Project::Web { + relative_path: "../../".to_string(), + }, + ); } diff --git a/frontend/rust-lib/flowy-server-pub/Cargo.toml b/frontend/rust-lib/flowy-server-pub/Cargo.toml index 5a59b5ccae..ccd601a5e9 100644 --- a/frontend/rust-lib/flowy-server-pub/Cargo.toml +++ b/frontend/rust-lib/flowy-server-pub/Cargo.toml @@ -9,3 +9,4 @@ edition = "2021" flowy-error = { workspace = true } serde.workspace = true serde_repr.workspace = true + diff --git a/frontend/rust-lib/flowy-server-pub/src/lib.rs b/frontend/rust-lib/flowy-server-pub/src/lib.rs index 20cb8a126f..4736587f4e 100644 --- a/frontend/rust-lib/flowy-server-pub/src/lib.rs +++ b/frontend/rust-lib/flowy-server-pub/src/lib.rs @@ -1,6 +1,33 @@ use serde_repr::Deserialize_repr; -pub mod af_cloud_config; +macro_rules! if_native { + ($($item:item)*) => {$( + #[cfg(not(target_arch = "wasm32"))] + $item + )*} +} + +macro_rules! if_wasm { + ($($item:item)*) => {$( + #[cfg(target_arch = "wasm32")] + $item + )*} +} + +if_native! { + mod native; + pub mod af_cloud_config { + pub use crate::native::af_cloud_config::*; + } +} + +if_wasm! { + mod wasm; + pub mod af_cloud_config { + pub use crate::wasm::af_cloud_config::*; + } +} + pub mod supabase_config; pub const CLOUT_TYPE_STR: &str = "APPFLOWY_CLOUD_ENV_CLOUD_TYPE"; diff --git a/frontend/rust-lib/flowy-server-pub/src/native/af_cloud_config.rs b/frontend/rust-lib/flowy-server-pub/src/native/af_cloud_config.rs new file mode 100644 index 0000000000..d75c30a673 --- /dev/null +++ b/frontend/rust-lib/flowy-server-pub/src/native/af_cloud_config.rs @@ -0,0 +1,69 @@ +use std::fmt::Display; + +use serde::{Deserialize, Serialize}; + +use flowy_error::{ErrorCode, FlowyError}; + +pub const APPFLOWY_CLOUD_BASE_URL: &str = "APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_BASE_URL"; +pub const APPFLOWY_CLOUD_WS_BASE_URL: &str = "APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_WS_BASE_URL"; +pub const APPFLOWY_CLOUD_GOTRUE_URL: &str = "APPFLOWY_CLOUD_ENV_APPFLOWY_CLOUD_GOTRUE_URL"; + +#[derive(Debug, Serialize, Deserialize, Clone, Default)] +pub struct AFCloudConfiguration { + pub base_url: String, + pub ws_base_url: String, + pub gotrue_url: String, +} + +impl Display for AFCloudConfiguration { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!( + "base_url: {}, ws_base_url: {}, gotrue_url: {}", + self.base_url, self.ws_base_url, self.gotrue_url, + )) + } +} + +impl AFCloudConfiguration { + pub fn from_env() -> Result { + let base_url = std::env::var(APPFLOWY_CLOUD_BASE_URL).map_err(|_| { + FlowyError::new( + ErrorCode::InvalidAuthConfig, + "Missing APPFLOWY_CLOUD_BASE_URL", + ) + })?; + + let ws_base_url = std::env::var(APPFLOWY_CLOUD_WS_BASE_URL).map_err(|_| { + FlowyError::new( + ErrorCode::InvalidAuthConfig, + "Missing APPFLOWY_CLOUD_WS_BASE_URL", + ) + })?; + + let gotrue_url = std::env::var(APPFLOWY_CLOUD_GOTRUE_URL) + .map_err(|_| FlowyError::new(ErrorCode::InvalidAuthConfig, "Missing AF_CLOUD_GOTRUE_URL"))?; + + if base_url.is_empty() || ws_base_url.is_empty() || gotrue_url.is_empty() { + return Err(FlowyError::new( + ErrorCode::InvalidAuthConfig, + format!( + "Invalid APPFLOWY_CLOUD_BASE_URL: {}, APPFLOWY_CLOUD_WS_BASE_URL: {}, APPFLOWY_CLOUD_GOTRUE_URL: {}", + base_url, ws_base_url, gotrue_url, + )), + ); + } + + Ok(Self { + base_url, + ws_base_url, + gotrue_url, + }) + } + + /// Write the configuration to the environment variables. + pub fn write_env(&self) { + std::env::set_var(APPFLOWY_CLOUD_BASE_URL, &self.base_url); + std::env::set_var(APPFLOWY_CLOUD_WS_BASE_URL, &self.ws_base_url); + std::env::set_var(APPFLOWY_CLOUD_GOTRUE_URL, &self.gotrue_url); + } +} diff --git a/frontend/rust-lib/flowy-server-pub/src/native/mod.rs b/frontend/rust-lib/flowy-server-pub/src/native/mod.rs new file mode 100644 index 0000000000..8103d04851 --- /dev/null +++ b/frontend/rust-lib/flowy-server-pub/src/native/mod.rs @@ -0,0 +1 @@ +pub mod af_cloud_config; diff --git a/frontend/rust-lib/flowy-server-pub/src/wasm/af_cloud_config.rs b/frontend/rust-lib/flowy-server-pub/src/wasm/af_cloud_config.rs new file mode 100644 index 0000000000..2db924b3d7 --- /dev/null +++ b/frontend/rust-lib/flowy-server-pub/src/wasm/af_cloud_config.rs @@ -0,0 +1,18 @@ +use serde::{Deserialize, Serialize}; +use std::fmt::Display; + +#[derive(Debug, Serialize, Deserialize, Clone, Default)] +pub struct AFCloudConfiguration { + pub base_url: String, + pub ws_base_url: String, + pub gotrue_url: String, +} + +impl Display for AFCloudConfiguration { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!( + "base_url: {}, ws_base_url: {}, gotrue_url: {}", + self.base_url, self.ws_base_url, self.gotrue_url, + )) + } +} diff --git a/frontend/rust-lib/flowy-server-pub/src/wasm/mod.rs b/frontend/rust-lib/flowy-server-pub/src/wasm/mod.rs new file mode 100644 index 0000000000..8103d04851 --- /dev/null +++ b/frontend/rust-lib/flowy-server-pub/src/wasm/mod.rs @@ -0,0 +1 @@ +pub mod af_cloud_config; diff --git a/frontend/rust-lib/flowy-server/Cargo.toml b/frontend/rust-lib/flowy-server/Cargo.toml index bb887080c6..3149b96b85 100644 --- a/frontend/rust-lib/flowy-server/Cargo.toml +++ b/frontend/rust-lib/flowy-server/Cargo.toml @@ -4,6 +4,9 @@ version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["cdylib", "rlib"] + [dependencies] tracing.workspace = true @@ -23,7 +26,7 @@ anyhow.workspace = true uuid.workspace = true chrono = { workspace = true, default-features = false, features = ["clock", "serde"] } collab = { version = "0.1.0" } -collab-plugins = { version = "0.1.0", features = ["postgres_plugin"] } +collab-plugins = { version = "0.1.0"} collab-document = { version = "0.1.0" } collab-entity = { version = "0.1.0" } hex = "0.4.3" @@ -53,3 +56,7 @@ yrs = "0.17.1" assert-json-diff = "2.0.2" serde_json.workspace = true client-api = { version = "0.1.0" } + +[features] +enable_wasm = ["collab/async-plugin"] +enable_supabase = ["collab-plugins/postgres_plugin"] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/define.rs b/frontend/rust-lib/flowy-server/src/af_cloud/define.rs new file mode 100644 index 0000000000..cf3529ae2f --- /dev/null +++ b/frontend/rust-lib/flowy-server/src/af_cloud/define.rs @@ -0,0 +1,4 @@ +pub const USER_SIGN_IN_URL: &str = "sign_in_url"; +pub const USER_UUID: &str = "uuid"; +pub const USER_EMAIL: &str = "email"; +pub const USER_DEVICE_ID: &str = "device_id"; diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs index 5f4ab31b8e..cf934bed61 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/impls/user/cloud_service_impl.rs @@ -4,23 +4,23 @@ use std::sync::Arc; use anyhow::{anyhow, Error}; use client_api::entity::workspace_dto::{CreateWorkspaceMember, WorkspaceMemberChangeset}; use client_api::entity::{AFRole, AFWorkspace, AuthProvider, CollabParams, CreateCollabParams}; -use client_api::ClientConfiguration; +use client_api::{Client, ClientConfiguration}; use collab::core::collab::CollabDocState; use collab_entity::CollabObject; use parking_lot::RwLock; -use flowy_error::{ErrorCode, FlowyError}; +use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_user_pub::cloud::{UserCloudService, UserCollabParams, UserUpdate, UserUpdateReceiver}; use flowy_user_pub::entities::*; use lib_infra::box_any::BoxAny; use lib_infra::future::FutureResult; +use crate::af_cloud::define::USER_SIGN_IN_URL; use crate::af_cloud::impls::user::dto::{ af_update_from_update_params, from_af_workspace_member, to_af_role, user_profile_from_af_profile, }; use crate::af_cloud::impls::user::util::encryption_type_from_profile; use crate::af_cloud::{AFCloudClient, AFServer}; -use crate::supabase::define::USER_SIGN_IN_URL; pub(crate) struct AFCloudUserAuthServiceImpl { server: T, @@ -71,32 +71,46 @@ where let try_get_client = self.server.try_get_client(); FutureResult::new(async move { let client = try_get_client?; - let admin_email = std::env::var("GOTRUE_ADMIN_EMAIL").map_err(|_| { - anyhow!( - "GOTRUE_ADMIN_EMAIL is not set. Please set it to the admin email for the test server" - ) - })?; - let admin_password = std::env::var("GOTRUE_ADMIN_PASSWORD").map_err(|_| { - anyhow!( - "GOTRUE_ADMIN_PASSWORD is not set. Please set it to the admin password for the test server" - ) - })?; - let admin_client = client_api::Client::new( - client.base_url(), - client.ws_addr(), - client.gotrue_url(), - ClientConfiguration::default(), - ); - admin_client - .sign_in_password(&admin_email, &admin_password) - .await?; - + let admin_client = get_admin_client(&client).await?; let action_link = admin_client.generate_sign_in_action_link(&email).await?; let sign_in_url = client.extract_sign_in_url(&action_link).await?; Ok(sign_in_url) }) } + fn create_user(&self, email: &str, password: &str) -> FutureResult<(), FlowyError> { + let password = password.to_string(); + let email = email.to_string(); + let try_get_client = self.server.try_get_client(); + FutureResult::new(async move { + let client = try_get_client?; + let admin_client = get_admin_client(&client).await?; + admin_client + .create_email_verified_user(&email, &password) + .await?; + + Ok(()) + }) + } + + fn sign_in_with_password( + &self, + email: &str, + password: &str, + ) -> FutureResult { + let password = password.to_string(); + let email = email.to_string(); + let try_get_client = self.server.try_get_client(); + FutureResult::new(async move { + let client = try_get_client?; + client.sign_in_password(&email, &password).await?; + let profile = client.get_profile().await?; + let token = client.get_token()?; + let profile = user_profile_from_af_profile(token, profile)?; + Ok(profile) + }) + } + fn generate_oauth_url_with_provider(&self, provider: &str) -> FutureResult { let provider = AuthProvider::from(provider); let try_get_client = self.server.try_get_client(); @@ -282,6 +296,23 @@ where } } +async fn get_admin_client(client: &Arc) -> FlowyResult { + let admin_email = + std::env::var("GOTRUE_ADMIN_EMAIL").unwrap_or_else(|_| "admin@example.com".to_string()); + let admin_password = + std::env::var("GOTRUE_ADMIN_PASSWORD").unwrap_or_else(|_| "password".to_string()); + let admin_client = client_api::Client::new( + client.base_url(), + client.ws_addr(), + client.gotrue_url(), + ClientConfiguration::default(), + ); + admin_client + .sign_in_password(&admin_email, &admin_password) + .await?; + Ok(admin_client) +} + pub async fn user_sign_up_request( client: Arc, params: AFCloudOAuthParams, diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/mod.rs b/frontend/rust-lib/flowy-server/src/af_cloud/mod.rs index 554e1a18d7..cbd12bf151 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/mod.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/mod.rs @@ -1,4 +1,5 @@ pub use server::*; +pub mod define; pub mod impls; mod server; diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/server.rs b/frontend/rust-lib/flowy-server/src/af_cloud/server.rs index 13a4856623..9a9a8cd57b 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/server.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/server.rs @@ -5,10 +5,10 @@ use anyhow::Error; use client_api::collab_sync::collab_msg::CollabMessage; use client_api::entity::UserMessage; use client_api::notify::{TokenState, TokenStateReceiver}; -use client_api::{Client, ClientConfiguration}; -use client_api::{ +use client_api::ws::{ ConnectState, WSClient, WSClientConfig, WSConnectStateReceiver, WebSocketChannel, }; +use client_api::{Client, ClientConfiguration}; use flowy_storage::ObjectStorageService; use tokio::sync::watch; use tokio_stream::wrappers::WatchStream; @@ -137,7 +137,7 @@ impl AppFlowyServer for AppFlowyCloudServer { }; let mut user_change = self.ws_client.subscribe_user_changed(); let (tx, rx) = tokio::sync::mpsc::channel(1); - tokio::spawn(async move { + af_spawn(async move { while let Ok(user_message) = user_change.recv().await { if let UserMessage::ProfileChange(change) = user_message { let user_update = UserUpdate { diff --git a/frontend/rust-lib/flowy-server/src/lib.rs b/frontend/rust-lib/flowy-server/src/lib.rs index 66086909a8..c06a43d334 100644 --- a/frontend/rust-lib/flowy-server/src/lib.rs +++ b/frontend/rust-lib/flowy-server/src/lib.rs @@ -5,5 +5,8 @@ pub mod local_server; // mod request; mod response; mod server; + +#[cfg(feature = "enable_supabase")] pub mod supabase; + pub mod util; diff --git a/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs b/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs index 7153af7e48..8f97d9be68 100644 --- a/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs +++ b/frontend/rust-lib/flowy-server/src/local_server/impls/user.rs @@ -87,11 +87,28 @@ impl UserCloudService for LocalServerUserAuthServiceImpl { fn generate_sign_in_url_with_email(&self, _email: &str) -> FutureResult { FutureResult::new(async { Err( - FlowyError::internal().with_context("Can't generate callback url when using offline mode"), + FlowyError::local_version_not_support() + .with_context("Not support generate sign in url with email"), ) }) } + fn create_user(&self, _email: &str, _password: &str) -> FutureResult<(), FlowyError> { + FutureResult::new(async { + Err(FlowyError::local_version_not_support().with_context("Not support create user")) + }) + } + + fn sign_in_with_password( + &self, + _email: &str, + _password: &str, + ) -> FutureResult { + FutureResult::new(async { + Err(FlowyError::local_version_not_support().with_context("Not support")) + }) + } + fn generate_oauth_url_with_provider(&self, _provider: &str) -> FutureResult { FutureResult::new(async { Err(FlowyError::internal().with_context("Can't oauth url when using offline mode")) diff --git a/frontend/rust-lib/flowy-server/src/server.rs b/frontend/rust-lib/flowy-server/src/server.rs index 245006c718..be5b39d86a 100644 --- a/frontend/rust-lib/flowy-server/src/server.rs +++ b/frontend/rust-lib/flowy-server/src/server.rs @@ -3,11 +3,11 @@ use std::sync::Arc; use anyhow::Error; use client_api::collab_sync::collab_msg::CollabMessage; -use client_api::{ConnectState, WSConnectStateReceiver, WebSocketChannel}; -use collab_entity::CollabObject; -use collab_plugins::cloud_storage::RemoteCollabStorage; +use client_api::ws::{ConnectState, WSConnectStateReceiver, WebSocketChannel}; use parking_lot::RwLock; use tokio_stream::wrappers::WatchStream; +#[cfg(feature = "enable_supabase")] +use {collab_entity::CollabObject, collab_plugins::cloud_storage::RemoteCollabStorage}; use flowy_database_pub::cloud::DatabaseCloudService; use flowy_document_pub::cloud::DocumentCloudService; @@ -104,6 +104,7 @@ pub trait AppFlowyServer: Send + Sync + 'static { /// # Returns /// /// An `Option` that might contain an `Arc` wrapping the `RemoteCollabStorage` interface. + #[cfg(feature = "enable_supabase")] fn collab_storage(&self, _collab_object: &CollabObject) -> Option> { None } diff --git a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs index 7ef9c55b49..73b15d664a 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/api/user.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/api/user.rs @@ -171,6 +171,22 @@ where }) } + fn create_user(&self, _email: &str, _password: &str) -> FutureResult<(), FlowyError> { + FutureResult::new(async { + Err(FlowyError::not_support().with_context("Can't create user when using supabase")) + }) + } + + fn sign_in_with_password( + &self, + _email: &str, + _password: &str, + ) -> FutureResult { + FutureResult::new(async { + Err(FlowyError::not_support().with_context("Can't sign in with password when using supabase")) + }) + } + fn generate_oauth_url_with_provider(&self, _provider: &str) -> FutureResult { FutureResult::new(async { Err(FlowyError::internal().with_context("Can't generate oauth url when using supabase")) diff --git a/frontend/rust-lib/flowy-server/src/supabase/define.rs b/frontend/rust-lib/flowy-server/src/supabase/define.rs index 222069652a..bac37a3046 100644 --- a/frontend/rust-lib/flowy-server/src/supabase/define.rs +++ b/frontend/rust-lib/flowy-server/src/supabase/define.rs @@ -12,13 +12,14 @@ pub const AF_COLLAB_SNAPSHOT_TABLE: &str = "af_collab_snapshot"; pub const USER_UUID: &str = "uuid"; pub const USER_SIGN_IN_URL: &str = "sign_in_url"; +pub const USER_EMAIL: &str = "email"; +pub const USER_DEVICE_ID: &str = "device_id"; + +pub const USER_TABLE: &str = "af_user"; pub const USER_UID: &str = "uid"; pub const OWNER_USER_UID: &str = "owner_uid"; -pub const USER_EMAIL: &str = "email"; -pub const USER_TABLE: &str = "af_user"; pub const WORKSPACE_TABLE: &str = "af_workspace"; pub const USER_PROFILE_VIEW: &str = "af_user_profile_view"; -pub const USER_DEVICE_ID: &str = "device_id"; pub(crate) const WORKSPACE_ID: &str = "workspace_id"; pub(crate) const WORKSPACE_NAME: &str = "workspace_name"; diff --git a/frontend/rust-lib/flowy-server/src/util.rs b/frontend/rust-lib/flowy-server/src/util.rs index fd9e2a999c..936c6e8334 100644 --- a/frontend/rust-lib/flowy-server/src/util.rs +++ b/frontend/rust-lib/flowy-server/src/util.rs @@ -2,6 +2,7 @@ use serde::{Deserialize, Deserializer}; /// Handles the case where the value is null. If the value is null, return the default value of the /// type. Otherwise, deserialize the value. +#[allow(dead_code)] pub(crate) fn deserialize_null_or_default<'de, D, T>(deserializer: D) -> Result where T: Default + Deserialize<'de>, diff --git a/frontend/rust-lib/flowy-storage/Cargo.toml b/frontend/rust-lib/flowy-storage/Cargo.toml index 552340cf78..4b1173eb95 100644 --- a/frontend/rust-lib/flowy-storage/Cargo.toml +++ b/frontend/rust-lib/flowy-storage/Cargo.toml @@ -24,4 +24,4 @@ fxhash = "0.2.1" [features] -wasm_build = ["lib-infra/wasm_build", "flowy-error/wasm_build"] \ No newline at end of file +enable_wasm = [] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-storage/src/lib.rs b/frontend/rust-lib/flowy-storage/src/lib.rs index 018b9c1d54..8f0d02dfad 100644 --- a/frontend/rust-lib/flowy-storage/src/lib.rs +++ b/frontend/rust-lib/flowy-storage/src/lib.rs @@ -1,12 +1,19 @@ -use std::path::Path; +if_native! { + mod native; + pub use native::*; +} + +if_wasm! { + mod wasm; + pub use wasm::*; +} use bytes::Bytes; use flowy_error::FlowyError; use lib_infra::future::FutureResult; +use lib_infra::{if_native, if_wasm}; use mime::Mime; -use tokio::io::AsyncReadExt; -use tracing::info; pub struct ObjectIdentity { pub workspace_id: String, @@ -20,44 +27,6 @@ pub struct ObjectValue { pub mime: Mime, } -#[cfg(target_arch = "wasm32")] -pub async fn object_from_disk( - workspace_id: &str, - local_file_path: &str, -) -> Result<(ObjectIdentity, ObjectValue), FlowyError> { - todo!("object_from_disk is not implemented for wasm32") -} - -#[cfg(not(target_arch = "wasm32"))] -pub async fn object_from_disk( - workspace_id: &str, - local_file_path: &str, -) -> Result<(ObjectIdentity, ObjectValue), FlowyError> { - let ext = Path::new(local_file_path) - .extension() - .and_then(std::ffi::OsStr::to_str) - .unwrap_or("") - .to_owned(); - let mut file = tokio::fs::File::open(local_file_path).await?; - let mut content = Vec::new(); - let n = file.read_to_end(&mut content).await?; - info!("read {} bytes from file: {}", n, local_file_path); - let mime = mime_guess::from_path(local_file_path).first_or_octet_stream(); - let hash = fxhash::hash(&content); - - Ok(( - ObjectIdentity { - workspace_id: workspace_id.to_owned(), - file_id: hash.to_string(), - ext, - }, - ObjectValue { - raw: content.into(), - mime, - }, - )) -} - /// Provides a service for object storage. /// /// The trait includes methods for CRUD operations on storage objects. diff --git a/frontend/rust-lib/flowy-storage/src/native/mod.rs b/frontend/rust-lib/flowy-storage/src/native/mod.rs new file mode 100644 index 0000000000..777a8b08dc --- /dev/null +++ b/frontend/rust-lib/flowy-storage/src/native/mod.rs @@ -0,0 +1,34 @@ +use crate::{ObjectIdentity, ObjectValue}; +use flowy_error::FlowyError; +use std::path::Path; +use tokio::io::AsyncReadExt; +use tracing::info; + +pub async fn object_from_disk( + workspace_id: &str, + local_file_path: &str, +) -> Result<(ObjectIdentity, ObjectValue), FlowyError> { + let ext = Path::new(local_file_path) + .extension() + .and_then(std::ffi::OsStr::to_str) + .unwrap_or("") + .to_owned(); + let mut file = tokio::fs::File::open(local_file_path).await?; + let mut content = Vec::new(); + let n = file.read_to_end(&mut content).await?; + info!("read {} bytes from file: {}", n, local_file_path); + let mime = mime_guess::from_path(local_file_path).first_or_octet_stream(); + let hash = fxhash::hash(&content); + + Ok(( + ObjectIdentity { + workspace_id: workspace_id.to_owned(), + file_id: hash.to_string(), + ext, + }, + ObjectValue { + raw: content.into(), + mime, + }, + )) +} diff --git a/frontend/rust-lib/flowy-storage/src/wasm/mod.rs b/frontend/rust-lib/flowy-storage/src/wasm/mod.rs new file mode 100644 index 0000000000..8d4d3b1bfc --- /dev/null +++ b/frontend/rust-lib/flowy-storage/src/wasm/mod.rs @@ -0,0 +1,12 @@ +use crate::{ObjectIdentity, ObjectValue}; +use flowy_error::FlowyError; + +pub async fn object_from_disk( + _workspace_id: &str, + _local_file_path: &str, +) -> Result<(ObjectIdentity, ObjectValue), FlowyError> { + Err( + FlowyError::not_support() + .with_context(format!("object_from_disk is not implemented for wasm32")), + ) +} diff --git a/frontend/rust-lib/flowy-user-pub/Cargo.toml b/frontend/rust-lib/flowy-user-pub/Cargo.toml index 13311acbe5..548823d6c6 100644 --- a/frontend/rust-lib/flowy-user-pub/Cargo.toml +++ b/frontend/rust-lib/flowy-user-pub/Cargo.toml @@ -18,4 +18,10 @@ chrono = { workspace = true, default-features = false, features = ["clock", "se anyhow.workspace = true tokio = { workspace = true, features = ["sync"] } tokio-stream = "0.1.14" -flowy-folder-pub.workspace = true \ No newline at end of file +flowy-folder-pub.workspace = true +tracing.workspace = true +base64 = "0.21" + + +[features] +enable_wasm = [] \ No newline at end of file diff --git a/frontend/rust-lib/flowy-user-pub/src/cloud.rs b/frontend/rust-lib/flowy-user-pub/src/cloud.rs index 5be76a8eb0..c986c261b7 100644 --- a/frontend/rust-lib/flowy-user-pub/src/cloud.rs +++ b/frontend/rust-lib/flowy-user-pub/src/cloud.rs @@ -15,6 +15,7 @@ use flowy_error::{ErrorCode, FlowyError}; use lib_infra::box_any::BoxAny; use lib_infra::future::FutureResult; +use lib_infra::{if_native, if_wasm}; use crate::entities::{ AuthResponse, Authenticator, Role, UpdateUserProfileParams, UserCredentials, UserProfile, @@ -56,13 +57,21 @@ impl Display for UserCloudConfig { } } +if_native! { +pub trait UserCloudServiceProvider: UserCloudServiceProviderBase + Send + Sync + 'static {} +} + +if_wasm! { +pub trait UserCloudServiceProvider: UserCloudServiceProviderBase + 'static {} +} + /// `UserCloudServiceProvider` defines a set of methods for managing user cloud services, /// including token management, synchronization settings, network reachability, and authentication. /// /// This trait is intended for implementation by providers that offer cloud-based services for users. /// It includes methods for handling authentication tokens, enabling/disabling synchronization, /// setting network reachability, managing encryption secrets, and accessing user-specific cloud services. -pub trait UserCloudServiceProvider: Send + Sync + 'static { +pub trait UserCloudServiceProviderBase { /// Sets the authentication token for the cloud service. /// /// # Arguments @@ -94,7 +103,7 @@ pub trait UserCloudServiceProvider: Send + Sync + 'static { fn get_user_authenticator(&self) -> Authenticator; - /// Sets the network reachability statset_user_authenticatorus. + /// Sets the network reachability /// /// # Arguments /// * `reachable`: A boolean indicating whether the network is reachable. @@ -139,9 +148,17 @@ pub trait UserCloudService: Send + Sync + 'static { /// Currently, only use the admin client for testing fn generate_sign_in_url_with_email(&self, email: &str) -> FutureResult; + fn create_user(&self, email: &str, password: &str) -> FutureResult<(), FlowyError>; + + fn sign_in_with_password( + &self, + email: &str, + password: &str, + ) -> FutureResult; + /// When the user opens the OAuth URL, it redirects to the corresponding provider's OAuth web page. /// After the user is authenticated, the browser will open a deep link to the AppFlowy app (iOS, macOS, etc.), - /// which will call [Client::sign_in_with_url] to sign in. + /// which will call [Client::sign_in_with_url]generate_sign_in_url_with_email to sign in. /// /// For example, the OAuth URL on Google looks like `https://appflowy.io/authorize?provider=google`. fn generate_oauth_url_with_provider(&self, provider: &str) -> FutureResult; diff --git a/frontend/rust-lib/flowy-user-pub/src/entities.rs b/frontend/rust-lib/flowy-user-pub/src/entities.rs index 2d89d7aa3a..81bbb5be17 100644 --- a/frontend/rust-lib/flowy-user-pub/src/entities.rs +++ b/frontend/rust-lib/flowy-user-pub/src/entities.rs @@ -100,7 +100,7 @@ impl UserAuthResponse for AuthResponse { #[derive(Clone, Debug)] pub struct UserCredentials { - /// Currently, the token is only used when the [Authenticator] is AFCloud + /// Currently, the token is only used when the [Authenticator] is AppFlowyCloud pub token: Option, /// The user id @@ -391,3 +391,7 @@ pub struct WorkspaceMember { pub role: Role, pub name: String, } + +pub fn awareness_oid_from_user_uuid(user_uuid: &Uuid) -> Uuid { + Uuid::new_v5(user_uuid, b"user_awareness") +} diff --git a/frontend/rust-lib/flowy-user-pub/src/lib.rs b/frontend/rust-lib/flowy-user-pub/src/lib.rs index dbe947e074..2e51ecc626 100644 --- a/frontend/rust-lib/flowy-user-pub/src/lib.rs +++ b/frontend/rust-lib/flowy-user-pub/src/lib.rs @@ -1,5 +1,6 @@ pub mod cloud; pub mod entities; +pub mod session; pub mod workspace_service; pub const DEFAULT_USER_NAME: fn() -> String = || "Me".to_string(); diff --git a/frontend/rust-lib/flowy-user-pub/src/session.rs b/frontend/rust-lib/flowy-user-pub/src/session.rs new file mode 100644 index 0000000000..ef30bc1fc7 --- /dev/null +++ b/frontend/rust-lib/flowy-user-pub/src/session.rs @@ -0,0 +1,109 @@ +use crate::entities::{UserAuthResponse, UserWorkspace}; +use base64::engine::general_purpose::STANDARD; +use base64::Engine; +use chrono::Utc; +use serde::de::{MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_json::Value; +use std::fmt; +use uuid::Uuid; + +#[derive(Debug, Clone, Serialize)] +pub struct Session { + pub user_id: i64, + pub user_uuid: Uuid, + pub user_workspace: UserWorkspace, +} + +struct SessionVisitor; +impl<'de> Visitor<'de> for SessionVisitor { + type Value = Session; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("Session") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'de>, + { + let mut user_id = None; + let mut user_uuid = None; + // For historical reasons, the session used to contain a workspace_id field. + // This field is no longer used, and is replaced by user_workspace. + let mut workspace_id = None; + let mut user_workspace = None; + + while let Some(key) = map.next_key::()? { + match key.as_str() { + "user_id" => { + user_id = Some(map.next_value()?); + }, + "user_uuid" => { + user_uuid = Some(map.next_value()?); + }, + "workspace_id" => { + workspace_id = Some(map.next_value()?); + }, + "user_workspace" => { + user_workspace = Some(map.next_value()?); + }, + _ => { + let _ = map.next_value::(); + }, + } + } + let user_id = user_id.ok_or(serde::de::Error::missing_field("user_id"))?; + let user_uuid = user_uuid.ok_or(serde::de::Error::missing_field("user_uuid"))?; + if user_workspace.is_none() { + if let Some(workspace_id) = workspace_id { + user_workspace = Some(UserWorkspace { + id: workspace_id, + name: "My Workspace".to_string(), + created_at: Utc::now(), + // For historical reasons, the database_storage_id is constructed by the user_id. + database_view_tracker_id: STANDARD.encode(format!("{}:user:database", user_id)), + }) + } + } + + let session = Session { + user_id, + user_uuid, + user_workspace: user_workspace.ok_or(serde::de::Error::missing_field("user_workspace"))?, + }; + + Ok(session) + } +} + +impl<'de> Deserialize<'de> for Session { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_any(SessionVisitor) + } +} + +impl From<&T> for Session +where + T: UserAuthResponse, +{ + fn from(value: &T) -> Self { + Self { + user_id: value.user_id(), + user_uuid: *value.user_uuid(), + user_workspace: value.latest_workspace().clone(), + } + } +} + +impl std::convert::From for String { + fn from(session: Session) -> Self { + serde_json::to_string(&session).unwrap_or_else(|e| { + tracing::error!("Serialize session to string failed: {:?}", e); + "".to_string() + }) + } +} diff --git a/frontend/rust-lib/flowy-user/Cargo.toml b/frontend/rust-lib/flowy-user/Cargo.toml index 7b92151837..71163380a2 100644 --- a/frontend/rust-lib/flowy-user/Cargo.toml +++ b/frontend/rust-lib/flowy-user/Cargo.toml @@ -9,7 +9,7 @@ edition = "2018" flowy-derive.workspace = true flowy-sqlite = { workspace = true, optional = true } flowy-encrypt = { workspace = true } -flowy-error = { workspace = true, features = ["impl_from_dispatch_error"] } +flowy-error = { workspace = true, features = ["impl_from_dispatch_error", "impl_from_sqlite"] } flowy-folder-pub = { workspace = true } lib-infra = { workspace = true } flowy-notification = { workspace = true } @@ -59,7 +59,7 @@ quickcheck_macros = "1.0" default = ["rev-sqlite"] rev-sqlite = ["flowy-sqlite"] dart = ["flowy-codegen/dart", "flowy-notification/dart"] -ts = ["flowy-codegen/ts", "flowy-notification/ts"] +tauri_ts = ["flowy-codegen/ts", "flowy-notification/tauri_ts"] [build-dependencies] flowy-codegen.workspace = true diff --git a/frontend/rust-lib/flowy-user/build.rs b/frontend/rust-lib/flowy-user/build.rs index 06388d2a02..f1036a135d 100644 --- a/frontend/rust-lib/flowy-user/build.rs +++ b/frontend/rust-lib/flowy-user/build.rs @@ -1,10 +1,13 @@ fn main() { - let crate_name = env!("CARGO_PKG_NAME"); - flowy_codegen::protobuf_file::gen(crate_name); - #[cfg(feature = "dart")] - flowy_codegen::dart_event::gen(crate_name); + { + flowy_codegen::protobuf_file::dart_gen(env!("CARGO_PKG_NAME")); + flowy_codegen::dart_event::gen(env!("CARGO_PKG_NAME")); + } - #[cfg(feature = "ts")] - flowy_codegen::ts_event::gen(crate_name); + #[cfg(feature = "tauri_ts")] + { + flowy_codegen::ts_event::gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + flowy_codegen::protobuf_file::ts_gen(env!("CARGO_PKG_NAME"), flowy_codegen::Project::Tauri); + } } diff --git a/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs b/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs index d74046fc61..db74881c12 100644 --- a/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs +++ b/frontend/rust-lib/flowy-user/src/anon_user/migrate_anon_user_collab.rs @@ -21,7 +21,7 @@ use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_folder_pub::cloud::gen_view_id; use crate::migrations::AnonUser; -use crate::services::entities::Session; +use flowy_user_pub::session::Session; /// Migration the collab objects of the old user to new user. Currently, it only happens when /// the user is a local user and try to use AppFlowy cloud service. diff --git a/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs b/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs index 8629cf868c..b8486febb0 100644 --- a/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs +++ b/frontend/rust-lib/flowy-user/src/anon_user/sync_supabase_user_collab.rs @@ -17,8 +17,7 @@ use parking_lot::Mutex; use collab_integrate::{CollabKVAction, CollabKVDB, PersistenceError}; use flowy_error::FlowyResult; use flowy_user_pub::cloud::UserCloudService; - -use crate::services::entities::Session; +use flowy_user_pub::session::Session; #[tracing::instrument(level = "info", skip_all, err)] pub async fn sync_supabase_user_data_to_cloud( diff --git a/frontend/rust-lib/flowy-user/src/entities/auth.rs b/frontend/rust-lib/flowy-user/src/entities/auth.rs index 8c808c5bc8..f20978ed33 100644 --- a/frontend/rust-lib/flowy-user/src/entities/auth.rs +++ b/frontend/rust-lib/flowy-user/src/entities/auth.rs @@ -179,6 +179,26 @@ pub enum AuthenticatorPB { AppFlowyCloud = 2, } +impl From for AuthenticatorPB { + fn from(auth_type: Authenticator) -> Self { + match auth_type { + Authenticator::Supabase => AuthenticatorPB::Supabase, + Authenticator::Local => AuthenticatorPB::Local, + Authenticator::AppFlowyCloud => AuthenticatorPB::AppFlowyCloud, + } + } +} + +impl From for Authenticator { + fn from(pb: AuthenticatorPB) -> Self { + match pb { + AuthenticatorPB::Supabase => Authenticator::Supabase, + AuthenticatorPB::Local => Authenticator::Local, + AuthenticatorPB::AppFlowyCloud => Authenticator::AppFlowyCloud, + } + } +} + impl Default for AuthenticatorPB { fn default() -> Self { Self::Local diff --git a/frontend/rust-lib/flowy-user/src/entities/user_profile.rs b/frontend/rust-lib/flowy-user/src/entities/user_profile.rs index 83bd86e1f4..030c5b1179 100644 --- a/frontend/rust-lib/flowy-user/src/entities/user_profile.rs +++ b/frontend/rust-lib/flowy-user/src/entities/user_profile.rs @@ -70,7 +70,7 @@ impl Default for EncryptionTypePB { } } -impl std::convert::From for UserProfilePB { +impl From for UserProfilePB { fn from(user_profile: UserProfile) -> Self { let (encryption_sign, encryption_ty) = match user_profile.encryption_type { EncryptionType::NoEncryption => ("".to_string(), EncryptionTypePB::NoEncryption), diff --git a/frontend/rust-lib/flowy-user/src/event_map.rs b/frontend/rust-lib/flowy-user/src/event_map.rs index b328eb098e..5e03387fb9 100644 --- a/frontend/rust-lib/flowy-user/src/event_map.rs +++ b/frontend/rust-lib/flowy-user/src/event_map.rs @@ -13,14 +13,14 @@ use crate::event_handler::*; use crate::user_manager::UserManager; #[rustfmt::skip] -pub fn init(user_session: Weak) -> AFPlugin { - let store_preferences = user_session +pub fn init(user_manager: Weak) -> AFPlugin { + let store_preferences = user_manager .upgrade() .map(|session| session.get_store_preferences()) .unwrap(); AFPlugin::new() .name("Flowy-User") - .state(user_session) + .state(user_manager) .state(store_preferences) .event(UserEvent::SignInWithEmailPassword, sign_in_with_email_password_handler) .event(UserEvent::SignUp, sign_up) diff --git a/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs b/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs index 78a6dc6673..94c4a6104d 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs @@ -14,7 +14,7 @@ use flowy_user_pub::entities::Authenticator; use crate::migrations::migration::UserDataMigration; use crate::migrations::util::load_collab; -use crate::services::entities::Session; +use flowy_user_pub::session::Session; /// Migrate the first level documents of the workspace by inserting documents pub struct HistoricalEmptyDocumentMigration; diff --git a/frontend/rust-lib/flowy-user/src/migrations/migration.rs b/frontend/rust-lib/flowy-user/src/migrations/migration.rs index b4af365519..58f26130c9 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/migration.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/migration.rs @@ -9,7 +9,7 @@ use flowy_sqlite::schema::user_data_migration_records; use flowy_sqlite::ConnectionPool; use flowy_user_pub::entities::Authenticator; -use crate::services::entities::Session; +use flowy_user_pub::session::Session; pub struct UserLocalDataMigration { session: Session, diff --git a/frontend/rust-lib/flowy-user/src/migrations/mod.rs b/frontend/rust-lib/flowy-user/src/migrations/mod.rs index 0af4d3dde0..d5f83d47c9 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/mod.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/mod.rs @@ -1,4 +1,4 @@ -use crate::services::entities::Session; +use flowy_user_pub::session::Session; pub mod document_empty_content; pub mod migration; diff --git a/frontend/rust-lib/flowy-user/src/migrations/session_migration.rs b/frontend/rust-lib/flowy-user/src/migrations/session_migration.rs index 42af09cfe1..77376e1c6c 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/session_migration.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/session_migration.rs @@ -1,5 +1,5 @@ -use crate::services::entities::Session; use flowy_sqlite::kv::StorePreferences; +use flowy_user_pub::session::Session; use serde_json::{json, Value}; use std::sync::Arc; use uuid::Uuid; diff --git a/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs b/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs index dec5dcbeef..2f3e7aca3c 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs @@ -10,7 +10,7 @@ use flowy_user_pub::entities::Authenticator; use crate::migrations::migration::UserDataMigration; use crate::migrations::util::load_collab; -use crate::services::entities::Session; +use flowy_user_pub::session::Session; /// 1. Migrate the workspace: { favorite: [view_id] } to { favorite: { uid: [view_id] } } /// 2. Migrate { workspaces: [workspace object] } to { views: { workspace object } }. Make each folder diff --git a/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs b/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs index 798a8bc1cf..8e3e65c73b 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs @@ -10,7 +10,7 @@ use flowy_user_pub::entities::Authenticator; use crate::migrations::migration::UserDataMigration; use crate::migrations::util::load_collab; -use crate::services::entities::Session; +use flowy_user_pub::session::Session; /// Migrate the workspace: { trash: [view_id] } to { trash: { uid: [view_id] } } pub struct WorkspaceTrashMapToSectionMigration; diff --git a/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs b/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs index 3603c54abe..6f560f0811 100644 --- a/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs +++ b/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs @@ -1,12 +1,13 @@ use crate::migrations::session_migration::migrate_session_with_user_uuid; use crate::services::db::UserDB; -use crate::services::entities::{Session, UserConfig, UserPaths}; +use crate::services::entities::{UserConfig, UserPaths}; use crate::services::sqlite_sql::user_sql::vacuum_database; use collab_integrate::CollabKVDB; use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult}; use flowy_sqlite::kv::StorePreferences; use flowy_sqlite::DBConnection; +use flowy_user_pub::session::Session; use std::sync::{Arc, Weak}; use tracing::{debug, error, info}; diff --git a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs index 67d4d08e8e..6ae5ef2a53 100644 --- a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs +++ b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs @@ -1,9 +1,8 @@ use crate::migrations::session_migration::migrate_session_with_user_uuid; use crate::services::data_import::importer::load_collab_by_oid; use crate::services::db::UserDBPath; -use crate::services::entities::{Session, UserPaths}; +use crate::services::entities::UserPaths; use crate::services::sqlite_sql::user_sql::select_user_profile; -use crate::user_manager::manager_user_awareness::awareness_oid_from_user_uuid; use crate::user_manager::run_collab_data_migration; use anyhow::anyhow; use collab::core::collab::{CollabDocState, MutexCollab}; @@ -27,7 +26,8 @@ use flowy_folder_pub::entities::{AppFlowyData, ImportData}; use flowy_folder_pub::folder_builder::{ParentChildViews, ViewBuilder}; use flowy_sqlite::kv::StorePreferences; use flowy_user_pub::cloud::{UserCloudService, UserCollabParams}; -use flowy_user_pub::entities::Authenticator; +use flowy_user_pub::entities::{awareness_oid_from_user_uuid, Authenticator}; +use flowy_user_pub::session::Session; use parking_lot::{Mutex, RwLock}; use std::collections::{HashMap, HashSet}; use std::ops::{Deref, DerefMut}; diff --git a/frontend/rust-lib/flowy-user/src/services/data_import/importer.rs b/frontend/rust-lib/flowy-user/src/services/data_import/importer.rs index f4b98c0c3a..d12854f5fb 100644 --- a/frontend/rust-lib/flowy-user/src/services/data_import/importer.rs +++ b/frontend/rust-lib/flowy-user/src/services/data_import/importer.rs @@ -1,6 +1,6 @@ use crate::services::data_import::appflowy_data_import::import_appflowy_data_folder; -use crate::services::entities::Session; use collab_integrate::{CollabKVAction, CollabKVDB, PersistenceError}; +use flowy_user_pub::session::Session; use std::collections::HashMap; use crate::services::data_import::ImportContext; diff --git a/frontend/rust-lib/flowy-user/src/services/entities.rs b/frontend/rust-lib/flowy-user/src/services/entities.rs index 642bca01b8..b988feb7d0 100644 --- a/frontend/rust-lib/flowy-user/src/services/entities.rs +++ b/frontend/rust-lib/flowy-user/src/services/entities.rs @@ -1,142 +1,10 @@ use base64::alphabet::URL_SAFE; +use std::fs; use std::path::PathBuf; -use std::{fmt, fs}; - -use base64::engine::general_purpose::{PAD, STANDARD}; -use base64::engine::GeneralPurpose; -use base64::Engine; -use chrono::prelude::*; -use serde::de::{Deserializer, MapAccess, Visitor}; -use serde::{Deserialize, Serialize}; -use serde_json::Value; -use uuid::Uuid; - -use flowy_user_pub::entities::UserWorkspace; -use flowy_user_pub::entities::{Authenticator, UserAuthResponse}; - -use crate::entities::AuthenticatorPB; use crate::services::db::UserDBPath; - -#[derive(Debug, Clone, Serialize)] -pub struct Session { - pub user_id: i64, - pub user_uuid: Uuid, - pub user_workspace: UserWorkspace, -} - -struct SessionVisitor; -impl<'de> Visitor<'de> for SessionVisitor { - type Value = Session; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("Session") - } - - fn visit_map(self, mut map: M) -> Result - where - M: MapAccess<'de>, - { - let mut user_id = None; - let mut user_uuid = None; - // For historical reasons, the session used to contain a workspace_id field. - // This field is no longer used, and is replaced by user_workspace. - let mut workspace_id = None; - let mut user_workspace = None; - - while let Some(key) = map.next_key::()? { - match key.as_str() { - "user_id" => { - user_id = Some(map.next_value()?); - }, - "user_uuid" => { - user_uuid = Some(map.next_value()?); - }, - "workspace_id" => { - workspace_id = Some(map.next_value()?); - }, - "user_workspace" => { - user_workspace = Some(map.next_value()?); - }, - _ => { - let _ = map.next_value::(); - }, - } - } - let user_id = user_id.ok_or(serde::de::Error::missing_field("user_id"))?; - let user_uuid = user_uuid.ok_or(serde::de::Error::missing_field("user_uuid"))?; - if user_workspace.is_none() { - if let Some(workspace_id) = workspace_id { - user_workspace = Some(UserWorkspace { - id: workspace_id, - name: "My Workspace".to_string(), - created_at: Utc::now(), - // For historical reasons, the database_storage_id is constructed by the user_id. - database_view_tracker_id: STANDARD.encode(format!("{}:user:database", user_id)), - }) - } - } - - let session = Session { - user_id, - user_uuid, - user_workspace: user_workspace.ok_or(serde::de::Error::missing_field("user_workspace"))?, - }; - - Ok(session) - } -} - -impl<'de> Deserialize<'de> for Session { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_any(SessionVisitor) - } -} - -impl From<&T> for Session -where - T: UserAuthResponse, -{ - fn from(value: &T) -> Self { - Self { - user_id: value.user_id(), - user_uuid: *value.user_uuid(), - user_workspace: value.latest_workspace().clone(), - } - } -} - -impl std::convert::From for String { - fn from(session: Session) -> Self { - serde_json::to_string(&session).unwrap_or_else(|e| { - tracing::error!("Serialize session to string failed: {:?}", e); - "".to_string() - }) - } -} - -impl From for Authenticator { - fn from(pb: AuthenticatorPB) -> Self { - match pb { - AuthenticatorPB::Supabase => Authenticator::Supabase, - AuthenticatorPB::Local => Authenticator::Local, - AuthenticatorPB::AppFlowyCloud => Authenticator::AppFlowyCloud, - } - } -} - -impl From for AuthenticatorPB { - fn from(auth_type: Authenticator) -> Self { - match auth_type { - Authenticator::Supabase => AuthenticatorPB::Supabase, - Authenticator::Local => AuthenticatorPB::Local, - Authenticator::AppFlowyCloud => AuthenticatorPB::AppFlowyCloud, - } - } -} +use base64::engine::general_purpose::PAD; +use base64::engine::GeneralPurpose; pub const URL_SAFE_ENGINE: GeneralPurpose = GeneralPurpose::new(&URL_SAFE, PAD); #[derive(Clone)] diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager.rs index e45ea43d2e..d22b6ab04b 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager.rs @@ -36,13 +36,13 @@ use crate::services::collab_interact::{CollabInteract, DefaultCollabInteract}; use crate::services::data_import::importer::import_data; use crate::services::data_import::ImportContext; -use crate::services::entities::Session; use crate::services::sqlite_sql::user_sql::{select_user_profile, UserTable, UserTableChangeset}; use crate::user_manager::manager_user_awareness::UserAwarenessDataSource; use crate::user_manager::manager_user_encryption::validate_encryption_sign; use crate::user_manager::manager_user_workspace::save_user_workspaces; use crate::user_manager::user_login_state::UserAuthProcess; use crate::{errors::FlowyError, notification::*}; +use flowy_user_pub::session::Session; pub struct UserManager { pub(crate) cloud_services: Arc, @@ -171,9 +171,9 @@ impl UserManager { UserTokenState::Refresh { token } => { // Only save the token if the token is different from the current token if token != user_token { - if let Some(pool) = weak_pool.upgrade() { + if let Some(conn) = weak_pool.upgrade().and_then(|pool| pool.get().ok()) { // Save the new token - if let Err(err) = save_user_token(user_uid, pool, token) { + if let Err(err) = save_user_token(user_uid, conn, token) { error!("Save user token failed: {}", err); } } @@ -423,7 +423,7 @@ impl UserManager { #[tracing::instrument(level = "info", skip(self))] pub async fn sign_out(&self) -> Result<(), FlowyError> { if let Ok(session) = self.get_session() { - let _ = remove_user_token(session.user_id, self.db_pool(session.user_id)?); + let _ = remove_user_token(session.user_id, self.db_connection(session.user_id)?); self.authenticate_user.database.close(session.user_id)?; self.authenticate_user.set_session(None)?; @@ -448,7 +448,11 @@ impl UserManager { ) -> Result<(), FlowyError> { let changeset = UserTableChangeset::new(params.clone()); let session = self.get_session()?; - upsert_user_profile_change(session.user_id, self.db_pool(session.user_id)?, changeset)?; + upsert_user_profile_change( + session.user_id, + self.db_connection(session.user_id)?, + changeset, + )?; let profile = self.get_user_profile_from_disk(session.user_id).await?; self @@ -463,7 +467,7 @@ impl UserManager { pub async fn prepare_user(&self, session: &Session) { let _ = self.authenticate_user.database.close(session.user_id); - self.set_collab_config(session); + self.prepare_collab(session); } pub async fn prepare_backup(&self, session: &Session) { @@ -513,7 +517,7 @@ impl UserManager { let changeset = UserTableChangeset::from_user_profile(new_user_profile); let _ = upsert_user_profile_change( uid, - self.authenticate_user.database.get_pool(uid)?, + self.authenticate_user.database.get_connection(uid)?, changeset, ); } @@ -647,7 +651,7 @@ impl UserManager { self.set_anon_user(session.clone()); } - save_user_workspaces(uid, self.db_pool(uid)?, response.user_workspaces())?; + save_user_workspaces(uid, self.db_connection(uid)?, response.user_workspaces())?; event!(tracing::Level::INFO, "Save new user profile to disk"); self.authenticate_user.set_session(Some(session.clone()))?; self @@ -656,7 +660,7 @@ impl UserManager { Ok(()) } - fn set_collab_config(&self, session: &Session) { + fn prepare_collab(&self, session: &Session) { let collab_builder = self.collab_builder.upgrade().unwrap(); collab_builder.initialize(session.user_workspace.id.clone()); } @@ -673,7 +677,7 @@ impl UserManager { // Save the user profile change upsert_user_profile_change( user_update.uid, - self.db_pool(user_update.uid)?, + self.db_connection(user_update.uid)?, UserTableChangeset::from(user_update), )?; } @@ -724,7 +728,7 @@ impl UserManager { self .authenticate_user .database - .get_pool(old_user.session.user_id)?, + .get_connection(old_user.session.user_id)?, &[old_user.session.user_workspace.clone()], )?; Ok(()) @@ -759,7 +763,7 @@ fn current_authenticator() -> Authenticator { fn upsert_user_profile_change( uid: i64, - pool: Arc, + mut conn: DBConnection, changeset: UserTableChangeset, ) -> FlowyResult<()> { event!( @@ -767,7 +771,6 @@ fn upsert_user_profile_change( "Update user profile with changeset: {:?}", changeset ); - let mut conn = pool.get()?; diesel_update_table!(user_table, changeset, &mut *conn); let user: UserProfile = user_table::dsl::user_table .filter(user_table::id.eq(&uid.to_string())) @@ -780,15 +783,14 @@ fn upsert_user_profile_change( } #[instrument(level = "info", skip_all, err)] -fn save_user_token(uid: i64, pool: Arc, token: String) -> FlowyResult<()> { +fn save_user_token(uid: i64, conn: DBConnection, token: String) -> FlowyResult<()> { let params = UpdateUserProfileParams::new(uid).with_token(token); let changeset = UserTableChangeset::new(params); - upsert_user_profile_change(uid, pool, changeset) + upsert_user_profile_change(uid, conn, changeset) } #[instrument(level = "info", skip_all, err)] -fn remove_user_token(uid: i64, pool: Arc) -> FlowyResult<()> { - let mut conn = pool.get()?; +fn remove_user_token(uid: i64, mut conn: DBConnection) -> FlowyResult<()> { diesel::update(user_table::dsl::user_table.filter(user_table::id.eq(&uid.to_string()))) .set(user_table::token.eq("")) .execute(&mut *conn)?; diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager_history_user.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager_history_user.rs index f6da7d828e..251a77bd98 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager_history_user.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager_history_user.rs @@ -6,7 +6,7 @@ use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_user_pub::entities::Authenticator; use crate::migrations::AnonUser; -use crate::services::entities::Session; +use flowy_user_pub::session::Session; const ANON_USER: &str = "anon_user"; impl UserManager { diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs index eaa3c1dd67..e9db667eda 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs @@ -7,14 +7,14 @@ use collab_entity::CollabType; use collab_integrate::collab_builder::CollabBuilderConfig; use collab_user::core::{MutexUserAwareness, UserAwareness}; use tracing::{error, trace}; -use uuid::Uuid; use collab_integrate::CollabKVDB; use flowy_error::{ErrorCode, FlowyError, FlowyResult}; +use flowy_user_pub::entities::awareness_oid_from_user_uuid; use crate::entities::ReminderPB; -use crate::services::entities::Session; use crate::user_manager::UserManager; +use flowy_user_pub::session::Session; impl UserManager { /// Adds a new reminder based on the given payload. @@ -214,10 +214,6 @@ impl UserManager { } } -pub fn awareness_oid_from_user_uuid(user_uuid: &Uuid) -> Uuid { - Uuid::new_v5(user_uuid, b"user_awareness") -} - /// Indicate using which data source to initialize the user awareness /// If the user is not a new user, the local data source is used. Otherwise, the remote data source is used. /// When using the remote data source, the user awareness will be initialized from the remote server. diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs index 60e8c0741a..83e1c62f77 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs @@ -8,7 +8,7 @@ use tracing::{error, info, instrument}; use flowy_error::{FlowyError, FlowyResult}; use flowy_folder_pub::entities::{AppFlowyData, ImportData}; use flowy_sqlite::schema::user_workspace_table; -use flowy_sqlite::{query_dsl::*, ConnectionPool, ExpressionMethods}; +use flowy_sqlite::{query_dsl::*, DBConnection, ExpressionMethods}; use flowy_user_pub::entities::{Role, UserWorkspace, WorkspaceMember}; use lib_dispatch::prelude::af_spawn; @@ -16,9 +16,9 @@ use crate::entities::{RepeatedUserWorkspacePB, ResetWorkspacePB}; use crate::migrations::AnonUser; use crate::notification::{send_notification, UserNotification}; use crate::services::data_import::{upload_collab_objects_data, ImportContext}; -use crate::services::entities::Session; use crate::services::sqlite_sql::workspace_sql::UserWorkspaceTable; use crate::user_manager::UserManager; +use flowy_user_pub::session::Session; impl UserManager { /// Import appflowy data from the given path. @@ -56,7 +56,7 @@ impl UserManager { // with synchronous handler requirements." let (tx, rx) = tokio::sync::oneshot::channel(); let cloned_workspace_service = self.user_workspace_service.clone(); - tokio::spawn(async move { + af_spawn(async move { let result = async { cloned_workspace_service .did_import_database_views(database_view_ids_by_database_id) @@ -222,11 +222,13 @@ impl UserManager { if let Ok(pool) = self.db_pool(uid) { af_spawn(async move { if let Ok(new_user_workspaces) = service.get_all_workspace(uid).await { - let _ = save_user_workspaces(uid, pool, &new_user_workspaces); - let repeated_workspace_pbs = RepeatedUserWorkspacePB::from(new_user_workspaces); - send_notification(&uid.to_string(), UserNotification::DidUpdateUserWorkspaces) - .payload(repeated_workspace_pbs) - .send(); + if let Ok(conn) = pool.get() { + let _ = save_user_workspaces(uid, conn, &new_user_workspaces); + let repeated_workspace_pbs = RepeatedUserWorkspacePB::from(new_user_workspaces); + send_notification(&uid.to_string(), UserNotification::DidUpdateUserWorkspaces) + .payload(repeated_workspace_pbs) + .send(); + } } }); } @@ -255,7 +257,7 @@ impl UserManager { pub fn save_user_workspaces( uid: i64, - pool: Arc, + mut conn: DBConnection, user_workspaces: &[UserWorkspace], ) -> FlowyResult<()> { let user_workspaces = user_workspaces @@ -263,7 +265,6 @@ pub fn save_user_workspaces( .flat_map(|user_workspace| UserWorkspaceTable::try_from((uid, user_workspace)).ok()) .collect::>(); - let mut conn = pool.get()?; conn.immediate_transaction(|conn| { for user_workspace in user_workspaces { if let Err(err) = diesel::update( diff --git a/frontend/rust-lib/lib-dispatch/Cargo.toml b/frontend/rust-lib/lib-dispatch/Cargo.toml index 93258501f7..f0b6202775 100644 --- a/frontend/rust-lib/lib-dispatch/Cargo.toml +++ b/frontend/rust-lib/lib-dispatch/Cargo.toml @@ -34,6 +34,7 @@ thread-id = "3.3.0" [target.'cfg(target_arch = "wasm32")'.dependencies] getrandom = { version = "0.2", features = ["js"]} wasm-bindgen = { version = "0.2.89" } +wasm-bindgen-futures = "0.4" [dev-dependencies] tokio = { workspace = true, features = ["rt"] } @@ -43,7 +44,5 @@ futures-util = "0.3.26" default = ["use_protobuf"] use_serde = ["bincode", "serde_json", "serde", "serde_repr"] use_protobuf= ["protobuf"] -single_thread = [] -wasm_build = ["single_thread"] diff --git a/frontend/rust-lib/lib-dispatch/src/dispatcher.rs b/frontend/rust-lib/lib-dispatch/src/dispatcher.rs index 4237f2d45e..7ef38a8d46 100644 --- a/frontend/rust-lib/lib-dispatch/src/dispatcher.rs +++ b/frontend/rust-lib/lib-dispatch/src/dispatcher.rs @@ -16,60 +16,60 @@ use crate::{ service::{AFPluginServiceFactory, Service}, }; -#[cfg(feature = "single_thread")] +#[cfg(target_arch = "wasm32")] pub trait AFConcurrent {} -#[cfg(feature = "single_thread")] +#[cfg(target_arch = "wasm32")] impl AFConcurrent for T where T: ?Sized {} -#[cfg(not(feature = "single_thread"))] +#[cfg(not(target_arch = "wasm32"))] pub trait AFConcurrent: Send + Sync {} -#[cfg(not(feature = "single_thread"))] +#[cfg(not(target_arch = "wasm32"))] impl AFConcurrent for T where T: Send + Sync {} -#[cfg(feature = "single_thread")] +#[cfg(target_arch = "wasm32")] pub type AFBoxFuture<'a, T> = futures_core::future::LocalBoxFuture<'a, T>; -#[cfg(not(feature = "single_thread"))] +#[cfg(not(target_arch = "wasm32"))] pub type AFBoxFuture<'a, T> = futures_core::future::BoxFuture<'a, T>; pub type AFStateMap = std::sync::Arc; -#[cfg(feature = "single_thread")] +#[cfg(target_arch = "wasm32")] pub(crate) fn downcast_owned(boxed: AFBox) -> Option { boxed.downcast().ok().map(|boxed| *boxed) } -#[cfg(not(feature = "single_thread"))] +#[cfg(not(target_arch = "wasm32"))] pub(crate) fn downcast_owned(boxed: AFBox) -> Option { boxed.downcast().ok().map(|boxed| *boxed) } -#[cfg(feature = "single_thread")] +#[cfg(target_arch = "wasm32")] pub(crate) type AFBox = Box; -#[cfg(not(feature = "single_thread"))] +#[cfg(not(target_arch = "wasm32"))] pub(crate) type AFBox = Box; -#[cfg(feature = "single_thread")] +#[cfg(target_arch = "wasm32")] pub type BoxFutureCallback = Box AFBoxFuture<'static, ()> + 'static>; -#[cfg(not(feature = "single_thread"))] +#[cfg(not(target_arch = "wasm32"))] pub type BoxFutureCallback = Box AFBoxFuture<'static, ()> + Send + Sync + 'static>; -#[cfg(feature = "single_thread")] +#[cfg(target_arch = "wasm32")] pub fn af_spawn(future: T) -> tokio::task::JoinHandle where - T: Future + Send + 'static, - T::Output: Send + 'static, + T: Future + 'static, + T::Output: 'static, { - tokio::spawn(future) + tokio::task::spawn_local(future) } -#[cfg(not(feature = "single_thread"))] +#[cfg(not(target_arch = "wasm32"))] pub fn af_spawn(future: T) -> tokio::task::JoinHandle where T: Future + Send + 'static, @@ -92,10 +92,7 @@ impl AFPluginDispatcher { } } - pub async fn async_send( - dispatch: Arc, - request: Req, - ) -> AFPluginEventResponse + pub async fn async_send(dispatch: &AFPluginDispatcher, request: Req) -> AFPluginEventResponse where Req: Into, { @@ -103,7 +100,7 @@ impl AFPluginDispatcher { } pub async fn async_send_with_callback( - dispatch: Arc, + dispatch: &AFPluginDispatcher, request: Req, callback: Callback, ) -> AFPluginEventResponse @@ -146,7 +143,7 @@ impl AFPluginDispatcher { } pub fn box_async_send( - dispatch: Arc, + dispatch: &AFPluginDispatcher, request: Req, ) -> DispatchFuture where @@ -156,7 +153,7 @@ impl AFPluginDispatcher { } pub fn boxed_async_send_with_callback( - dispatch: Arc, + dispatch: &AFPluginDispatcher, request: Req, callback: Callback, ) -> DispatchFuture @@ -189,9 +186,10 @@ impl AFPluginDispatcher { }) }); + let runtime = dispatch.runtime.clone(); DispatchFuture { fut: Box::pin(async move { - let result = dispatch.runtime.run_until(handle).await; + let result = runtime.run_until(handle).await; result.unwrap_or_else(|e| { let msg = format!("EVENT_DISPATCH join error: {:?}", e); tracing::error!("{}", msg); @@ -202,19 +200,19 @@ impl AFPluginDispatcher { } } - #[cfg(not(feature = "single_thread"))] + #[cfg(not(target_arch = "wasm32"))] pub fn sync_send( dispatch: Arc, request: AFPluginRequest, ) -> AFPluginEventResponse { futures::executor::block_on(AFPluginDispatcher::async_send_with_callback( - dispatch, + dispatch.as_ref(), request, |_| Box::pin(async {}), )) } - #[cfg(feature = "single_thread")] + #[cfg(target_arch = "wasm32")] #[track_caller] pub fn spawn(&self, future: F) -> tokio::task::JoinHandle where @@ -223,7 +221,7 @@ impl AFPluginDispatcher { self.runtime.spawn(future) } - #[cfg(not(feature = "single_thread"))] + #[cfg(not(target_arch = "wasm32"))] #[track_caller] pub fn spawn(&self, future: F) -> tokio::task::JoinHandle where @@ -233,7 +231,7 @@ impl AFPluginDispatcher { self.runtime.spawn(future) } - #[cfg(feature = "single_thread")] + #[cfg(target_arch = "wasm32")] pub async fn run_until(&self, future: F) -> F::Output where F: Future + 'static, @@ -242,7 +240,7 @@ impl AFPluginDispatcher { self.runtime.run_until(handle).await.unwrap() } - #[cfg(not(feature = "single_thread"))] + #[cfg(not(target_arch = "wasm32"))] pub async fn run_until<'a, F>(&self, future: F) -> F::Output where F: Future + Send + 'a, diff --git a/frontend/rust-lib/lib-dispatch/src/request/payload.rs b/frontend/rust-lib/lib-dispatch/src/request/payload.rs index 6fc2a98e99..3a9c29adc4 100644 --- a/frontend/rust-lib/lib-dispatch/src/request/payload.rs +++ b/frontend/rust-lib/lib-dispatch/src/request/payload.rs @@ -18,6 +18,15 @@ impl Payload { } } +impl AsRef<[u8]> for Payload { + fn as_ref(&self) -> &[u8] { + match self { + Payload::None => &[], + Payload::Bytes(bytes) => bytes.as_ref(), + } + } +} + impl std::fmt::Debug for Payload { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { format_payload_print(self, f) diff --git a/frontend/rust-lib/lib-dispatch/src/runtime.rs b/frontend/rust-lib/lib-dispatch/src/runtime.rs index f918aa0054..98cbab4a4e 100644 --- a/frontend/rust-lib/lib-dispatch/src/runtime.rs +++ b/frontend/rust-lib/lib-dispatch/src/runtime.rs @@ -8,13 +8,13 @@ use tokio::task::JoinHandle; pub struct AFPluginRuntime { inner: Runtime, - #[cfg(feature = "single_thread")] + #[cfg(target_arch = "wasm32")] local: tokio::task::LocalSet, } impl Display for AFPluginRuntime { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - if cfg!(feature = "single_thread") { + if cfg!(target_arch = "wasm32") { write!(f, "Runtime(single_thread)") } else { write!(f, "Runtime(multi_thread)") @@ -27,12 +27,12 @@ impl AFPluginRuntime { let inner = default_tokio_runtime()?; Ok(Self { inner, - #[cfg(feature = "single_thread")] + #[cfg(target_arch = "wasm32")] local: tokio::task::LocalSet::new(), }) } - #[cfg(feature = "single_thread")] + #[cfg(target_arch = "wasm32")] #[track_caller] pub fn spawn(&self, future: F) -> JoinHandle where @@ -41,7 +41,7 @@ impl AFPluginRuntime { self.local.spawn_local(future) } - #[cfg(not(feature = "single_thread"))] + #[cfg(not(target_arch = "wasm32"))] #[track_caller] pub fn spawn(&self, future: F) -> JoinHandle where @@ -51,7 +51,7 @@ impl AFPluginRuntime { self.inner.spawn(future) } - #[cfg(feature = "single_thread")] + #[cfg(target_arch = "wasm32")] pub async fn run_until(&self, future: F) -> F::Output where F: Future, @@ -59,7 +59,7 @@ impl AFPluginRuntime { self.local.run_until(future).await } - #[cfg(not(feature = "single_thread"))] + #[cfg(not(target_arch = "wasm32"))] pub async fn run_until(&self, future: F) -> F::Output where F: Future, @@ -67,7 +67,7 @@ impl AFPluginRuntime { future.await } - #[cfg(feature = "single_thread")] + #[cfg(target_arch = "wasm32")] #[track_caller] pub fn block_on(&self, f: F) -> F::Output where @@ -76,7 +76,7 @@ impl AFPluginRuntime { self.local.block_on(&self.inner, f) } - #[cfg(not(feature = "single_thread"))] + #[cfg(not(target_arch = "wasm32"))] #[track_caller] pub fn block_on(&self, f: F) -> F::Output where @@ -86,14 +86,14 @@ impl AFPluginRuntime { } } -#[cfg(feature = "single_thread")] +#[cfg(target_arch = "wasm32")] pub fn default_tokio_runtime() -> io::Result { runtime::Builder::new_current_thread() .thread_name("dispatch-rt-st") .build() } -#[cfg(not(feature = "single_thread"))] +#[cfg(not(target_arch = "wasm32"))] pub fn default_tokio_runtime() -> io::Result { runtime::Builder::new_multi_thread() .thread_name("dispatch-rt-mt") diff --git a/frontend/rust-lib/lib-dispatch/src/service/boxed.rs b/frontend/rust-lib/lib-dispatch/src/service/boxed.rs index 76780e1d30..5c6e2f769c 100644 --- a/frontend/rust-lib/lib-dispatch/src/service/boxed.rs +++ b/frontend/rust-lib/lib-dispatch/src/service/boxed.rs @@ -16,7 +16,7 @@ where BoxServiceFactory(Box::new(FactoryWrapper(factory))) } -#[cfg(feature = "single_thread")] +#[cfg(target_arch = "wasm32")] type Inner = Box< dyn AFPluginServiceFactory< Req, @@ -27,7 +27,7 @@ type Inner = Box< Future = AFBoxFuture<'static, Result, Err>>, >, >; -#[cfg(not(feature = "single_thread"))] +#[cfg(not(target_arch = "wasm32"))] type Inner = Box< dyn AFPluginServiceFactory< Req, @@ -58,12 +58,12 @@ where } } -#[cfg(feature = "single_thread")] +#[cfg(target_arch = "wasm32")] pub type BoxService = Box< dyn Service>>, >; -#[cfg(not(feature = "single_thread"))] +#[cfg(not(target_arch = "wasm32"))] pub type BoxService = Box< dyn Service>> + Sync diff --git a/frontend/rust-lib/lib-dispatch/tests/api/module.rs b/frontend/rust-lib/lib-dispatch/tests/api/module.rs index 8e2a675cdf..2c4539bd7e 100644 --- a/frontend/rust-lib/lib-dispatch/tests/api/module.rs +++ b/frontend/rust-lib/lib-dispatch/tests/api/module.rs @@ -16,7 +16,7 @@ async fn test() { vec![AFPlugin::new().event(event, hello)], )); let request = AFPluginRequest::new(event); - let _ = AFPluginDispatcher::async_send_with_callback(dispatch.clone(), request, |resp| { + let _ = AFPluginDispatcher::async_send_with_callback(dispatch.as_ref(), request, |resp| { Box::pin(async move { dbg!(&resp); }) diff --git a/frontend/rust-lib/lib-infra/Cargo.toml b/frontend/rust-lib/lib-infra/Cargo.toml index 037d8dec6a..82f39cbf1b 100644 --- a/frontend/rust-lib/lib-infra/Cargo.toml +++ b/frontend/rust-lib/lib-infra/Cargo.toml @@ -31,5 +31,4 @@ zip = { version = "0.6.6", features = ["deflate"] } brotli = { version = "3.4.0", optional = true } [features] -compression = ["brotli"] -wasm_build = [] \ No newline at end of file +compression = ["brotli"] \ No newline at end of file diff --git a/frontend/rust-lib/lib-infra/src/lib.rs b/frontend/rust-lib/lib-infra/src/lib.rs index 2d7ac5d091..f6f1b4b1b0 100644 --- a/frontend/rust-lib/lib-infra/src/lib.rs +++ b/frontend/rust-lib/lib-infra/src/lib.rs @@ -1,15 +1,25 @@ pub use async_trait; pub mod box_any; -#[cfg(not(target_arch = "wasm32"))] -pub mod file_util; - #[cfg(feature = "compression")] pub mod compression; -pub mod future; +if_native! { + mod native; + pub mod file_util; + pub mod future { + pub use crate::native::future::*; + } +} + +if_wasm! { + mod wasm; + pub mod future { + pub use crate::wasm::future::*; + } +} + +pub mod priority_task; pub mod ref_map; pub mod util; pub mod validator_fn; - -pub mod priority_task; diff --git a/frontend/rust-lib/lib-infra/src/future.rs b/frontend/rust-lib/lib-infra/src/native/future.rs similarity index 100% rename from frontend/rust-lib/lib-infra/src/future.rs rename to frontend/rust-lib/lib-infra/src/native/future.rs diff --git a/frontend/rust-lib/lib-infra/src/native/mod.rs b/frontend/rust-lib/lib-infra/src/native/mod.rs new file mode 100644 index 0000000000..7cd38fb24b --- /dev/null +++ b/frontend/rust-lib/lib-infra/src/native/mod.rs @@ -0,0 +1 @@ +pub(crate) mod future; diff --git a/frontend/rust-lib/lib-infra/src/wasm/future.rs b/frontend/rust-lib/lib-infra/src/wasm/future.rs new file mode 100644 index 0000000000..635c50e214 --- /dev/null +++ b/frontend/rust-lib/lib-infra/src/wasm/future.rs @@ -0,0 +1,65 @@ +use futures_core::future::LocalBoxFuture; +use futures_core::ready; +use pin_project::pin_project; +use std::{ + fmt::Debug, + future::Future, + pin::Pin, + task::{Context, Poll}, +}; + +#[allow(dead_code)] +pub fn to_fut(f: T) -> Fut +where + T: Future + 'static, +{ + Fut { fut: Box::pin(f) } +} + +#[pin_project] +pub struct Fut { + #[pin] + pub fut: Pin>>, +} + +impl Future for Fut { + type Output = T; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.as_mut().project(); + Poll::Ready(ready!(this.fut.poll(cx))) + } +} + +#[allow(dead_code)] +#[pin_project] +pub struct FutureResult { + #[pin] + pub fut: Pin>>>, +} + +impl FutureResult { + #[allow(dead_code)] + pub fn new(f: F) -> Self + where + F: Future> + 'static, + { + Self { fut: Box::pin(f) } + } +} + +impl Future for FutureResult +where + E: Debug, +{ + type Output = Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.as_mut().project(); + let result = ready!(this.fut.poll(cx)); + Poll::Ready(result) + } +} + +#[allow(dead_code)] +pub type BoxResultFuture<'a, T, E> = LocalBoxFuture<'a, Result>; diff --git a/frontend/rust-lib/lib-infra/src/wasm/mod.rs b/frontend/rust-lib/lib-infra/src/wasm/mod.rs new file mode 100644 index 0000000000..4dba81d64f --- /dev/null +++ b/frontend/rust-lib/lib-infra/src/wasm/mod.rs @@ -0,0 +1 @@ +pub mod future; diff --git a/frontend/scripts/makefile/web.toml b/frontend/scripts/makefile/web.toml index e1cf6678c5..ef1676d642 100644 --- a/frontend/scripts/makefile/web.toml +++ b/frontend/scripts/makefile/web.toml @@ -5,15 +5,56 @@ script = [ """ #!/bin/bash BASE_DIR=$(pwd) -# crates=("lib-dispatch" "flowy-encrypt" "lib-infra" "flowy-notification" "flowy-date" "flowy-error" "collab-integrate" "flowy-document") - crates=("flowy-document") + crates=("lib-dispatch" "flowy-encrypt" "lib-infra" "flowy-notification" "flowy-date" "flowy-error" "collab-integrate" "flowy-document") # Iterate over each crate and build it for crate in "${crates[@]}"; do echo "🔥🔥🔥 Building $crate with wasm-pack..." cd "$BASE_DIR/rust-lib/$crate" || { echo "Failed to enter directory $crate"; exit 1; } - wasm-pack build --features="wasm_build" || { echo "Build failed for $crate"; exit 1; } + wasm-pack build --features="enable_wasm" || { echo "Build failed for $crate"; exit 1; } done """ ] + + +[tasks.web_clean] +description = "Remove all the building artifacts" +run_task = { name = [ + "rust_lib_clean", + "rm_macro_build_cache", + "rm_rust_generated_files", + "rm_web_generated_protobuf_files", + "rm_web_generated_event_files", +] } + + +[tasks.rm_web_generated_protobuf_files] +private = true +script = [""" + protobuf_file_paths = glob_array ${WEB_BACKEND_SERVICE_PATH}/models + if not array_is_empty ${protobuf_file_paths} + echo Remove generated protobuf files: + for path in ${protobuf_file_paths} + echo remove ${path} + rm -rf ${path} + end + end + """] +script_runner = "@duckscript" + + + +[tasks.rm_web_generated_event_files] +private = true +script = [""" + event_file_paths = glob_array ${WEB_BACKEND_SERVICE_PATH}/events + if not array_is_empty ${event_file_paths} + echo Remove generated protobuf files: + for path in ${event_file_paths} + echo remove ${path} + rm -rf ${path} + end + end + """] +script_runner = "@duckscript" \ No newline at end of file diff --git a/frontend/scripts/tool/update_client_api_rev.sh b/frontend/scripts/tool/update_client_api_rev.sh index f4a8e8bd28..472bb87d6f 100755 --- a/frontend/scripts/tool/update_client_api_rev.sh +++ b/frontend/scripts/tool/update_client_api_rev.sh @@ -8,12 +8,12 @@ fi NEW_REV="$1" echo "New revision: $NEW_REV" -directories=("rust-lib" "appflowy_tauri/src-tauri") +directories=("rust-lib" "appflowy_tauri/src-tauri" "appflowy_web/wasm-libs") for dir in "${directories[@]}"; do echo "Updating $dir" + pushd "$dir" > /dev/null - cd "$dir" sed -i.bak "/^client-api[[:alnum:]-]*[[:space:]]*=/s/rev = \"[a-fA-F0-9]\{6,40\}\"/rev = \"$NEW_REV\"/g" Cargo.toml # Detect changed crates @@ -25,6 +25,5 @@ for dir in "${directories[@]}"; do cargo update -p $crate done - cd .. + popd > /dev/null done - diff --git a/frontend/scripts/tool/update_collab_rev.sh b/frontend/scripts/tool/update_collab_rev.sh index c91302d5f4..1e3b6aa632 100755 --- a/frontend/scripts/tool/update_collab_rev.sh +++ b/frontend/scripts/tool/update_collab_rev.sh @@ -8,12 +8,12 @@ fi NEW_REV="$1" echo "New revision: $NEW_REV" -directories=("rust-lib" "appflowy_tauri/src-tauri") +directories=("rust-lib" "appflowy_tauri/src-tauri" "appflowy_web/wasm-libs") for dir in "${directories[@]}"; do echo "Updating $dir" + pushd "$dir" > /dev/null - cd "$dir" sed -i.bak "/^collab[[:alnum:]-]*[[:space:]]*=/s/rev = \"[a-fA-F0-9]\{6,40\}\"/rev = \"$NEW_REV\"/g" Cargo.toml # Detect changed crates @@ -30,6 +30,6 @@ for dir in "${directories[@]}"; do echo "Updating crates: $crates_to_update" cargo update $crates_to_update - cd .. + popd > /dev/null done