diff --git a/examples/lazy_routes/Cargo.toml b/examples/lazy_routes/Cargo.toml index c42445681b..962e353708 100644 --- a/examples/lazy_routes/Cargo.toml +++ b/examples/lazy_routes/Cargo.toml @@ -10,7 +10,7 @@ crate-type = ["cdylib", "rlib"] axum = { version = "0.8.1", optional = true } console_error_panic_hook = "0.1.7" console_log = "1.0" -leptos = { path = "../../leptos", features = ["tracing"] } +leptos = { path = "../../leptos", features = ["tracing", "lazy"] } leptos_meta = { path = "../../meta" } leptos_axum = { path = "../../integrations/axum", optional = true } leptos_router = { path = "../../router" } diff --git a/leptos/Cargo.toml b/leptos/Cargo.toml index b5a3cc4a0c..0b8423cce6 100644 --- a/leptos/Cargo.toml +++ b/leptos/Cargo.toml @@ -122,6 +122,7 @@ subsecond = [ "web-sys/WebSocket", "web-sys/Window", ] +lazy = ["tachys/lazy"] [dev-dependencies] tokio = { features = [ diff --git a/tachys/Cargo.toml b/tachys/Cargo.toml index aa75106e38..921055db4c 100644 --- a/tachys/Cargo.toml +++ b/tachys/Cargo.toml @@ -179,6 +179,7 @@ default = ["testing"] delegation = [] # enables event delegation error-hook = [] hydrate = [] +lazy = [] islands = ["dep:serde", "dep:serde_json"] ssr = [] oco = ["dep:oco_ref"] diff --git a/tachys/src/view/any_view.rs b/tachys/src/view/any_view.rs index 449937447e..6c11f20c6b 100644 --- a/tachys/src/view/any_view.rs +++ b/tachys/src/view/any_view.rs @@ -17,7 +17,7 @@ use crate::{ }; use futures::future::{join, join_all}; use std::{any::TypeId, fmt::Debug}; -#[cfg(any(feature = "ssr", feature = "hydrate"))] +#[cfg(any(feature = "ssr", all(feature = "hydrate", feature = "lazy")))] use std::{future::Future, pin::Pin}; /// A type-erased view. This can be used if control flow requires that multiple different types of @@ -67,10 +67,10 @@ pub struct AnyView { resolve: fn(Erased) -> Pin + Send>>, #[cfg(feature = "ssr")] dry_resolve: fn(&mut Erased), - #[cfg(feature = "hydrate")] + #[cfg(all(feature = "hydrate", not(feature = "lazy")))] #[allow(clippy::type_complexity)] hydrate_from_server: fn(Erased, &Cursor, &PositionState) -> AnyViewState, - #[cfg(feature = "hydrate")] + #[cfg(all(feature = "hydrate", feature = "lazy"))] #[allow(clippy::type_complexity)] hydrate_async: fn( Erased, @@ -291,7 +291,7 @@ where } } - #[cfg(feature = "hydrate")] + #[cfg(all(feature = "hydrate", not(feature = "lazy")))] fn hydrate_from_server( value: Erased, cursor: &Cursor, @@ -313,7 +313,7 @@ where } } - #[cfg(feature = "hydrate")] + #[cfg(all(feature = "hydrate", feature = "lazy"))] fn hydrate_async( value: Erased, cursor: &Cursor, @@ -367,9 +367,9 @@ where to_html_async: to_html_async::, #[cfg(feature = "ssr")] to_html_async_ooo: to_html_async_ooo::, - #[cfg(feature = "hydrate")] + #[cfg(all(feature = "hydrate", not(feature = "lazy")))] hydrate_from_server: hydrate_from_server::, - #[cfg(feature = "hydrate")] + #[cfg(all(feature = "hydrate", feature = "lazy"))] hydrate_async: hydrate_async::, value: Erased::new(value), } @@ -572,7 +572,7 @@ impl RenderHtml for AnyView { cursor: &Cursor, position: &PositionState, ) -> Self::State { - #[cfg(feature = "hydrate")] + #[cfg(all(feature = "hydrate", not(feature = "lazy")))] { if FROM_SERVER { if cfg!(feature = "mark_branches") { @@ -591,6 +591,14 @@ impl RenderHtml for AnyView { ); } } + #[cfg(all(feature = "hydrate", feature = "lazy"))] + { + use futures::FutureExt; + + (self.hydrate_async)(self.value, cursor, position) + .now_or_never() + .unwrap() + } #[cfg(not(feature = "hydrate"))] { _ = cursor; @@ -607,11 +615,12 @@ impl RenderHtml for AnyView { cursor: &Cursor, position: &PositionState, ) -> Self::State { - #[cfg(feature = "hydrate")] + #[cfg(all(feature = "hydrate", feature = "lazy"))] { if cfg!(feature = "mark_branches") { cursor.advance_to_placeholder(position); } + #[cfg(all(feature = "hydrate", feature = "lazy"))] let state = (self.hydrate_async)(self.value, cursor, position).await; if cfg!(feature = "mark_branches") { @@ -619,6 +628,15 @@ impl RenderHtml for AnyView { } state } + #[cfg(all(feature = "hydrate", not(feature = "lazy")))] + { + _ = cursor; + _ = position; + panic!( + "the `lazy` feature on `tachys` must be activated to use lazy \ + hydration" + ); + } #[cfg(not(feature = "hydrate"))] { _ = cursor;