mirror of
https://github.com/leptos-rs/leptos
synced 2024-09-20 06:21:57 +00:00
added HydrationCtx
helpers and fixed a couple bugs with the hydration example
This commit is contained in:
parent
416e1a617b
commit
9eadac9f2c
6 changed files with 54 additions and 16 deletions
|
@ -1,3 +1,4 @@
|
|||
use leptos_dom::HydrationCtx;
|
||||
use leptos_dom::{Fragment, IntoView};
|
||||
use leptos_reactive::{provide_context, Scope, SuspenseContext};
|
||||
use typed_builder::TypedBuilder;
|
||||
|
@ -88,10 +89,28 @@ where
|
|||
F: Fn() -> E + 'static,
|
||||
E: IntoView,
|
||||
{
|
||||
use std::cell::RefCell;
|
||||
|
||||
use leptos_dom::DynChild;
|
||||
|
||||
let cached_id = RefCell::new(None);
|
||||
|
||||
DynChild::new(move || {
|
||||
let mut cached_id_borrow = cached_id.borrow_mut();
|
||||
|
||||
let first_run = if cached_id_borrow.is_none() {
|
||||
*cached_id_borrow = Some(HydrationCtx::peak());
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if context.ready() {
|
||||
if let Some(id) = *cached_id_borrow {
|
||||
HydrationCtx::continue_from(id);
|
||||
}
|
||||
|
||||
child(cx).into_view(cx)
|
||||
} else {
|
||||
fallback().into_view(cx)
|
||||
|
@ -124,14 +143,14 @@ where
|
|||
else {
|
||||
let key = cx.current_fragment_key();
|
||||
cx.register_suspense(context, &key, move || {
|
||||
orig_child(cx).into_view(cx).render_to_string(cx).to_string()
|
||||
orig_child(cx)
|
||||
.into_view(cx)
|
||||
.render_to_string(cx)
|
||||
.to_string()
|
||||
});
|
||||
|
||||
// return the fallback for now, wrapped in fragment identifer
|
||||
div(cx)
|
||||
.id(key.to_string())
|
||||
.child(fallback)
|
||||
.into_view(cx)
|
||||
div(cx).id(key.to_string()).child(fallback).into_view(cx)
|
||||
}
|
||||
};
|
||||
initial
|
||||
|
|
|
@ -11,6 +11,7 @@ leptos = { path = "../../../leptos", default-features = false }
|
|||
actix-web = { version = "4", optional = true }
|
||||
actix-files = { version = "0.6", optional = true }
|
||||
wasm-bindgen = { version = "0.2", optional = true}
|
||||
gloo = { version = "0.8", optional = true }
|
||||
console_error_panic_hook = "0.1.7"
|
||||
cfg-if = "1.0.0"
|
||||
gloo-timers = { version = "0.2", features = ["futures"] }
|
||||
|
@ -19,6 +20,6 @@ futures = "0.3"
|
|||
[features]
|
||||
default = ["ssr"]
|
||||
ssr = ["leptos/ssr", "dep:actix-files", "dep:actix-web"]
|
||||
hydrate = ["leptos/hydrate", "dep:wasm-bindgen"]
|
||||
hydrate = ["leptos/hydrate", "dep:wasm-bindgen", "dep:gloo"]
|
||||
|
||||
[workspace]
|
||||
|
|
|
@ -11,15 +11,14 @@ pub fn App(cx: Scope) -> impl IntoView {
|
|||
if cfg!(feature = "ssr") {
|
||||
let (tx, rx) = futures::channel::oneshot::channel();
|
||||
spawn_local(async {
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
std::thread::sleep(std::time::Duration::from_secs(10));
|
||||
tx.send(());
|
||||
});
|
||||
rx.await;
|
||||
} else {
|
||||
|
||||
}
|
||||
()
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
view! { cx,
|
||||
|
@ -35,11 +34,13 @@ pub fn App(cx: Scope) -> impl IntoView {
|
|||
}
|
||||
|
||||
#[component]
|
||||
pub fn ComponentA(cx: Scope, children: Box<dyn Fn() -> Vec<View>>) -> impl IntoView {
|
||||
pub fn ComponentA(
|
||||
cx: Scope,
|
||||
children: Box<dyn Fn() -> Vec<View>>,
|
||||
) -> impl IntoView {
|
||||
let (value, set_value) = create_signal(cx, "Hello?".to_string());
|
||||
let (counter, set_counter) = create_signal(cx, 0);
|
||||
|
||||
|
||||
// Test to make sure hydration isn't broken by
|
||||
// something like this
|
||||
let _ = [div(cx)].into_view(cx);
|
||||
|
@ -66,6 +67,8 @@ use wasm_bindgen::prelude::wasm_bindgen;
|
|||
pub fn hydrate() {
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
gloo::console::debug!("starting WASM");
|
||||
|
||||
leptos::mount_to_body(move |cx| {
|
||||
view! { cx, <App/> }
|
||||
});
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use actix_files::Files;
|
||||
use actix_web::*;
|
||||
use futures::StreamExt;
|
||||
use hydration_test::*;
|
||||
use leptos::*;
|
||||
use futures::StreamExt;
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
|
@ -21,17 +21,19 @@ async fn main() -> std::io::Result<()> {
|
|||
<link rel="modulepreload" href="{pkg_path}.js">
|
||||
<link rel="preload" href="{pkg_path}_bg.wasm" as="fetch" type="application/wasm" crossorigin="">
|
||||
<script type="module">import init, {{ hydrate }} from '{pkg_path}.js'; init('{pkg_path}_bg.wasm').then(hydrate);</script>
|
||||
"#
|
||||
</head>
|
||||
<body>"#
|
||||
);
|
||||
|
||||
let tail = "</body></html>";
|
||||
|
||||
HttpResponse::Ok().content_type("text/html").streaming(
|
||||
futures::stream::once(async move { head.clone() })
|
||||
.chain(render_to_stream(
|
||||
.chain(render_to_stream(
|
||||
|cx| view! { cx, <App/> }.into_view(cx),
|
||||
))
|
||||
.chain(futures::stream::once(async { tail.to_string() }))
|
||||
.inspect(|html| println!("{html}"))
|
||||
.map(|html| Ok(web::Bytes::from(html)) as Result<web::Bytes>),
|
||||
)})
|
||||
))
|
||||
|
|
|
@ -20,9 +20,15 @@ static mut IS_HYDRATING: LazyCell<bool> = LazyCell::new(|| {
|
|||
#[thread_local]
|
||||
static mut ID: usize = 0;
|
||||
|
||||
pub(crate) struct HydrationCtx;
|
||||
/// Control and utility methods for hydration.
|
||||
pub struct HydrationCtx;
|
||||
|
||||
impl HydrationCtx {
|
||||
/// Get the next `id` without incrementing it.
|
||||
pub fn peak() -> usize {
|
||||
unsafe { ID }
|
||||
}
|
||||
|
||||
pub(crate) fn id() -> usize {
|
||||
unsafe {
|
||||
let id = ID;
|
||||
|
@ -44,6 +50,12 @@ impl HydrationCtx {
|
|||
unsafe { ID = 0 };
|
||||
}
|
||||
|
||||
/// Resums hydration from the provided `id`. Usefull for
|
||||
/// `Suspense` and other fancy things.
|
||||
pub fn continue_from(id: usize) {
|
||||
unsafe { ID = id }
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
|
||||
pub(crate) fn set_id(cx: Scope) {
|
||||
/* let new_id = if let Some(id) = cx.get_hydration_key() {
|
||||
|
|
|
@ -19,12 +19,13 @@ mod node_ref;
|
|||
mod ssr;
|
||||
mod transparent;
|
||||
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
pub use components::*;
|
||||
pub use events::typed as ev;
|
||||
pub use helpers::*;
|
||||
pub use html::*;
|
||||
use hydration::HydrationCtx;
|
||||
pub use hydration::HydrationCtx;
|
||||
pub use js_sys;
|
||||
use leptos_reactive::Scope;
|
||||
pub use logging::*;
|
||||
|
|
Loading…
Reference in a new issue