hook only.Expand description
The use_query and use_mutation hooks — ergonomic query and mutation
subscriptions for GPUI components.
§v2 Improvements
- Uses
QueryObserverwhich returnsOption<Subscription>instead of panicking - Signals are properly cancelled on
LatestWinsreplacement andreset() AHashMapinQueryClientfor faster lookupsMutationDiagnosticis a real type in devtoolsmax_pagesdefaults toSome(50)QueryErrorhas fullDisplay+Errorimpls
§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§
- Infinite
Query Options - Options for infinite queries.
- Mutation
Callbacks - Lifecycle callbacks for mutations.
- Mutation
Options - Options for
use_mutation. - Query
Options - Options for
use_queryandfetch_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 returnsFetched<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 aQuerySignalthat it can check periodically for cooperative cancellation. - mutate
- Trigger a mutation on an existing mutation entity.
- mutate_
arc - Audit fix #3: Like
mutate_by_refbut acceptsArc<V>directly, letting the caller share the variables buffer across multiple mutation invocations (or with other readers) without an extraArc::new. - mutate_
by_ ref - Audit fix #3: Like
mutatebut the mutator receives&Vinstead ofV, so the retry loop borrows the variables from the storedArc<V>and performs noV::cloneper attempt. The caller is responsible for cloningVinside the mutator only if the fetcher needs an owned value across an.await(otherwise no clone is needed at all). - mutate_
with_ callbacks - Like
mutatebut 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_manualthat 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_querybut the fetcher receives no signal argument. - use_
query_ unsignalled_ opts - Convenience wrapper around
use_query_unsignalledthat accepts animpl Into<QueryOptions>instead of the raw(key, cache_policy, request_policy)triple. - use_
query_ with_ policy - Like
use_query, but the fetcher returnsFetched<T>so a server-derived [CachePolicy] can override the caller’s per-query policy on success (“server wins”).