diff --git a/leptos_core/src/suspense.rs b/leptos_core/src/suspense.rs index 65b1891..2907910 100644 --- a/leptos_core/src/suspense.rs +++ b/leptos_core/src/suspense.rs @@ -93,19 +93,16 @@ where use leptos_dom::DynChild; Component::new("Suspense", move |cx| { - let cached_id = HydrationCtx::peek(); + let mut cached_id = HydrationCtx::peek(); + let mut id_to_replace = cached_id.clone(); + id_to_replace.offset += 0; - DynChild::new(move || { - let mut id_to_replace = cached_id.clone(); - id_to_replace.offset += 2; + if context.ready() { HydrationCtx::continue_from(id_to_replace); - - if context.ready() { - child(cx).into_view(cx) - } else { - fallback().into_view(cx) - } - }) + child(cx).into_view(cx) + } else { + fallback().into_view(cx) + } }) } @@ -125,32 +122,37 @@ where let orig_child = Rc::clone(&orig_child); Component::new("Suspense", move |cx| { - DynChild::new(move || { - let current_id = HydrationCtx::peek(); + let current_id = HydrationCtx::peek(); - // run the child; we'll probably throw this away, but it will register resource reads - let child = orig_child(cx).into_view(cx); + // run the child; we'll probably throw this away, but it will register resource reads + let child = orig_child(cx).into_view(cx); - let initial = { - // no resources were read under this, so just return the child - if context.pending_resources.get() == 0 { - child.clone() - } - // show the fallback, but also prepare to stream HTML - else { - let orig_child = Rc::clone(&orig_child); - cx.register_suspense(context, ¤t_id.to_string(), move || { + let initial = { + // no resources were read under this, so just return the child + if context.pending_resources.get() == 0 { + child.clone() + } + // show the fallback, but also prepare to stream HTML + else { + let orig_child = Rc::clone(&orig_child); + cx.register_suspense(context, ¤t_id.to_string(), { + let current_id = current_id.clone(); + move || { + HydrationCtx::continue_from(current_id); orig_child(cx) .into_view(cx) .render_to_string(cx) .to_string() - }); - - // return the fallback for now, wrapped in fragment identifer - fallback().into_view(cx) - } - }; - initial - }) + } + }); + + // return the fallback for now, wrapped in fragment identifer + fallback().into_view(cx) + } + }; + + HydrationCtx::continue_from(current_id); + + initial }) } diff --git a/leptos_reactive/src/hydration.rs b/leptos_reactive/src/hydration.rs index 93c70dc..3777d5b 100644 --- a/leptos_reactive/src/hydration.rs +++ b/leptos_reactive/src/hydration.rs @@ -4,8 +4,8 @@ use std::{ future::Future, pin::Pin, }; +use cfg_if::cfg_if; -#[derive(Default)] pub struct SharedContext { pub events: Vec<()>, pub pending_resources: HashSet, @@ -29,6 +29,43 @@ impl PartialEq for SharedContext { impl Eq for SharedContext {} -impl SharedContext { +impl Default for SharedContext { -} \ No newline at end of file + fn default() -> Self { + cfg_if! { + if #[cfg(feature = "hydrate")] { + let pending_resources = js_sys::Reflect::get( + &web_sys::window().unwrap(), + &wasm_bindgen::JsValue::from_str("__LEPTOS_PENDING_RESOURCES"), + ); + let pending_resources: HashSet = pending_resources + .map_err(|_| ()) + .and_then(|pr| serde_wasm_bindgen::from_value(pr).map_err(|_| ())) + .unwrap_or_default(); + + let resolved_resources = js_sys::Reflect::get( + &web_sys::window().unwrap(), + &wasm_bindgen::JsValue::from_str("__LEPTOS_RESOLVED_RESOURCES"), + ) + .unwrap_or(wasm_bindgen::JsValue::NULL); + + let resolved_resources = + serde_wasm_bindgen::from_value(resolved_resources).unwrap_or_default(); + + Self { + events: Default::default(), + pending_resources, + resolved_resources, + pending_fragments: Default::default(), + } + } else { + Self { + events: Default::default(), + pending_resources: Default::default(), + resolved_resources: Default::default(), + pending_fragments: Default::default(), + } + } + } + } +}