Skip to content

Commit

Permalink
fix: treat Suspense as containing a Set of resources, not a counter (…
Browse files Browse the repository at this point in the history
…closes `Suspense` only working with a single `Resource` (closes #1805, closes #1905) (#1985)
  • Loading branch information
gbj authored Nov 4, 2023
1 parent 7aced17 commit b1e8105
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 43 deletions.
2 changes: 1 addition & 1 deletion leptos/src/suspense_component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ where

{
// no resources were read under this, so just return the child
if context.pending_resources.get() == 0 {
if context.none_pending() {
with_owner(owner, move || {
//HydrationCtx::continue_from(current_id);
DynChild::new(move || children_rendered.clone())
Expand Down
3 changes: 1 addition & 2 deletions leptos/src/transition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,9 @@ pub fn Transition(
}
child_runs.set(child_runs.get() + 1);

let pending = suspense_context.pending_resources;
create_isomorphic_effect(move |_| {
if let Some(set_pending) = set_pending {
set_pending.set(pending.get() > 0)
set_pending.set(!suspense_context.none_pending())
}
});
frag
Expand Down
8 changes: 4 additions & 4 deletions leptos_reactive/src/hydration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use crate::Owner;
use crate::{
runtime::PinnedFuture, suspense::StreamChunk, with_runtime, ResourceId,
SuspenseContext,
SignalGet, SuspenseContext,
};
use futures::stream::FuturesUnordered;
#[cfg(feature = "experimental-islands")]
Expand Down Expand Up @@ -84,9 +84,9 @@ impl SharedContext {
let pending = context
.pending_serializable_resources
.read_only()
.try_with(|n| *n)
.unwrap_or(0);
if pending == 0 {
.try_get()
.unwrap_or_default();
if pending.is_empty() {
_ = tx1.unbounded_send(());
_ = tx2.unbounded_send(());
_ = tx3.unbounded_send(());
Expand Down
59 changes: 39 additions & 20 deletions leptos_reactive/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ where
// client
create_render_effect({
let r = Rc::clone(&r);
move |_| r.load(false)
move |_| r.load(false, id)
});

Resource {
Expand All @@ -402,10 +402,9 @@ where
S: PartialEq + Clone + 'static,
T: 'static,
{
_ = id;
SUPPRESS_RESOURCE_LOAD.with(|s| {
if !s.get() {
r.load(false)
r.load(false, id)
}
});
}
Expand Down Expand Up @@ -483,7 +482,7 @@ where
} else {
// Server didn't mark the resource as pending, so load it on the
// client
r.load(false);
r.load(false, id);
}
})
}
Expand Down Expand Up @@ -528,7 +527,7 @@ where
let location = std::panic::Location::caller();
with_runtime(|runtime| {
runtime.resource(self.id, |resource: &ResourceState<S, T>| {
resource.with(f, location)
resource.with(f, location, self.id)
})
})
.ok()
Expand Down Expand Up @@ -598,7 +597,7 @@ where
runtime.resource(self.id, |resource: &ResourceState<S, T>| {
#[cfg(debug_assertions)]
let prev = SpecialNonReactiveZone::enter();
resource.refetch();
resource.refetch(self.id);
#[cfg(debug_assertions)]
{
SpecialNonReactiveZone::exit(prev);
Expand Down Expand Up @@ -708,9 +707,10 @@ impl<S, T> SignalUpdate for Resource<S, T> {
for suspense_context in
resource.suspense_contexts.borrow().iter()
{
suspense_context.decrement(
suspense_context.decrement_for_resource(
resource.serializable
!= ResourceSerialization::Local,
self.id,
);
}
}
Expand Down Expand Up @@ -748,7 +748,7 @@ where
let location = std::panic::Location::caller();
match with_runtime(|runtime| {
runtime.resource(self.id, |resource: &ResourceState<S, T>| {
resource.with_maybe(f, location)
resource.with_maybe(f, location, self.id)
})
})
.expect("runtime to be alive")
Expand Down Expand Up @@ -783,7 +783,7 @@ where
let location = std::panic::Location::caller();
with_runtime(|runtime| {
runtime.resource(self.id, |resource: &ResourceState<S, T>| {
resource.with_maybe(f, location)
resource.with_maybe(f, location, self.id)
})
})
.ok()
Expand Down Expand Up @@ -835,7 +835,7 @@ where
let location = std::panic::Location::caller();
with_runtime(|runtime| {
runtime.resource(self.id, |resource: &ResourceState<S, T>| {
resource.read(location)
resource.read(location, self.id)
})
})
.ok()
Expand Down Expand Up @@ -1155,18 +1155,23 @@ where
T: 'static,
{
#[track_caller]
pub fn read(&self, location: &'static Location<'static>) -> Option<T>
pub fn read(
&self,
location: &'static Location<'static>,
id: ResourceId,
) -> Option<T>
where
T: Clone,
{
self.with(T::clone, location)
self.with(T::clone, location, id)
}

#[track_caller]
pub fn with<U>(
&self,
f: impl FnOnce(&T) -> U,
location: &'static Location<'static>,
id: ResourceId,
) -> Option<U> {
let global_suspense_cx = use_context::<GlobalSuspenseContext>();
let suspense_cx = use_context::<SuspenseContext>();
Expand All @@ -1177,14 +1182,22 @@ where
.ok()?
.flatten();

self.handle_result(location, global_suspense_cx, suspense_cx, v, false)
self.handle_result(
location,
global_suspense_cx,
suspense_cx,
v,
false,
id,
)
}

#[track_caller]
pub fn with_maybe<U>(
&self,
f: impl FnOnce(&Option<T>) -> U,
location: &'static Location<'static>,
id: ResourceId,
) -> Option<U> {
let global_suspense_cx = use_context::<GlobalSuspenseContext>();
let suspense_cx = use_context::<SuspenseContext>();
Expand All @@ -1197,6 +1210,7 @@ where
suspense_cx,
Some(v),
!was_loaded,
id,
)
}

Expand All @@ -1207,6 +1221,7 @@ where
suspense_cx: Option<SuspenseContext>,
v: Option<U>,
force_suspend: bool,
id: ResourceId,
) -> Option<U> {
let suspense_contexts = self.suspense_contexts.clone();
let has_value = v.is_some();
Expand Down Expand Up @@ -1276,8 +1291,9 @@ where
// because the context has been tracked here
// on the first read, resource is already loading without having incremented
if !has_value || force_suspend {
s.increment(
s.increment_for_resource(
serializable != ResourceSerialization::Local,
id,
);
if serializable == ResourceSerialization::Blocking {
s.should_block.set_value(true);
Expand All @@ -1295,9 +1311,10 @@ where
contexts.insert(*s);

if !has_value || force_suspend {
s.increment(
s.increment_for_resource(
serializable
!= ResourceSerialization::Local,
id,
);
}
}
Expand All @@ -1314,15 +1331,15 @@ where
any(debug_assertions, feature = "ssr"),
instrument(level = "trace", skip_all,)
)]
pub fn refetch(&self) {
self.load(true);
pub fn refetch(&self, id: ResourceId) {
self.load(true, id);
}

#[cfg_attr(
any(debug_assertions, feature = "ssr"),
instrument(level = "trace", skip_all,)
)]
fn load(&self, refetching: bool) {
fn load(&self, refetching: bool, id: ResourceId) {
// doesn't refetch if already refetching
if refetching && self.scheduled.get() {
return;
Expand Down Expand Up @@ -1359,8 +1376,9 @@ where
let suspense_contexts = self.suspense_contexts.clone();

for suspense_context in suspense_contexts.borrow().iter() {
suspense_context.increment(
suspense_context.increment_for_resource(
self.serializable != ResourceSerialization::Local,
id,
);
if self.serializable == ResourceSerialization::Blocking {
suspense_context.should_block.set_value(true);
Expand All @@ -1384,8 +1402,9 @@ where
}

for suspense_context in suspense_contexts.borrow().iter() {
suspense_context.decrement(
suspense_context.decrement_for_resource(
serializable != ResourceSerialization::Local,
id,
);
}
}
Expand Down
Loading

0 comments on commit b1e8105

Please sign in to comment.