Compare commits

...

3 Commits
v0.5.7 ... keys

Author SHA1 Message Date
Greg Johnston
2aa14e5e65 differentiate suspense/errorboundary 2023-07-15 16:35:08 -04:00
Greg Johnston
40f6ed9252 make component key paths independent 2023-07-15 12:59:12 -04:00
Greg Johnston
9d9ed45565 make hydration keys !Copy 2023-07-15 10:47:27 -04:00
7 changed files with 35 additions and 28 deletions

View File

@@ -58,14 +58,13 @@ where
F: Fn(Scope, RwSignal<Errors>) -> IV + 'static,
IV: IntoView,
{
let before_children = HydrationCtx::next_component();
let before_children = HydrationCtx::next_component("e");
let errors: RwSignal<Errors> = create_rw_signal(cx, Errors::default());
provide_context(cx, errors);
// Run children so that they render and execute resources
_ = HydrationCtx::next_component();
let children = children(cx);
HydrationCtx::continue_from(before_children);

View File

@@ -69,11 +69,13 @@ where
// provide this SuspenseContext to any resources below it
provide_context(cx, context);
let current_id = HydrationCtx::next_component();
let before = HydrationCtx::peek();
let current_id = HydrationCtx::next_component("s");
leptos::log!("<Suspense/> next_component {current_id}");
let child = DynChild::new({
#[cfg(not(any(feature = "csr", feature = "hydrate")))]
let current_id = current_id;
let current_id = current_id.clone();
let children = Rc::new(orig_children(cx).into_view(cx));
#[cfg(not(any(feature = "csr", feature = "hydrate")))]
@@ -97,7 +99,7 @@ where
{
// no resources were read under this, so just return the child
if context.pending_resources.get() == 0 {
HydrationCtx::continue_from(current_id);
HydrationCtx::continue_from(current_id.clone());
DynChild::new({
let children = Rc::clone(&children);
move || (*children).clone()
@@ -106,7 +108,7 @@ where
}
// show the fallback, but also prepare to stream HTML
else {
HydrationCtx::continue_from(current_id);
HydrationCtx::continue_from(current_id.clone());
cx.register_suspense(
context,
@@ -114,8 +116,11 @@ where
// out-of-order streaming
{
let orig_children = Rc::clone(&orig_children);
let current_id = current_id.clone();
move || {
HydrationCtx::continue_from(current_id);
HydrationCtx::continue_from(
current_id.clone(),
);
DynChild::new({
let orig_children =
orig_children(cx).into_view(cx);
@@ -129,8 +134,11 @@ where
// in-order streaming
{
let orig_children = Rc::clone(&orig_children);
let current_id = current_id.clone();
move || {
HydrationCtx::continue_from(current_id);
HydrationCtx::continue_from(
current_id.clone(),
);
DynChild::new({
let orig_children =
orig_children(cx).into_view(cx);
@@ -155,8 +163,8 @@ where
_ => unreachable!(),
};
HydrationCtx::continue_from(current_id);
HydrationCtx::next_component();
HydrationCtx::continue_from(before.clone());
_ = HydrationCtx::id();
leptos_dom::View::Suspense(current_id, core_component)
}

View File

@@ -445,7 +445,7 @@ impl<El: ElementDescriptor + 'static> HtmlElement<El> {
element: AnyElement {
name: element.name(),
is_void: element.is_void(),
id: *element.hydration_id()
id: element.hydration_id().clone()
},
#[cfg(debug_assertions)]
view_marker
@@ -1070,7 +1070,7 @@ impl<El: ElementDescriptor> IntoView for HtmlElement<El> {
..
} = self;
let id = *element.hydration_id();
let id = element.hydration_id().clone();
let mut element = Element::new(element);
let children = children;
@@ -1114,7 +1114,7 @@ pub fn custom<El: ElementDescriptor>(cx: Scope, el: El) -> HtmlElement<Custom> {
#[cfg(all(target_arch = "wasm32", feature = "web"))]
element: el.as_ref().clone(),
#[cfg(not(all(target_arch = "wasm32", feature = "web")))]
id: *el.hydration_id(),
id: el.hydration_id().clone(),
},
)
}

View File

@@ -50,13 +50,13 @@ cfg_if! {
static IS_HYDRATING: RefCell<LazyCell<bool>> = RefCell::new(LazyCell::new(|| {
#[cfg(debug_assertions)]
return crate::document().get_element_by_id("_0-1").is_some()
|| crate::document().get_element_by_id("_0-1o").is_some()
|| HYDRATION_COMMENTS.with(|comments| comments.get("_0-1o").is_some());
return crate::document().get_element_by_id("_-1").is_some()
|| crate::document().get_element_by_id("_-1o").is_some()
|| HYDRATION_COMMENTS.with(|comments| comments.get("_-1o").is_some());
#[cfg(not(debug_assertions))]
return crate::document().get_element_by_id("_0-1").is_some()
|| HYDRATION_COMMENTS.with(|comments| comments.get("_0-1").is_some());
return crate::document().get_element_by_id("_-1").is_some()
|| HYDRATION_COMMENTS.with(|comments| comments.get("_-1").is_some());
}));
}
@@ -67,12 +67,12 @@ cfg_if! {
}
/// A stable identifier within the server-rendering or hydration process.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
pub struct HydrationKey {
/// ID of the current key.
pub id: usize,
/// ID of the current fragment.
pub fragment: usize,
pub fragment: String,
}
impl Display for HydrationKey {
@@ -89,7 +89,7 @@ pub struct HydrationCtx;
impl HydrationCtx {
/// Get the next `id` without incrementing it.
pub fn peek() -> HydrationKey {
ID.with(|id| *id.borrow())
ID.with(|id| id.borrow().clone())
}
/// Increments the current hydration `id` and returns it
@@ -97,17 +97,17 @@ impl HydrationCtx {
ID.with(|id| {
let mut id = id.borrow_mut();
id.id = id.id.wrapping_add(1);
*id
id.clone()
})
}
/// Resets the hydration `id` for the next component, and returns it
pub fn next_component() -> HydrationKey {
pub fn next_component(tag: &'static str) -> HydrationKey {
ID.with(|id| {
let mut id = id.borrow_mut();
id.fragment = id.fragment.wrapping_add(1);
id.fragment = format!("{}-{}{}", id.fragment, id.id, tag);
id.id = 0;
*id
id.clone()
})
}

View File

@@ -378,7 +378,7 @@ impl Element {
is_void: el.is_void(),
attrs: Default::default(),
children: Default::default(),
id: *el.hydration_id(),
id: el.hydration_id().clone(),
#[cfg(debug_assertions)]
view_marker: None
}

View File

@@ -453,7 +453,7 @@ impl View {
View::CoreComponent(node) => {
let (id, name, wrap, content) = match node {
CoreComponent::Unit(u) => (
u.id,
u.id.clone(),
"",
false,
Box::new(move || {

View File

@@ -381,7 +381,7 @@ impl View {
View::CoreComponent(node) => {
let (id, name, wrap, content) = match node {
CoreComponent::Unit(u) => (
u.id,
u.id.clone(),
"",
false,
Box::new(move |chunks: &mut VecDeque<StreamChunk>| {