A Cache that persists the normalized record store to a Hive Box so
it survives app restarts, while keeping every read/write on the fast
in-memory InMemoryCache path — the box is only a durable mirror,
updated in the background after each mutation.
Terminating Link for executing HTTP POST GraphQL requests via dio.Dio
— an intentionally lightweight alternative to DioLink (no proactive
GET-for-queries, no response-context headers, best-effort cancellation).
Configures automatic retry-with-backoff for a query (and, when explicitly
set on the request, a mutation or subscription) on transient network
failures.
Normalized info about a possibly-unauthorized response, passed to
IsUnauthorizedCallback — built the same way whether it came from a
normal streamed Response or a thrown ServerException, so detection
logic doesn't need to juggle two nullable inputs or duplicate checks for
both cases.
Automatically merges previous and incoming GraphQL query data objects by converting them
to JSON, deeply concatenating list fields, and parsing back using request.parseData.
Exponential backoff delay for attempt (0 = the first attempt, before
any failure), starting at initialDelay and multiplying by multiplier
for each subsequent attempt, capped at maxDelay so a long-lived
failure (a dead server, no network) settles into a fixed, bounded retry
cadence instead of growing forever. Shared by WebSocketLink's
reconnect scheduling; RetryOptions uses its own attempt-counted
variant since it isn't capped the same way.
Classifies a dio.DioException into the matching DioLink*Exception —
shared by every Dio-based terminating link (DioLink, SseLink) so
connection failures (timeouts, cancellation, DNS/socket errors, bad TLS
certificates, non-2xx statuses) are reported the same, structured way
everywhere instead of each transport bucketing most of them into one
generic exception.
Canonical identity for a GraphQLRequest: same operation, same document
text, and same variables (regardless of map key insertion order) all map
to the same key. Shared by InMemoryCache's query storage keys, the
in-flight request dedup map, and the active-watcher registry on
GraphQLClient so all three agree on request identity.
Recursively merges two JSON maps, automatically concatenating any matching List fields
and merging nested Maps, while updating new page metadata (e.g. pageInfo, cursors).
Optional callback that returns whether the current token is expired.
If omitted, expiry is not checked proactively — only unauthorized responses trigger refresh.
Classifies a possibly-unauthorized response/exception into an
AuthFailure. Receives a normalized UnauthorizedContext built the same
way for both a streamed Response and a thrown ServerException, so
custom detection logic can read errors/statusCode without caring
which case it came from.
Callback invoked when the access token is expired.
Receives a plain GraphQLClient (no auth link attached) that can be used
to perform the refresh request via its normal typed API (e.g. refreshClient.future(...)).
Should return new headers to use (e.g. {'Authorization': 'Bearer <newToken>'}),
or return null / throw to trigger token revocation.
Performs token refresh given the currently stored refresh token — always
non-null, since GraphQLClient only calls this when one is actually
persisted (no stored refresh token revokes immediately without calling
this at all) — and returns the new TokenPair to persist, or null/throws
to revoke. Receives a plain GraphQLClient (no auth link attached) to run
the refresh request via its normal typed API.
Callback that builds the auth headers (e.g. Authorization) for a given
token, read from TokenStorage.i by the caller — only invoked when a
token is actually stored, so token is always non-null.