gquery
Types
Represents the full lifecycle of a remotely fetched value.
NotAsked— no fetch has been attempted yet.Loading— a fetch is in progress. Carries optional stale data so the UI can display the previous value while revalidating.Loaded— the last fetch succeeded.atis the Unix timestamp in milliseconds at which the data was recorded.Failed— the last fetch failed with an error.
pub type Entry(data, err) {
NotAsked
Loading(stale: option.Option(data))
Loaded(data: data, at: Int)
Failed(err: err)
}
Constructors
-
NotAsked -
Loading(stale: option.Option(data)) -
Loaded(data: data, at: Int) -
Failed(err: err)
Values
pub const always_stale: Int
Pass to stale_ms to always consider an entry stale.
The fetch will fire on every call to query.
pub fn get_data(entry: Entry(a, e)) -> option.Option(a)
Returns the most recent data held by the entry, if any.
Returns Some(data) for Loaded and Loading(Some(data)) (stale-while-
revalidate). Returns None for NotAsked, Failed, and Loading(None).
case gleam_query.get_data(entry) {
Some(contacts) -> render_list(contacts)
None -> render_empty()
}
pub fn invalidate(entry: Entry(a, e)) -> Entry(a, e)
Marks a loaded entry as stale, transitioning it to Loading while
preserving the existing data for display during revalidation.
Loaded(data, _)→Loading(Some(data))Loading(_)→ unchanged (fetch already in progress)NotAsked→ unchanged (nothing to preserve)Failed(_)→NotAsked(retry from a clean state)
Call this after a successful mutation to trigger a background refetch on the next access.
let contacts = dict.map_values(cache.contacts, fn(_, e) {
gleam_query.invalidate(e)
})
pub fn is_stale(
entry: Entry(a, e),
stale_ms: Int,
now_ms: Int,
) -> Bool
Returns True when the entry needs a fresh fetch.
NotAskedandFailedare always considered stale.Loadingis never stale (a fetch is already in flight).Loadedis stale whennow_ms - at > stale_ms.
gleam_query.is_stale(entry, stale_ms: 30_000, now_ms: now())
pub const never_stale: Int
Pass to stale_ms to never consider a loaded entry stale.
The fetch fires only once; the data is kept until manually invalidated.
pub fn record(
result: Result(data, err),
now_ms: Int,
) -> Entry(data, err)
Creates an Entry from a fetch result and a current timestamp.
Ok(data)→Loaded(data, at: now_ms)Error(err)→Failed(err)
Prefer gleam_query/lustre.record in Lustre apps — it captures the
current timestamp automatically.
let entry = gleam_query.record(result, now_ms: current_time_ms())