Skip to main content

Module hook

Module hook 

Source
Available on crate feature hook only.
Expand description

The use_query and use_mutation hooks — ergonomic query and mutation subscriptions for GPUI components.

§v2 Improvements

  • Uses QueryObserver which returns Option<Subscription> instead of panicking
  • Signals are properly cancelled on LatestWins replacement and reset()
  • AHashMap in QueryClient for faster lookups
  • MutationDiagnostic is a real type in devtools
  • max_pages defaults to Some(50)
  • QueryError has full Display + Error impls

§Query Usage (options-first)

The primary API is options-first with sensible defaults. The fetcher always receives a [QuerySignal] for cooperative cancellation:

use gpui_query::hook::use_query;
use gpui_query::{QueryOptions, CachePolicy, RequestPolicy};

struct MyView {
    users: gpui::Entity<gpui_query::QueryResource<Vec<User>, MyError>>,
    _subscription: gpui::Subscription,
}

impl MyView {
    fn new(cx: &mut gpui::Context<Self>) -> Self {
        let (users, _subscription) = use_query(
            QueryOptions::new("users")
                .cache_policy(CachePolicy::Ttl { ttl_ms: 60_000 })
                .request_policy(RequestPolicy::LatestWins),
            |signal| async move {
                // Your async fetcher here
                Ok(vec![])
            },
            cx,
        );
        Self { users, _subscription }
    }
}

For backward compatibility, use_query_unsignalled is available with a Fn() -> Fut fetcher that receives no signal. However, the signal-accepting use_query is the recommended default per the v2 “Signal-always” design goal.

§Mutation Usage

use gpui_query::hook::{use_mutation, mutate};

struct MyView {
    create_user: gpui::Entity<gpui_query::MutationResource<NewUser, User, MyError>>,
    _subscription: gpui::Subscription,
}

impl MyView {
    fn new(cx: &mut gpui::Context<Self>) -> Self {
        let (entity, sub) = use_mutation((), cx);
        Self { create_user: entity, _subscription: sub }
    }

    fn handle_submit(&mut self, name: String, cx: &mut gpui::Context<Self>) {
        mutate(&self.create_user, NewUser { name }, |vars| async move {
            Ok(User)
        }, cx);
    }
}

§WeakEntity Discard Behavior

Throughout this module, gpui::WeakEntity::upgrade() is used inside async tasks to access the owning entity. If the owning component is unmounted while a fetch is in-flight, upgrade() returns None and the fetch result is silently discarded. This is intentional for cache-layer correctness (avoids writing to a dead entity), but callers who rely on side effects from fetch completion should be aware that no callback or notification fires in this case.

§Signal Cancellation (Audit Finding #8)

The accept_current_request guard is the authoritative protection against stale writes. A previous signal.is_cancelled() check after the fetcher returned was removed – it was a best-effort optimization with a TOCTOU window that provided no guarantees. The two-phase protocol (accept + complete) correctly handles all cases where a newer request supersedes the current one.

Structs§

InfiniteQueryOptions
Options for infinite queries.
MutationCallbacks
Lifecycle callbacks for mutations.
MutationOptions
Options for use_mutation.
QueryOptions
Options for use_query and fetch_query.

Functions§

current_time_ms
Returns current time as milliseconds since UNIX epoch.
fetch_next_page_infinite
Initiate a fetch of the next page on an existing infinite query entity.
fetch_previous_page_infinite
Initiate a fetch of the previous page on an existing infinite query entity.
fetch_query
Initiate a fetch on an existing query entity.
fetch_query_with_policy
Like fetch_query, but the fetcher returns Fetched<T> so a server-derived [CachePolicy] can override the resource’s policy on success (“server wins”).
fetch_query_with_signal
Like fetch_query, but the fetcher receives a QuerySignal that it can check periodically for cooperative cancellation.
mutate
Trigger a mutation on an existing mutation entity.
mutate_arc
Audit fix #3: Like mutate_by_ref but accepts Arc<V> directly, letting the caller share the variables buffer across multiple mutation invocations (or with other readers) without an extra Arc::new.
mutate_by_ref
Audit fix #3: Like mutate but the mutator receives &V instead of V, so the retry loop borrows the variables from the stored Arc<V> and performs no V::clone per attempt. The caller is responsible for cloning V inside the mutator only if the fetcher needs an owned value across an .await (otherwise no clone is needed at all).
mutate_with_callbacks
Like mutate but with lifecycle callbacks.
use_infinite_query
Hook for infinite scrolling / pagination.
use_mutation
Hook for executing mutations (create, update, delete operations).
use_mutation_state
Hook to observe all mutation state across the application for a given (V, T, E) type triple.
use_query
Subscribe to a query resource and automatically re-render when it changes.
use_query_manual
Lower-level hook that sets up the entity and observation without starting a fetch.
use_query_manual_opts
Convenience wrapper around use_query_manual that builds the entity and observation from a [QueryOptions] value instead of raw policy parameters.
use_query_select
Subscribe to a query and project its data through a SelectTransform.
use_query_unsignalled
Like use_query but the fetcher receives no signal argument.
use_query_unsignalled_opts
Convenience wrapper around use_query_unsignalled that accepts an impl Into<QueryOptions> instead of the raw (key, cache_policy, request_policy) triple.
use_query_with_policy
Like use_query, but the fetcher returns Fetched<T> so a server-derived [CachePolicy] can override the caller’s per-query policy on success (“server wins”).