Skip to content

Commit

Permalink
feat: add [Arc]LocalResource::refetch method (#3394)
Browse files Browse the repository at this point in the history
  • Loading branch information
linw1995 authored Jan 10, 2025
1 parent 7d9cd43 commit eeb01e2
Showing 1 changed file with 33 additions and 5 deletions.
38 changes: 33 additions & 5 deletions leptos_server/src/local_resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand All @@ -20,6 +23,7 @@ use std::{
/// A reference-counted resource that only loads its data locally on the client.
pub struct ArcLocalResource<T> {
data: ArcAsyncDerived<SendWrapper<T>>,
refetch: ArcRwSignal<usize>,
#[cfg(any(debug_assertions, leptos_debuginfo))]
defined_at: &'static Location<'static>,
}
Expand All @@ -28,6 +32,7 @@ impl<T> Clone for ArcLocalResource<T> {
fn clone(&self) -> Self {
Self {
data: self.data.clone(),
refetch: self.refetch.clone(),
#[cfg(any(debug_assertions, leptos_debuginfo))]
defined_at: self.defined_at,
}
Expand Down Expand Up @@ -65,15 +70,27 @@ impl<T> ArcLocalResource<T> {
}
};
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<T> IntoFuture for ArcLocalResource<T>
Expand Down Expand Up @@ -200,6 +217,7 @@ impl<T> Subscriber for ArcLocalResource<T> {
/// A resource that only loads its data locally on the client.
pub struct LocalResource<T> {
data: AsyncDerived<SendWrapper<T>>,
refetch: RwSignal<usize>,
#[cfg(any(debug_assertions, leptos_debuginfo))]
defined_at: &'static Location<'static>,
}
Expand Down Expand Up @@ -242,21 +260,29 @@ impl<T> LocalResource<T> {
}
}
};
let refetch = RwSignal::new(0);

Self {
data: if cfg!(feature = "ssr") {
AsyncDerived::new_mock(fetcher)
} 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<T> IntoFuture for LocalResource<T>
Expand Down Expand Up @@ -398,6 +424,7 @@ impl<T: 'static> From<ArcLocalResource<T>> for LocalResource<T> {
fn from(arc: ArcLocalResource<T>) -> Self {
Self {
data: arc.data.into(),
refetch: arc.refetch.into(),
#[cfg(any(debug_assertions, leptos_debuginfo))]
defined_at: arc.defined_at,
}
Expand All @@ -408,6 +435,7 @@ impl<T: 'static> From<LocalResource<T>> for ArcLocalResource<T> {
fn from(local: LocalResource<T>) -> Self {
Self {
data: local.data.into(),
refetch: local.refetch.into(),
#[cfg(any(debug_assertions, leptos_debuginfo))]
defined_at: local.defined_at,
}
Expand Down

0 comments on commit eeb01e2

Please sign in to comment.