QueryScope

Struct QueryScope 

Source
pub struct QueryScope<K, V> { /* private fields */ }
Expand description

A threadsafe wrapper for a query function. This can be used to add specific QueryOptions to only apply to one query scope.

These QueryOptions will be combined with the global QueryOptions set on the crate::QueryClient, with the local options taking precedence.

If you don’t need to set specific options, you can use functions with the crate::QueryClient directly.

Implementations§

Source§

impl<Key, PageItem> QueryScope<PaginatedPageKey<Key>, Option<(Vec<PageItem>, bool)>>
where Key: DebugIfDevtoolsEnabled + Clone + Hash + PartialEq + 'static + Send + Sync, PageItem: DebugIfDevtoolsEnabled + Clone + 'static + Send + Sync,

Source

pub fn new_paginated_with_cursor<Cursor, Fut>( getter: impl Fn(Key, usize, Option<Cursor>) -> Fut + 'static + Send + Sync, ) -> QueryScope<PaginatedPageKey<Key>, Option<(Vec<PageItem>, bool)>>
where Cursor: DebugIfDevtoolsEnabled + Clone + 'static + Send + Sync, Fut: Future<Output = (Vec<PageItem>, Option<Cursor>)> + Send,

Create a cursor-based paginated query scope.

Use this when your API uses continuation tokens/cursors rather than numeric offsets. Good for infinite scroll patterns or when your API doesn’t support offset-based pagination.

§Arguments

The getter receives:

  • query_key: Key - Your custom key, same across all pages
  • nb_items_requested: usize - Target number of items to return, will call again if not enough items returned
  • cursor: Option<Cursor> - Cursor from previous fetch, None on first page

The getter must return:

  • Vec<Item> - Items for this page
  • Option<Cursor> - Next cursor token, None when no more data
§Example
use leptos_fetch::{QueryScope, PaginatedPageKey};

// Create paginated scope with cursor-based API
let scope = QueryScope::new_paginated_with_cursor(
    |_key: (), nb_items, cursor: Option<String>| async move {
        // Call your API with cursor token
        let (items, next_cursor) = fetch_from_api(cursor, nb_items).await;
        (items, next_cursor)
    }
);

// Use like any other scope - fetch pages with PaginatedPageKey
let (items, has_more) = client.fetch_query(scope, PaginatedPageKey {
    key: (),
    page_index: 0,
    page_size: 20,
}).await.expect("Page exists");

// has_more: bool indicates if another page is available
if has_more {
    let (next_items, _) = client.fetch_query(scope, PaginatedPageKey {
        key: (),
        page_index: 1,
        page_size: 20,
    }).await.expect("Next page exists");
}
Source§

impl<Key, PageItem> QueryScope<PaginatedPageKey<Key>, Option<(Vec<PageItem>, Option<u64>)>>
where Key: DebugIfDevtoolsEnabled + Clone + Hash + PartialEq + 'static + Send + Sync, PageItem: DebugIfDevtoolsEnabled + Clone + 'static + Send + Sync,

Source

pub fn new_paginated_with_offset<Fut>( getter: impl Fn(Key, usize, u64) -> Fut + 'static + Send + Sync, ) -> QueryScope<PaginatedPageKey<Key>, Option<(Vec<PageItem>, Option<u64>)>>
where Fut: Future<Output = (Vec<PageItem>, Option<u64>)> + Send,

Create an offset-based paginated query scope.

Preferred when your API supports numeric offsets. Enables jumping to any page without loading intermediate pages and can return total item count for page calculations.

§Arguments

The getter receives:

  • query_key: Key - Your custom key, same across all pages
  • nb_items_requested: usize - Target number of items to return
  • offset: u64 - Starting position/offset for this fetch

The getter must return:

  • Vec<Item> - Items for this page
  • Option<u64> - Total item count if known (enables page count calculations)
§Example
use leptos_fetch::{QueryScope, PaginatedPageKey};

// Create paginated scope with offset-based API
let scope = QueryScope::new_paginated_with_offset(
    |_key: (), nb_items, offset| async move {
        // Call your API with offset and limit
        let (items, total) = fetch_from_api(offset, nb_items).await;
        (items, Some(total))
    }
);

// Fetch page 0
let (items, total) = client.fetch_query(scope, PaginatedPageKey {
    key: (),
    page_index: 0,
    page_size: 20,
}).await.expect("Page exists");

// Jump directly to page 10 (no need to load pages 1-9)
let (items, total) = client.fetch_query(scope, PaginatedPageKey {
    key: (),
    page_index: 10,
    page_size: 20,
}).await.expect("Page exists");

// Calculate total pages from returned total count
if let Some(total_items) = total {
    let total_pages = (total_items as f64 / 20.0).ceil() as u64;
}
Source§

impl<K, V> QueryScope<K, V>

Source

pub fn new<M>( query_scope: impl QueryScopeTrait<K, V, M> + Send + Sync + 'static, ) -> Self
where K: 'static + Send + Sync, V: 'static + Send + Sync,

Create a new QueryScope . If the query fn does not have a key argument, K=()

Source

pub fn with_options(self, options: QueryOptions) -> Self

Set specific QueryOptions to only apply to this query scope.

These QueryOptions will be combined with the global QueryOptions set on the crate::QueryClient, with the local options taking precedence.

Different query types are sometimes linked to the same source, e.g. you may want an invalidation of list_blogposts() to always automatically invalidate get_blogpost(id).

QueryScope::with_invalidation_link can be used to this effect, given a query key &K, you provide a Vec<String> that’s used as a hierarchy key (HK) for that query. When a query is invalidated, any query’s HK that’s prefixed by this HK will also be invalidated automatically. E.g. A query with HK ["users"] will also auto invalidate another query with ["users", "1"], but not the other way around. 2 queries with an identicial HK of ["users"] will auto invalidate each other.

use std::time::Duration;

use leptos_fetch::{QueryClient, QueryScope, QueryOptions};
use leptos::prelude::*;

#[derive(Debug, Clone)]
struct User;

fn list_users_query() -> QueryScope<(), Vec<User>> {
    QueryScope::new(async || vec![])
        .with_invalidation_link(
            |_key| ["users"]
        )
}

fn get_user_query() -> QueryScope<i32, User> {
    QueryScope::new(async move |user_id: i32| User)
        .with_invalidation_link(
            |user_id| ["users".to_string(), user_id.to_string()]
        )
}

let client = QueryClient::new();

// This invalidates only user "2", because ["users", "2"] is not a prefix of ["users"],
// list_users_query is NOT invalidated.
client.invalidate_query(get_user_query(), &2);

// This invalidates both queries, because ["users"] is a prefix of ["users", "$x"]
client.invalidate_query(list_users_query(), &());
Source

pub fn on_invalidation( self, on_invalidation_cb: impl Fn(&K) + 'static + Send + Sync, ) -> Self

Run a callback when a query is invalidated. Will only run once when a query is first invalidated, and not on repeated invalidations before a refresh/reset.

Source

pub fn on_gc(self, on_gc_cb: impl Fn(&K) + 'static + Send + Sync) -> Self

Run a callback when a query is garbage collected.

Source

pub fn with_title(self, title: impl Into<String>) -> Self

Available on crate features devtools or devtools-always only.

Set a custom query scope/type title that will show in devtools.

Trait Implementations§

Source§

impl<K, V> Clone for QueryScope<K, V>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<K, V> Debug for QueryScope<K, V>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<K, V> Freeze for QueryScope<K, V>

§

impl<K, V> !RefUnwindSafe for QueryScope<K, V>

§

impl<K, V> Send for QueryScope<K, V>

§

impl<K, V> Sync for QueryScope<K, V>

§

impl<K, V> Unpin for QueryScope<K, V>

§

impl<K, V> !UnwindSafe for QueryScope<K, V>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> ArchivePointee for T

Source§

type ArchivedMetadata = ()

The archived version of the pointer metadata for this type.
Source§

fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata

Converts some archived metadata to the pointer metadata for itself.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<E, T, Request, Encoding> FromReq<Patch<Encoding>, Request, E> for T
where Request: Req<E> + Send + 'static, Encoding: Decodes<T>, E: FromServerFnError,

Source§

async fn from_req(req: Request) -> Result<T, E>

Attempts to deserialize the arguments from a request.
Source§

impl<E, T, Request, Encoding> FromReq<Post<Encoding>, Request, E> for T
where Request: Req<E> + Send + 'static, Encoding: Decodes<T>, E: FromServerFnError,

Source§

async fn from_req(req: Request) -> Result<T, E>

Attempts to deserialize the arguments from a request.
Source§

impl<E, T, Request, Encoding> FromReq<Put<Encoding>, Request, E> for T
where Request: Req<E> + Send + 'static, Encoding: Decodes<T>, E: FromServerFnError,

Source§

async fn from_req(req: Request) -> Result<T, E>

Attempts to deserialize the arguments from a request.
Source§

impl<E, Encoding, Response, T> FromRes<Patch<Encoding>, Response, E> for T
where Response: ClientRes<E> + Send, Encoding: Decodes<T>, E: FromServerFnError,

Source§

async fn from_res(res: Response) -> Result<T, E>

Attempts to deserialize the outputs from a response.
Source§

impl<E, Encoding, Response, T> FromRes<Post<Encoding>, Response, E> for T
where Response: ClientRes<E> + Send, Encoding: Decodes<T>, E: FromServerFnError,

Source§

async fn from_res(res: Response) -> Result<T, E>

Attempts to deserialize the outputs from a response.
Source§

impl<E, Encoding, Response, T> FromRes<Put<Encoding>, Response, E> for T
where Response: ClientRes<E> + Send, Encoding: Decodes<T>, E: FromServerFnError,

Source§

async fn from_res(res: Response) -> Result<T, E>

Attempts to deserialize the outputs from a response.
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<E, T, Encoding, Request> IntoReq<Patch<Encoding>, Request, E> for T
where Request: ClientReq<E>, Encoding: Encodes<T>, E: FromServerFnError,

Source§

fn into_req(self, path: &str, accepts: &str) -> Result<Request, E>

Attempts to serialize the arguments into an HTTP request.
Source§

impl<E, T, Encoding, Request> IntoReq<Post<Encoding>, Request, E> for T
where Request: ClientReq<E>, Encoding: Encodes<T>, E: FromServerFnError,

Source§

fn into_req(self, path: &str, accepts: &str) -> Result<Request, E>

Attempts to serialize the arguments into an HTTP request.
Source§

impl<E, T, Encoding, Request> IntoReq<Put<Encoding>, Request, E> for T
where Request: ClientReq<E>, Encoding: Encodes<T>, E: FromServerFnError,

Source§

fn into_req(self, path: &str, accepts: &str) -> Result<Request, E>

Attempts to serialize the arguments into an HTTP request.
Source§

impl<E, Response, Encoding, T> IntoRes<Patch<Encoding>, Response, E> for T
where Response: TryRes<E>, Encoding: Encodes<T>, E: FromServerFnError + Send, T: Send,

Source§

async fn into_res(self) -> Result<Response, E>

Attempts to serialize the output into an HTTP response.
Source§

impl<E, Response, Encoding, T> IntoRes<Post<Encoding>, Response, E> for T
where Response: TryRes<E>, Encoding: Encodes<T>, E: FromServerFnError + Send, T: Send,

Source§

async fn into_res(self) -> Result<Response, E>

Attempts to serialize the output into an HTTP response.
Source§

impl<E, Response, Encoding, T> IntoRes<Put<Encoding>, Response, E> for T
where Response: TryRes<E>, Encoding: Encodes<T>, E: FromServerFnError + Send, T: Send,

Source§

async fn into_res(self) -> Result<Response, E>

Attempts to serialize the output into an HTTP response.
Source§

impl<T> LayoutRaw for T

Source§

fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>

Returns the layout of the type.
Source§

impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
where T: SharedNiching<N1, N2>, N1: Niching<T>, N2: Niching<T>,

Source§

unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool

Returns whether the given value has been niched. Read more
Source§

fn resolve_niched(out: Place<NichedOption<T, N1>>)

Writes data to out indicating that a T is niched.
Source§

impl<T> Pointee for T

Source§

type Metadata = ()

The metadata type for pointers and references to this type.
Source§

impl<T> SerializableKey for T

Source§

fn ser_key(&self) -> String

Serializes the key to a unique string. Read more
Source§

impl<T> StorageAccess<T> for T

Source§

fn as_borrowed(&self) -> &T

Borrows the value.
Source§

fn into_taken(self) -> T

Takes the value.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.