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: 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. 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/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: 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; } 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(), diff --git a/packages/fullstack/Cargo.toml b/packages/fullstack/Cargo.toml index b9b8628b3..89ce8f6ae 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/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..59b7c36ea 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 { @@ -77,7 +76,7 @@ pub trait DioxusRouterExt { /// use dioxus_fullstack::prelude::*; /// /// struct ServerFunctionHandler { - /// server_fn: ServerFunction, + /// server_fn: server_fn::ServerFnTraitObj, /// } /// /// #[handler] @@ -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 269823773..50ae46642 100644 --- a/packages/fullstack/src/lib.rs +++ b/packages/fullstack/src/lib.rs @@ -36,7 +36,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 21779d7d8..231285149 100644 --- a/packages/fullstack/src/server_fn.rs +++ b/packages/fullstack/src/server_fn.rs @@ -1,18 +1,63 @@ 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. @@ -22,9 +67,10 @@ pub struct DioxusServerFnRegistry; 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 {} 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" /// } 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"