use std::pin::Pin;
use std::rc::Rc;
use std::{borrow::Borrow, future::Future};
use leptos::Signal;
use crate::{
use_query, use_query_client, QueryKey, QueryOptions, QueryResult, QueryState, QueryValue,
RefetchFn,
};
pub fn create_query<K, V, Fu>(
fetcher: impl Fn(K) -> Fu + 'static,
options: QueryOptions<V>,
) -> QueryScope<K, V>
where
K: QueryKey + 'static,
V: QueryValue + 'static,
Fu: Future<Output = V> + 'static,
{
let fetcher = Rc::new(move |s| Box::pin(fetcher(s)) as Pin<Box<dyn Future<Output = V>>>);
QueryScope { fetcher, options }
}
#[derive(Clone)]
pub struct QueryScope<K, V> {
#[allow(clippy::type_complexity)]
fetcher: Rc<dyn Fn(K) -> Pin<Box<dyn Future<Output = V>>>>,
options: QueryOptions<V>,
}
impl<K, V> QueryScope<K, V>
where
K: QueryKey + 'static,
V: QueryValue + 'static,
{
pub fn use_query(&self, key: impl Fn() -> K + 'static) -> QueryResult<V, impl RefetchFn> {
use_query(key, self.make_fetcher(), self.options.clone())
}
pub fn use_query_with_options(
&self,
key: impl Fn() -> K + 'static,
options: QueryOptions<V>,
) -> QueryResult<V, impl RefetchFn> {
use_query(key, self.make_fetcher(), options)
}
pub fn use_query_map_options(
&self,
key: impl Fn() -> K + 'static,
options: impl FnOnce(QueryOptions<V>) -> QueryOptions<V>,
) -> QueryResult<V, impl RefetchFn> {
use_query(key, self.make_fetcher(), options(self.options.clone()))
}
pub fn get_options(&self) -> &QueryOptions<V> {
&self.options
}
pub async fn prefetch_query(&self, key: K) {
use_query_client()
.prefetch_query(key, self.make_fetcher())
.await
}
pub async fn fetch_query(&self, key: K) -> QueryState<V> {
use_query_client()
.fetch_query(key, self.make_fetcher())
.await
}
pub fn get_query_state(&self, key: impl Fn() -> K + 'static) -> Signal<Option<QueryState<V>>> {
use_query_client().get_query_state(key)
}
pub fn peek_query_state(&self, key: &K) -> Option<QueryState<V>> {
use_query_client().peek_query_state(key)
}
pub fn invalidate_query(&self, key: impl Borrow<K>) -> bool {
use_query_client().invalidate_query::<K, V>(key)
}
pub fn invalidate_queries<Q>(&self, keys: impl IntoIterator<Item = Q>) -> Option<Vec<Q>>
where
K: QueryKey + 'static,
V: QueryValue + 'static,
Q: Borrow<K> + 'static,
{
use_query_client().invalidate_queries::<K, V, Q>(keys)
}
pub fn invalidate_all_queries(&self) {
use_query_client().invalidate_query_type::<K, V>();
}
pub fn update_query_data(
&self,
key: K,
updater: impl FnOnce(Option<&V>) -> Option<V> + 'static,
) {
use_query_client().update_query_data(key, updater);
}
pub fn set_query_data(&self, key: K, data: V) {
use_query_client().set_query_data(key, data);
}
pub fn update_query_data_mut(&self, key: impl Borrow<K>, updater: impl FnOnce(&mut V)) -> bool {
use_query_client().update_query_data_mut(key, updater)
}
pub fn cancel_query(&self, key: K) -> bool {
use_query_client().cancel_query::<K, V>(key)
}
fn make_fetcher(&self) -> impl Fn(K) -> Pin<Box<dyn Future<Output = V>>> {
let fetcher = self.fetcher.clone();
move |key| fetcher(key)
}
}