From b48cfe5730c73ac2d61106a33a57efb87286a839 Mon Sep 17 00:00:00 2001 From: Nick Mosher Date: Mon, 19 Jun 2023 09:29:29 -0400 Subject: [PATCH 1/9] fix: Remove dbg that was causing TUI rendering problems (#1085) --- packages/core/src/virtual_dom.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs index fe4d3e35b..b118cd59a 100644 --- a/packages/core/src/virtual_dom.rs +++ b/packages/core/src/virtual_dom.rs @@ -426,7 +426,7 @@ impl VirtualDom { } } - parent_path = dbg!(template.parent).and_then(|id| self.elements.get(id.0)); + parent_path = template.parent.and_then(|id| self.elements.get(id.0)); } else { break; } From 96802c27ef14625a349b9491fd10150a97e9897b Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 19 Jun 2023 06:46:52 -0700 Subject: [PATCH 2/9] fixed typo in README (#1098) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 40981401e..9a1c347c9 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ fn app(cx: Scope) -> Element { } ``` -Dioxus can be used to deliver webapps, desktop apps, static sites, mobile apps, TUI apps, liveview apps, and more. Dioxus is entirely renderer agnostic and can be used as platform for any renderer. +Dioxus can be used to deliver webapps, desktop apps, static sites, mobile apps, TUI apps, liveview apps, and more. Dioxus is entirely renderer agnostic and can be used as a platform for any renderer. If you know React, then you already know Dioxus. From d596967b4008739ee328ec213fedc24b53987942 Mon Sep 17 00:00:00 2001 From: Jon Earnshaw <1021321+jpearnshaw@users.noreply.github.com> Date: Mon, 19 Jun 2023 14:49:43 +0100 Subject: [PATCH 3/9] Fix typos on Event Handlers page (#1102) * Fix typo on Event Handlers page * Fix 2nd typo on Event Handlers page --- docs/guide/src/en/interactivity/event_handlers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/src/en/interactivity/event_handlers.md b/docs/guide/src/en/interactivity/event_handlers.md index 317038923..e1057f98b 100644 --- a/docs/guide/src/en/interactivity/event_handlers.md +++ b/docs/guide/src/en/interactivity/event_handlers.md @@ -29,7 +29,7 @@ To learn what the different event types for HTML provide, read the [events modul Some events will trigger first on the element the event originated at upward. For example, a click event on a `button` inside a `div` would first trigger the button's event listener and then the div's event listener. -> For more information about event propigation see [the mdn docs on event bubling](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#event_bubbling) +> For more information about event propagation see [the mdn docs on event bubbling](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#event_bubbling) If you want to prevent this behavior, you can call `stop_propagation()` on the event: From 6e5fbcff6384ee0f7ef50abc22c4c3cca7aa6d70 Mon Sep 17 00:00:00 2001 From: James Fletcher <38212943+jmsfltchr@users.noreply.github.com> Date: Mon, 19 Jun 2023 15:26:02 +0100 Subject: [PATCH 4/9] Increase the number of tokio channels for the query engine from 8 to 1000. (#1095) --- packages/desktop/src/query.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/desktop/src/query.rs b/packages/desktop/src/query.rs index bd8b2ee2a..fb23dc487 100644 --- a/packages/desktop/src/query.rs +++ b/packages/desktop/src/query.rs @@ -22,7 +22,7 @@ pub(crate) struct QueryEngine { impl Default for QueryEngine { fn default() -> Self { - let (sender, _) = tokio::sync::broadcast::channel(8); + let (sender, _) = tokio::sync::broadcast::channel(1000); Self { sender: Rc::new(sender), active_requests: SharedSlab::default(), From 8a16eb4cb3552023a8e8b384b47abb7ccd64d13f Mon Sep 17 00:00:00 2001 From: Dirk Stolle Date: Mon, 19 Jun 2023 19:43:33 +0200 Subject: [PATCH 5/9] replace unmaintained actions-rs/* actions in CI workflows (#1099) Basically all of the `actions-rs/*` actions are unmaintained. See for more information. Due to their age they generate several warnings in CI runs. To get rid of those warnings the occurrences of `actions-rs/toolchain` are replaced by `dtolnay/rust-toolchain`, and the occurrences of `actions-rs/cargo` are replaced by direct invocations of `cargo`. --- .github/workflows/macos.yml | 11 ++-------- .github/workflows/main.yml | 44 +++++++------------------------------ 2 files changed, 10 insertions(+), 45 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index c5616322e..b80a7b1f5 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -30,14 +30,7 @@ jobs: name: Test Suite runs-on: macos-latest steps: - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true + - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - uses: actions/checkout@v3 - - uses: actions-rs/cargo@v1 - with: - command: test - args: --all --tests + - run: cargo test --all --tests diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a3bff9fc6..1a4b156cd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,30 +32,19 @@ jobs: name: Check runs-on: ubuntu-latest steps: - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true + - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - run: sudo apt-get update - run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev - uses: actions/checkout@v3 - - uses: actions-rs/cargo@v1 - with: - command: check - args: --all --examples --tests + - run: cargo check --all --examples --tests test: if: github.event.pull_request.draft == false name: Test Suite runs-on: ubuntu-latest steps: - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true + - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - run: sudo apt-get update - run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev @@ -63,48 +52,31 @@ jobs: - uses: browser-actions/setup-firefox@latest - uses: jetli/wasm-pack-action@v0.4.0 - uses: actions/checkout@v3 - - uses: actions-rs/cargo@v1 - with: - command: make - args: tests + - run: cargo make tests fmt: if: github.event.pull_request.draft == false name: Rustfmt runs-on: ubuntu-latest steps: - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true + - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - run: rustup component add rustfmt - uses: actions/checkout@v3 - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check + - run: cargo fmt --all -- --check clippy: if: github.event.pull_request.draft == false name: Clippy runs-on: ubuntu-latest steps: - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true + - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - run: sudo apt-get update - run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev - run: rustup component add clippy - uses: actions/checkout@v3 - - uses: actions-rs/cargo@v1 - with: - command: clippy - args: --workspace --examples --tests -- -D warnings + - run: cargo clippy --workspace --examples --tests -- -D warnings # Coverage is disabled until we can fix it # coverage: From 158852e5a0afe64deff5270116d4f83da53458b8 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 19 Jun 2023 16:08:46 -0500 Subject: [PATCH 6/9] make regestering server functions optional --- docs/guide/examples/server_context.rs | 3 - docs/guide/examples/server_context_state.rs | 3 - docs/guide/examples/server_function.rs | 3 - packages/fullstack/Cargo.toml | 2 +- packages/fullstack/README.md | 1 - .../examples/axum-desktop/src/server.rs | 3 - .../examples/axum-hello-world/src/main.rs | 2 - .../examples/axum-router/src/main.rs | 2 - .../examples/salvo-hello-world/src/main.rs | 2 - .../examples/warp-hello-world/src/main.rs | 2 - packages/fullstack/server-macro/Cargo.toml | 4 +- packages/fullstack/server-macro/src/lib.rs | 2 +- .../fullstack/src/adapters/axum_adapter.rs | 15 ++- .../fullstack/src/adapters/salvo_adapter.rs | 24 ++--- .../fullstack/src/adapters/warp_adapter.rs | 17 ++-- packages/fullstack/src/lib.rs | 2 +- packages/fullstack/src/server_fn.rs | 98 ++++++++++++++----- 17 files changed, 106 insertions(+), 79 deletions(-) diff --git a/docs/guide/examples/server_context.rs b/docs/guide/examples/server_context.rs index 446b0a93a..eb3c5e9c1 100644 --- a/docs/guide/examples/server_context.rs +++ b/docs/guide/examples/server_context.rs @@ -16,9 +16,6 @@ fn main() { use axum::extract::State; use axum::routing::get; - // Register the server function before starting the server - DoubleServer::register().unwrap(); - tokio::runtime::Runtime::new() .unwrap() .block_on(async move { diff --git a/docs/guide/examples/server_context_state.rs b/docs/guide/examples/server_context_state.rs index 390849ff6..c75496561 100644 --- a/docs/guide/examples/server_context_state.rs +++ b/docs/guide/examples/server_context_state.rs @@ -25,9 +25,6 @@ fn main() { use axum::routing::get; use std::sync::Arc; - // Register the server function before starting the server - DoubleServer::register().unwrap(); - tokio::runtime::Runtime::new() .unwrap() .block_on(async move { diff --git a/docs/guide/examples/server_function.rs b/docs/guide/examples/server_function.rs index d803ea60d..55f5104f9 100644 --- a/docs/guide/examples/server_function.rs +++ b/docs/guide/examples/server_function.rs @@ -16,9 +16,6 @@ fn main() { use axum::extract::State; use axum::routing::get; - // Register the server function before starting the server - DoubleServer::register().unwrap(); - tokio::runtime::Runtime::new() .unwrap() .block_on(async move { diff --git a/packages/fullstack/Cargo.toml b/packages/fullstack/Cargo.toml index 5e7da25ca..3a64f8570 100644 --- a/packages/fullstack/Cargo.toml +++ b/packages/fullstack/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["dom", "ui", "gui", "react", "ssr", "fullstack"] [dependencies] # server functions -server_fn = { git = "https://github.com/leptos-rs/leptos", rev = "671b1e4a8fff7a2e05bb621ef08e87be2b18ccae", default-features = false, features = ["stable"] } +server_fn = { git = "https://github.com/leptos-rs/leptos", rev = "15a4e54435eb5a539afb75891292bcccd2cc8e85", default-features = false, features = ["stable"] } dioxus_server_macro = { path = "server-macro" } # warp diff --git a/packages/fullstack/README.md b/packages/fullstack/README.md index ec3d1c833..ecd003ee8 100644 --- a/packages/fullstack/README.md +++ b/packages/fullstack/README.md @@ -46,7 +46,6 @@ fn main() { ); #[cfg(feature = "ssr")] { - GetMeaning::register().unwrap(); tokio::runtime::Runtime::new() .unwrap() .block_on(async move { diff --git a/packages/fullstack/examples/axum-desktop/src/server.rs b/packages/fullstack/examples/axum-desktop/src/server.rs index 7602d1e48..6098ae3f4 100644 --- a/packages/fullstack/examples/axum-desktop/src/server.rs +++ b/packages/fullstack/examples/axum-desktop/src/server.rs @@ -8,9 +8,6 @@ use dioxus_fullstack::prelude::*; #[tokio::main] async fn main() { - PostServerData::register().unwrap(); - GetServerData::register().unwrap(); - let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 8080)); axum::Server::bind(&addr) .serve( diff --git a/packages/fullstack/examples/axum-hello-world/src/main.rs b/packages/fullstack/examples/axum-hello-world/src/main.rs index 0301a190c..66c3af096 100644 --- a/packages/fullstack/examples/axum-hello-world/src/main.rs +++ b/packages/fullstack/examples/axum-hello-world/src/main.rs @@ -32,8 +32,6 @@ fn main() { true })); - PostServerData::register().unwrap(); - GetServerData::register().unwrap(); tokio::runtime::Runtime::new() .unwrap() .block_on(async move { diff --git a/packages/fullstack/examples/axum-router/src/main.rs b/packages/fullstack/examples/axum-router/src/main.rs index 96567c791..2b98ad842 100644 --- a/packages/fullstack/examples/axum-router/src/main.rs +++ b/packages/fullstack/examples/axum-router/src/main.rs @@ -34,8 +34,6 @@ fn main() { })); use axum::extract::State; - PostServerData::register().unwrap(); - GetServerData::register().unwrap(); tokio::runtime::Runtime::new() .unwrap() .block_on(async move { diff --git a/packages/fullstack/examples/salvo-hello-world/src/main.rs b/packages/fullstack/examples/salvo-hello-world/src/main.rs index 0cbd3598f..01b67ff99 100644 --- a/packages/fullstack/examples/salvo-hello-world/src/main.rs +++ b/packages/fullstack/examples/salvo-hello-world/src/main.rs @@ -33,8 +33,6 @@ fn main() { })); use salvo::prelude::*; - PostServerData::register().unwrap(); - GetServerData::register().unwrap(); tokio::runtime::Runtime::new() .unwrap() .block_on(async move { diff --git a/packages/fullstack/examples/warp-hello-world/src/main.rs b/packages/fullstack/examples/warp-hello-world/src/main.rs index 5e4c9aecb..34fc24c77 100644 --- a/packages/fullstack/examples/warp-hello-world/src/main.rs +++ b/packages/fullstack/examples/warp-hello-world/src/main.rs @@ -32,8 +32,6 @@ fn main() { true })); - PostServerData::register().unwrap(); - GetServerData::register().unwrap(); tokio::runtime::Runtime::new() .unwrap() .block_on(async move { diff --git a/packages/fullstack/server-macro/Cargo.toml b/packages/fullstack/server-macro/Cargo.toml index 286481bdd..cb039057b 100644 --- a/packages/fullstack/server-macro/Cargo.toml +++ b/packages/fullstack/server-macro/Cargo.toml @@ -7,8 +7,8 @@ edition = "2021" [dependencies] quote = "1.0.26" -server_fn_macro = { git = "https://github.com/leptos-rs/leptos", rev = "671b1e4a8fff7a2e05bb621ef08e87be2b18ccae", features = ["stable"] } -syn = { version = "1", features = ["full"] } +server_fn_macro = { git = "https://github.com/leptos-rs/leptos", rev = "15a4e54435eb5a539afb75891292bcccd2cc8e85", features = ["stable"] } +syn = { version = "2", features = ["full"] } [lib] proc-macro = true diff --git a/packages/fullstack/server-macro/src/lib.rs b/packages/fullstack/server-macro/src/lib.rs index f6df526c1..9a1a2c9c7 100644 --- a/packages/fullstack/server-macro/src/lib.rs +++ b/packages/fullstack/server-macro/src/lib.rs @@ -35,7 +35,6 @@ use server_fn_macro::*; /// ``` /// /// Note the following: -/// - You must **register** the server function by calling `T::register()` somewhere in your main function. /// - **Server functions must be `async`.** Even if the work being done inside the function body /// can run synchronously on the server, from the client’s perspective it involves an asynchronous /// function call. @@ -62,6 +61,7 @@ pub fn server(args: proc_macro::TokenStream, s: TokenStream) -> TokenStream { match server_macro_impl( args.into(), s.into(), + syn::parse_quote!(::dioxus_fullstack::prelude::ServerFnTraitObj), Some(context), Some(syn::parse_quote!(::dioxus_fullstack::prelude::server_fn)), ) { diff --git a/packages/fullstack/src/adapters/axum_adapter.rs b/packages/fullstack/src/adapters/axum_adapter.rs index c634d7f77..1ff136d4d 100644 --- a/packages/fullstack/src/adapters/axum_adapter.rs +++ b/packages/fullstack/src/adapters/axum_adapter.rs @@ -12,7 +12,6 @@ //! dioxus_web::launch_cfg(app, dioxus_web::Config::new().hydrate(true)); //! #[cfg(feature = "ssr")] //! { -//! GetServerData::register().unwrap(); //! tokio::runtime::Runtime::new() //! .unwrap() //! .block_on(async move { @@ -107,7 +106,7 @@ pub trait DioxusRouterExt { fn register_server_fns_with_handler( self, server_fn_route: &'static str, - handler: impl Fn(ServerFunction) -> H, + handler: impl FnMut(server_fn::ServerFnTraitObj) -> H, ) -> Self where H: Handler, @@ -232,7 +231,7 @@ where fn register_server_fns_with_handler( self, server_fn_route: &'static str, - mut handler: impl FnMut(ServerFunction) -> H, + mut handler: impl FnMut(server_fn::ServerFnTraitObj) -> H, ) -> Self where H: Handler, @@ -243,7 +242,7 @@ where for server_fn_path in DioxusServerFnRegistry::paths_registered() { let func = DioxusServerFnRegistry::get(server_fn_path).unwrap(); let full_route = format!("{server_fn_route}/{server_fn_path}"); - match func.encoding { + match func.encoding() { Encoding::Url | Encoding::Cbor => { router = router.route(&full_route, post(handler(func))); } @@ -314,7 +313,7 @@ where let cfg = cfg.into(); // Add server functions and render index.html - self.serve_static_assets(&cfg.assets_path) + self.serve_static_assets(cfg.assets_path) .route( "/", get(render_handler).with_state((cfg, SSRState::default())), @@ -371,7 +370,7 @@ async fn render_handler( /// A default handler for server functions. It will deserialize the request, call the server function, and serialize the response. pub async fn server_fn_handler( server_context: DioxusServerContext, - function: ServerFunction, + function: server_fn::ServerFnTraitObj, parts: Arc, body: Body, ) -> impl IntoResponse { @@ -389,11 +388,11 @@ pub async fn server_fn_handler( .expect("couldn't spawn runtime") .block_on(async { let query = &query_string.into(); - let data = match &function.encoding { + let data = match &function.encoding() { Encoding::Url | Encoding::Cbor => &body, Encoding::GetJSON | Encoding::GetCBOR => query, }; - let resp = match (function.trait_obj)(server_context.clone(), &data).await { + let resp = match function.call(server_context.clone(), data).await { Ok(serialized) => { // if this is Accept: application/json then send a serialized JSON response let accept_header = parts diff --git a/packages/fullstack/src/adapters/salvo_adapter.rs b/packages/fullstack/src/adapters/salvo_adapter.rs index 94814fea0..c2968ff75 100644 --- a/packages/fullstack/src/adapters/salvo_adapter.rs +++ b/packages/fullstack/src/adapters/salvo_adapter.rs @@ -12,7 +12,6 @@ //! #[cfg(feature = "ssr")] //! { //! use salvo::prelude::*; -//! GetServerData::register().unwrap(); //! tokio::runtime::Runtime::new() //! .unwrap() //! .block_on(async move { @@ -110,7 +109,7 @@ pub trait DioxusRouterExt { fn register_server_fns_with_handler( self, server_fn_route: &'static str, - handler: impl Fn(ServerFunction) -> H, + handler: impl Fn(server_fn::ServerFnTraitObj) -> H, ) -> Self where H: Handler + 'static; @@ -204,7 +203,7 @@ impl DioxusRouterExt for Router { fn register_server_fns_with_handler( self, server_fn_route: &'static str, - mut handler: impl FnMut(ServerFunction) -> H, + mut handler: impl FnMut(server_fn::ServerFnTraitObj) -> H, ) -> Self where H: Handler + 'static, @@ -213,7 +212,7 @@ impl DioxusRouterExt for Router { for server_fn_path in DioxusServerFnRegistry::paths_registered() { let func = DioxusServerFnRegistry::get(server_fn_path).unwrap(); let full_route = format!("{server_fn_route}/{server_fn_path}"); - match func.encoding { + match func.encoding() { Encoding::Url | Encoding::Cbor => { router = router.push(Router::with_path(&full_route).post(handler(func))); } @@ -280,7 +279,7 @@ impl DioxusRouterExt for Router { ) -> Self { let cfg = cfg.into(); - self.serve_static_assets(&cfg.assets_path) + self.serve_static_assets(cfg.assets_path) .connect_hot_reload() .register_server_fns(server_fn_path) .push(Router::with_path("/").get(SSRHandler { cfg })) @@ -288,8 +287,8 @@ impl DioxusRouterExt for Router { fn connect_hot_reload(self) -> Self { let mut _dioxus_router = Router::with_path("_dioxus"); - _dioxus_router = _dioxus_router - .push(Router::with_path("hot_reload").handle(HotReloadHandler::default())); + _dioxus_router = + _dioxus_router.push(Router::with_path("hot_reload").handle(HotReloadHandler)); #[cfg(all(debug_assertions, feature = "hot-reload", feature = "ssr"))] { _dioxus_router = _dioxus_router.push(Router::with_path("disconnect").handle(ignore_ws)); @@ -346,12 +345,15 @@ impl Handler for SSRHandler /// A default handler for server functions. It will deserialize the request body, call the server function, and serialize the response. pub struct ServerFnHandler { server_context: DioxusServerContext, - function: ServerFunction, + function: server_fn::ServerFnTraitObj, } impl ServerFnHandler { /// Create a new server function handler with the given server context and server function. - pub fn new(server_context: impl Into, function: ServerFunction) -> Self { + pub fn new( + server_context: impl Into, + function: server_fn::ServerFnTraitObj, + ) -> Self { let server_context = server_context.into(); Self { server_context, @@ -395,11 +397,11 @@ impl ServerFnHandler { tokio::runtime::Runtime::new() .expect("couldn't spawn runtime") .block_on(async move { - let data = match &function.encoding { + let data = match function.encoding() { Encoding::Url | Encoding::Cbor => &body, Encoding::GetJSON | Encoding::GetCBOR => &query, }; - let resp = (function.trait_obj)(server_context, data).await; + let resp = function.call(server_context, data).await; resp_tx.send(resp).unwrap(); }) diff --git a/packages/fullstack/src/adapters/warp_adapter.rs b/packages/fullstack/src/adapters/warp_adapter.rs index 872a94cdd..b9f23ae7f 100644 --- a/packages/fullstack/src/adapters/warp_adapter.rs +++ b/packages/fullstack/src/adapters/warp_adapter.rs @@ -11,7 +11,6 @@ //! dioxus_web::launch_cfg(app, dioxus_web::Config::new().hydrate(true)); //! #[cfg(feature = "ssr")] //! { -//! GetServerData::register().unwrap(); //! tokio::runtime::Runtime::new() //! .unwrap() //! .block_on(async move { @@ -93,7 +92,7 @@ pub fn register_server_fns_with_handler( mut handler: H, ) -> BoxedFilter<(R,)> where - H: FnMut(String, ServerFunction) -> F, + H: FnMut(String, server_fn::ServerFnTraitObj) -> F, F: Filter + Send + Sync + 'static, F::Extract: Send, R: Reply + 'static, @@ -104,7 +103,7 @@ where let full_route = format!("{server_fn_route}/{server_fn_path}") .trim_start_matches('/') .to_string(); - let route = handler(full_route, func.clone()).boxed(); + let route = handler(full_route, func).boxed(); if let Some(boxed_filter) = filter.take() { filter = Some(boxed_filter.or(route).unify().boxed()); } else { @@ -128,7 +127,7 @@ where /// ``` pub fn register_server_fns(server_fn_route: &'static str) -> BoxedFilter<(impl Reply,)> { register_server_fns_with_handler(server_fn_route, |full_route, func| { - path(full_route.clone()) + path(full_route) .and(warp::post().or(warp::get()).unify()) .and(request_parts()) .and(warp::body::bytes()) @@ -250,7 +249,7 @@ impl warp::reject::Reject for RecieveFailed {} /// A default handler for server functions. It will deserialize the request body, call the server function, and serialize the response. pub async fn server_fn_handler( server_context: impl Into, - function: ServerFunction, + function: server_fn::ServerFnTraitObj, parts: RequestParts, body: Bytes, ) -> Result, warp::Rejection> { @@ -274,11 +273,11 @@ pub async fn server_fn_handler( .as_bytes() .to_vec() .into(); - let data = match &function.encoding { + let data = match function.encoding() { Encoding::Url | Encoding::Cbor => &body, Encoding::GetJSON | Encoding::GetCBOR => &query, }; - let resp = match (function.trait_obj)(server_context.clone(), data).await { + let resp = match function.call(server_context.clone(), data).await { Ok(serialized) => { // if this is Accept: application/json then send a serialized JSON response let accept_header = parts @@ -373,7 +372,7 @@ pub fn connect_hot_reload() -> impl Filter impl Filter); impl Drop for DisconnectOnDrop { fn drop(&mut self) { - let _ = self.0.take().unwrap().close(); + std::mem::drop(self.0.take().unwrap().close()); } } diff --git a/packages/fullstack/src/lib.rs b/packages/fullstack/src/lib.rs index be437bc53..18cde9adb 100644 --- a/packages/fullstack/src/lib.rs +++ b/packages/fullstack/src/lib.rs @@ -34,7 +34,7 @@ pub mod prelude { #[cfg(feature = "ssr")] pub use crate::server_context::RequestParts; pub use crate::server_context::{DioxusServerContext, HasServerContext}; - pub use crate::server_fn::ServerFn; + pub use crate::server_fn::DioxusServerFn; #[cfg(feature = "ssr")] pub use crate::server_fn::{ServerFnTraitObj, ServerFunction}; pub use dioxus_server_macro::*; diff --git a/packages/fullstack/src/server_fn.rs b/packages/fullstack/src/server_fn.rs index da7311263..231285149 100644 --- a/packages/fullstack/src/server_fn.rs +++ b/packages/fullstack/src/server_fn.rs @@ -1,30 +1,76 @@ use crate::server_context::DioxusServerContext; #[cfg(any(feature = "ssr", doc))] +#[derive(Clone)] /// A trait object for a function that be called on serializable arguments and returns a serializable result. -pub type ServerFnTraitObj = server_fn::ServerFnTraitObj; +pub struct ServerFnTraitObj(server_fn::ServerFnTraitObj); + +#[cfg(any(feature = "ssr", doc))] +impl std::ops::Deref for ServerFnTraitObj { + type Target = server_fn::ServerFnTraitObj; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[cfg(any(feature = "ssr", doc))] +impl std::ops::DerefMut for ServerFnTraitObj { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +#[cfg(any(feature = "ssr", doc))] +impl ServerFnTraitObj { + fn new( + prefix: &'static str, + url: &'static str, + encoding: server_fn::Encoding, + run: ServerFunction, + ) -> Self { + Self(server_fn::ServerFnTraitObj::new(prefix, url, encoding, run)) + } + + /// Create a new `ServerFnTraitObj` from a `server_fn::ServerFnTraitObj`. + pub const fn from_generic_server_fn( + server_fn: server_fn::ServerFnTraitObj, + ) -> Self { + Self(server_fn) + } +} + +#[cfg(any(feature = "ssr", doc))] +server_fn::inventory::collect!(ServerFnTraitObj); #[cfg(any(feature = "ssr", doc))] /// A server function that can be called on serializable arguments and returns a serializable result. -pub type ServerFunction = server_fn::ServerFunction; +pub type ServerFunction = server_fn::SerializedFnTraitObj; #[cfg(any(feature = "ssr", doc))] #[allow(clippy::type_complexity)] static REGISTERED_SERVER_FUNCTIONS: once_cell::sync::Lazy< - std::sync::Arc>>, -> = once_cell::sync::Lazy::new(Default::default); + std::sync::Arc>>, +> = once_cell::sync::Lazy::new(|| { + let mut map = std::collections::HashMap::new(); + for server_fn in server_fn::inventory::iter:: { + map.insert(server_fn.0.url(), server_fn.clone()); + } + std::sync::Arc::new(std::sync::RwLock::new(map)) +}); #[cfg(any(feature = "ssr", doc))] /// The registry of all Dioxus server functions. pub struct DioxusServerFnRegistry; -#[cfg(any(feature = "ssr"))] +#[cfg(feature = "ssr")] impl server_fn::ServerFunctionRegistry for DioxusServerFnRegistry { type Error = ServerRegistrationFnError; - fn register( + fn register_explicit( + prefix: &'static str, url: &'static str, - server_function: std::sync::Arc, + server_function: ServerFunction, encoding: server_fn::Encoding, ) -> Result<(), Self::Error> { // store it in the hashmap @@ -33,10 +79,7 @@ impl server_fn::ServerFunctionRegistry for DioxusServerFnRe .map_err(|e| ServerRegistrationFnError::Poisoned(e.to_string()))?; let prev = write.insert( url, - ServerFunction { - trait_obj: server_function, - encoding, - }, + ServerFnTraitObj::new(prefix, url, encoding, server_function), ); // if there was already a server function with this key, @@ -53,27 +96,32 @@ impl server_fn::ServerFunctionRegistry for DioxusServerFnRe } } - /// Returns the server function registered at the given URL, or `None` if no function is registered at that URL. - fn get(url: &str) -> Option { - REGISTERED_SERVER_FUNCTIONS - .read() - .ok() - .and_then(|fns| fns.get(url).cloned()) + fn register( + url: &'static str, + server_function: ServerFunction, + encoding: server_fn::Encoding, + ) -> Result<(), Self::Error> { + Self::register_explicit("", url, server_function, encoding) } /// Returns the server function registered at the given URL, or `None` if no function is registered at that URL. - fn get_trait_obj(url: &str) -> Option> { + fn get(url: &str) -> Option> { REGISTERED_SERVER_FUNCTIONS .read() .ok() - .and_then(|fns| fns.get(url).map(|f| f.trait_obj.clone())) + .and_then(|fns| fns.get(url).map(|inner| inner.0.clone())) + } + + /// Returns the server function registered at the given URL, or `None` if no function is registered at that URL. + fn get_trait_obj(url: &str) -> Option> { + Self::get(url) } fn get_encoding(url: &str) -> Option { REGISTERED_SERVER_FUNCTIONS .read() .ok() - .and_then(|fns| fns.get(url).map(|f| f.encoding.clone())) + .and_then(|fns| fns.get(url).map(|f| f.encoding())) } /// Returns a list of all registered server functions. @@ -103,16 +151,16 @@ pub enum ServerRegistrationFnError { /// /// Server functions are created using the `server` macro. /// -/// The function should be registered by calling `ServerFn::register()`. The set of server functions +/// The set of server functions /// can be queried on the server for routing purposes by calling [server_fn::ServerFunctionRegistry::get]. /// /// Technically, the trait is implemented on a type that describes the server function's arguments, not the function itself. -pub trait ServerFn: server_fn::ServerFn { +pub trait DioxusServerFn: server_fn::ServerFn { /// Registers the server function, allowing the client to query it by URL. #[cfg(any(feature = "ssr", doc))] - fn register() -> Result<(), server_fn::ServerFnError> { - Self::register_in::() + fn register_explicit() -> Result<(), server_fn::ServerFnError> { + Self::register_in_explicit::() } } -impl ServerFn for T where T: server_fn::ServerFn {} +impl DioxusServerFn for T where T: server_fn::ServerFn {} From da44b7a3f250b86473aed958a277e4d390467c15 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 19 Jun 2023 16:11:59 -0500 Subject: [PATCH 7/9] fix salvo server function handler example --- packages/fullstack/src/adapters/salvo_adapter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fullstack/src/adapters/salvo_adapter.rs b/packages/fullstack/src/adapters/salvo_adapter.rs index c2968ff75..59b7c36ea 100644 --- a/packages/fullstack/src/adapters/salvo_adapter.rs +++ b/packages/fullstack/src/adapters/salvo_adapter.rs @@ -76,7 +76,7 @@ pub trait DioxusRouterExt { /// use dioxus_fullstack::prelude::*; /// /// struct ServerFunctionHandler { - /// server_fn: ServerFunction, + /// server_fn: server_fn::ServerFnTraitObj, /// } /// /// #[handler] From d93d11262db056572a9010727ecc2851c1463cf1 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Tue, 20 Jun 2023 11:57:24 -0400 Subject: [PATCH 8/9] bump interpreter version --- packages/interpreter/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/interpreter/Cargo.toml b/packages/interpreter/Cargo.toml index b34dad992..07f5cd930 100644 --- a/packages/interpreter/Cargo.toml +++ b/packages/interpreter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dioxus-interpreter-js" -version = "0.3.2" +version = "0.3.3" edition = "2018" authors = ["Jonathan Kelley"] description = "JS Intepreter for Dioxus - a concurrent renderer-agnostic Virtual DOM for interactive user experiences" From a3654fd0b865a7b831c0c870b980960eb563ec70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Esp=C3=ADn?= Date: Tue, 20 Jun 2023 19:13:34 +0200 Subject: [PATCH 9/9] Update use_shared_state.rs --- packages/hooks/src/use_shared_state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hooks/src/use_shared_state.rs b/packages/hooks/src/use_shared_state.rs index eb836a211..3a3a4d639 100644 --- a/packages/hooks/src/use_shared_state.rs +++ b/packages/hooks/src/use_shared_state.rs @@ -71,7 +71,7 @@ impl ProvidedStateInner { /// let current_theme = *theme.read(); /// /// render! { -/// match &*theme.read() { +/// match current_theme { /// Theme::Dark => { /// "Dark mode" /// }