diff --git a/examples/hackernews-axum/Cargo.toml b/examples/hackernews-axum/Cargo.toml index ae080a360..a52c5180d 100644 --- a/examples/hackernews-axum/Cargo.toml +++ b/examples/hackernews-axum/Cargo.toml @@ -12,12 +12,12 @@ console_log = "0.2" console_error_panic_hook = "0.1" futures = "0.3" cfg-if = "1" -leptos = { path = "../../../leptos/leptos", default-features = false, features = [ +leptos = { path = "../../leptos", default-features = false, features = [ "serde", ] } -leptos_axum = { path = "../../../leptos/integrations/axum", optional = true } -leptos_meta = { path = "../../../leptos/meta", default-features = false } -leptos_router = { path = "../../../leptos/router", default-features = false } +leptos_axum = { path = "../../integrations/axum", optional = true } +leptos_meta = { path = "../../meta", default-features = false } +leptos_router = { path = "../../router", default-features = false } log = "0.4" simple_logger = "2" serde = { version = "1", features = ["derive"] } diff --git a/examples/router/Cargo.toml b/examples/router/Cargo.toml index 74bc53184..e46a74784 100644 --- a/examples/router/Cargo.toml +++ b/examples/router/Cargo.toml @@ -11,7 +11,7 @@ leptos_router = { path = "../../router", features=["csr"] } serde = { version = "1", features = ["derive"] } futures = "0.3" console_error_panic_hook = "0.1.7" -leptos_meta = { path = "../../../leptos/meta", default-features = false } +leptos_meta = { path = "../../meta", default-features = false } [dev-dependencies] wasm-bindgen-test = "0.3.0" diff --git a/examples/router/src/lib.rs b/examples/router/src/lib.rs index 89f4eac48..968d7bd08 100644 --- a/examples/router/src/lib.rs +++ b/examples/router/src/lib.rs @@ -115,9 +115,9 @@ pub fn Contact(cx: Scope) -> impl IntoView { view! { cx,
- "Loading..."

}> + "Loading..."

}> {contact_display} -
+
} } diff --git a/examples/todo-app-sqlite-axum/Cargo.toml b/examples/todo-app-sqlite-axum/Cargo.toml index 3f09b98ae..5a86d5d4d 100644 --- a/examples/todo-app-sqlite-axum/Cargo.toml +++ b/examples/todo-app-sqlite-axum/Cargo.toml @@ -12,12 +12,12 @@ console_log = "0.2.0" console_error_panic_hook = "0.1.7" futures = "0.3.25" cfg-if = "1.0.0" -leptos = { path = "../../../leptos/leptos", default-features = false, features = [ +leptos = { path = "../../leptos", default-features = false, features = [ "serde", ] } -leptos_axum = { path = "../../../leptos/integrations/axum", default-features = false, optional = true } -leptos_meta = { path = "../../../leptos/meta", default-features = false } -leptos_router = { path = "../../../leptos/router", default-features = false } +leptos_axum = { path = "../../integrations/axum", default-features = false, optional = true } +leptos_meta = { path = "../../meta", default-features = false } +leptos_router = { path = "../../router", default-features = false } log = "0.4.17" simple_logger = "4.0.0" serde = { version = "1.0.148", features = ["derive"] } diff --git a/examples/todo-app-sqlite/Cargo.toml b/examples/todo-app-sqlite/Cargo.toml index 82955b4dd..af3c9892d 100644 --- a/examples/todo-app-sqlite/Cargo.toml +++ b/examples/todo-app-sqlite/Cargo.toml @@ -16,12 +16,12 @@ console_error_panic_hook = "0.1" serde = { version = "1", features = ["derive"] } futures = "0.3" cfg-if = "1" -leptos = { path = "../../../leptos/leptos", default-features = false, features = [ +leptos = { path = "../../leptos", default-features = false, features = [ "serde", ] } -leptos_actix = { path = "../../../leptos/integrations/actix", optional = true } -leptos_meta = { path = "../../../leptos/meta", default-features = false } -leptos_router = { path = "../../../leptos/router", default-features = false } +leptos_actix = { path = "../../integrations/actix", optional = true } +leptos_meta = { path = "../../meta", default-features = false } +leptos_router = { path = "../../router", default-features = false } log = "0.4" simple_logger = "2" gloo = { git = "https://github.com/rustwasm/gloo" } diff --git a/leptos/src/transition.rs b/leptos/src/transition.rs index f2513346a..9d5fcd46e 100644 --- a/leptos/src/transition.rs +++ b/leptos/src/transition.rs @@ -1,5 +1,5 @@ use cfg_if::cfg_if; -use leptos_dom::{Component, DynChild, Fragment, IntoView}; +use leptos_dom::{Component, DynChild, Fragment, IntoView, View}; use leptos_macro::component; use leptos_reactive::{provide_context, Scope, SignalSetter, SuspenseContext}; use std::{cell::RefCell, rc::Rc}; @@ -75,7 +75,30 @@ where F: Fn() -> E + 'static, E: IntoView, { - let context = SuspenseContext::new(cx); + let prev_children = std::rc::Rc::new(RefCell::new(None::>)); + crate::Suspense( + cx, + crate::SuspenseProps::builder() + .fallback({ + let prev_child = Rc::clone(&prev_children); + move || { + if let Some(prev_children) = &*prev_child.borrow() { + crate::log!("prev_children = {:#?}", prev_children); + prev_children.clone().into_view(cx) + } else { + fallback().into_view(cx) + } + } + }) + .children(Box::new(move |cx| { + let frag = children(cx); + *prev_children.borrow_mut() = Some(frag.nodes.clone()); + frag + })) + .build() + ) + + /* let context = SuspenseContext::new(cx); // provide this SuspenseContext to any resources below it provide_context(cx, context); @@ -103,6 +126,7 @@ where if let Some(pending) = &set_pending { pending.set(true); } + leptos::log!("prev_child = {prev_child:#?}"); prev_child.clone() } else { if let Some(pending) = &set_pending { @@ -150,5 +174,5 @@ where } } }) - }) + }) */ } \ No newline at end of file diff --git a/leptos_dom/src/components/fragment.rs b/leptos_dom/src/components/fragment.rs index bb6db13a4..543fc0994 100644 --- a/leptos_dom/src/components/fragment.rs +++ b/leptos_dom/src/components/fragment.rs @@ -24,7 +24,8 @@ where #[derive(Debug, Clone)] pub struct Fragment { id: HydrationKey, - nodes: Vec, + /// The nodes contained in the fragment. + pub nodes: Vec, } impl FromIterator for Fragment { diff --git a/leptos_dom/src/html/svg.rs b/leptos_dom/src/html/svg.rs index 0f15934ae..76bfa67ca 100644 --- a/leptos_dom/src/html/svg.rs +++ b/leptos_dom/src/html/svg.rs @@ -1,12 +1,15 @@ //! SVG elements. -use super::{ElementDescriptor, HtmlElement, IntoView}; +use super::{ElementDescriptor, HtmlElement}; #[cfg(not(all(target_arch = "wasm32", feature = "web")))] use super::{HydrationKey, HTML_ELEMENT_DEREF_UNIMPLEMENTED_MSG}; use crate::HydrationCtx; use leptos_reactive::Scope; -use std::{borrow::Cow, cell::LazyCell}; +use std::{borrow::Cow}; +#[cfg(all(target_arch = "wasm32", feature = "web"))] use wasm_bindgen::JsCast; +#[cfg(all(target_arch = "wasm32", feature = "web"))] +use std::cell::LazyCell; macro_rules! generate_svg_tags { ( @@ -148,6 +151,7 @@ macro_rules! generate_svg_tags { } #[$meta] + #[allow(non_snake_case)] pub fn [<$tag $(_ $second $(_ $third)?)? $($trailing_)?>](cx: Scope) -> HtmlElement<[<$tag:camel $($second:camel $($third:camel)?)?>]> { HtmlElement::new(cx, [<$tag:camel $($second:camel $($third:camel)?)?>]::default()) } diff --git a/leptos_reactive/src/resource.rs b/leptos_reactive/src/resource.rs index a6c236cee..58d37984c 100644 --- a/leptos_reactive/src/resource.rs +++ b/leptos_reactive/src/resource.rs @@ -116,23 +116,9 @@ where suspense_contexts: Default::default(), }); - cfg_if! { - if #[cfg(any(feature = "csr", feature = "hydrate"))] { - let id = with_runtime(cx.runtime, |runtime| { - runtime.create_serializable_resource(Rc::clone(&r)) - }); - } else { - let id = if use_context::(cx).is_some() { - with_runtime(cx.runtime, |runtime| { - runtime.create_serializable_resource(Rc::clone(&r)) - }) - } else { - with_runtime(cx.runtime, |runtime| { - runtime.create_unserializable_resource(Rc::clone(&r)) - }) - }; - } - } + let id = with_runtime(cx.runtime, |runtime| { + runtime.create_serializable_resource(Rc::clone(&r)) + }); create_isomorphic_effect(cx, { let r = Rc::clone(&r); @@ -281,8 +267,19 @@ where r.resolved.set(true); let res = T::from_json(&data).expect_throw("could not deserialize Resource JSON"); - r.set_value.update(|n| *n = Some(res)); - r.set_loading.update(|n| *n = false); + + // if we're under Suspense, the HTML has already streamed in so we can just set it + // if not under Suspense, there will be a hydration mismatch, so let's wait a tick + if use_context::(cx).is_some() { + r.set_value.update(|n| *n = Some(res)); + r.set_loading.update(|n| *n = false); + } else { + let r = Rc::clone(&r); + spawn_local(async move { + r.set_value.update(|n| *n = Some(res)); + r.set_loading.update(|n| *n = false); + }); + } // for reactivity r.source.subscribe();