diff --git a/leptos_server/src/local_resource.rs b/leptos_server/src/local_resource.rs index 9519571c7f..36396a0cc3 100644 --- a/leptos_server/src/local_resource.rs +++ b/leptos_server/src/local_resource.rs @@ -8,8 +8,11 @@ use reactive_graph::{ ToAnySource, ToAnySubscriber, }, owner::use_context, - signal::guards::{AsyncPlain, ReadGuard}, - traits::{DefinedAt, IsDisposed, ReadUntracked}, + signal::{ + guards::{AsyncPlain, ReadGuard}, + ArcRwSignal, RwSignal, + }, + traits::{DefinedAt, IsDisposed, ReadUntracked, Track, Update, Write}, }; use send_wrapper::SendWrapper; use std::{ @@ -20,6 +23,7 @@ use std::{ /// A reference-counted resource that only loads its data locally on the client. pub struct ArcLocalResource { data: ArcAsyncDerived>, + refetch: ArcRwSignal, #[cfg(any(debug_assertions, leptos_debuginfo))] defined_at: &'static Location<'static>, } @@ -28,6 +32,7 @@ impl Clone for ArcLocalResource { fn clone(&self) -> Self { Self { data: self.data.clone(), + refetch: self.refetch.clone(), #[cfg(any(debug_assertions, leptos_debuginfo))] defined_at: self.defined_at, } @@ -65,15 +70,27 @@ impl ArcLocalResource { } }; let fetcher = SendWrapper::new(fetcher); - Self { - data: ArcAsyncDerived::new(move || { + let refetch = ArcRwSignal::new(0); + let data = { + let refetch = refetch.clone(); + ArcAsyncDerived::new(move || { + refetch.track(); let fut = fetcher(); SendWrapper::new(async move { SendWrapper::new(fut.await) }) - }), + }) + }; + Self { + data, + refetch, #[cfg(any(debug_assertions, leptos_debuginfo))] defined_at: Location::caller(), } } + + /// Re-runs the async function. + pub fn refetch(&self) { + *self.refetch.write() += 1; + } } impl IntoFuture for ArcLocalResource @@ -200,6 +217,7 @@ impl Subscriber for ArcLocalResource { /// A resource that only loads its data locally on the client. pub struct LocalResource { data: AsyncDerived>, + refetch: RwSignal, #[cfg(any(debug_assertions, leptos_debuginfo))] defined_at: &'static Location<'static>, } @@ -242,6 +260,7 @@ impl LocalResource { } } }; + let refetch = RwSignal::new(0); Self { data: if cfg!(feature = "ssr") { @@ -249,14 +268,21 @@ impl LocalResource { } else { let fetcher = SendWrapper::new(fetcher); AsyncDerived::new(move || { + refetch.track(); let fut = fetcher(); SendWrapper::new(async move { SendWrapper::new(fut.await) }) }) }, + refetch, #[cfg(any(debug_assertions, leptos_debuginfo))] defined_at: Location::caller(), } } + + /// Re-runs the async function. + pub fn refetch(&self) { + self.refetch.try_update(|n| *n += 1); + } } impl IntoFuture for LocalResource @@ -398,6 +424,7 @@ impl From> for LocalResource { fn from(arc: ArcLocalResource) -> Self { Self { data: arc.data.into(), + refetch: arc.refetch.into(), #[cfg(any(debug_assertions, leptos_debuginfo))] defined_at: arc.defined_at, } @@ -408,6 +435,7 @@ impl From> for ArcLocalResource { fn from(local: LocalResource) -> Self { Self { data: local.data.into(), + refetch: local.refetch.into(), #[cfg(any(debug_assertions, leptos_debuginfo))] defined_at: local.defined_at, }