karna_network library

Classes

AuthInterceptor
Attaches an access token to every request and, on a single 401, refreshes it once and retries the original request. Concurrent 401s share the same in-flight refresh call instead of each triggering their own — the classic "10 widgets load at once, token expired" case only hits your refresh endpoint once.
BatchCollector<T>
Coalesces individual load(id) calls made within window into one call to batchFetcher, then fans the combined result back out to each caller. Only useful if your backend actually has a batch endpoint (e.g. GET /users?ids=1,2,3) — this doesn't invent one for you, it just stops your app from firing N separate requests when N widgets each ask for one id in the same frame.
CircuitBreaker
Per-key circuit breaker: after failureThreshold consecutive failures against the same endpoint, stop sending requests to it for cooldown and fail fast instead of retrying it into the ground — protects a struggling upstream from a client that keeps hammering it, and protects the user from a screen that hangs on every retry attempt.
ErrorNormalizingInterceptor
Converts every DioException into one AppError shape, attached as err.error. Add this LAST in dio.interceptors — errors bubble back through interceptors in reverse of the order they were added, so adding this last means it's the first to see the raw exception and the thing your app-level catch blocks always deal with, regardless of which upstream or which other interceptor produced it.
HiveCacheStore<T>
Persistent SWR cache store backed by Hive CE (hive_ce).
HiveMutationQueueStore<T>
Persistent offline mutation queue backed by Hive CE (hive_ce).
MemoryCacheStore
In-memory LRU cache. Simple, fast, and gone the moment the app process dies — that's the correct default for most SWR use (it exists to save redundant round-trips within a session, not to work offline). Swap in a persistent SwrCacheStore if you specifically need cold-start data.
MemoryMutationQueueStore
In-memory queue — lost on app restart. An offline queue's whole point is usually to survive exactly that, so treat this as a starting point and implement MutationQueueStore against Hive/sqflite/ shared_preferences before shipping this to real users.
MutationQueueStore
OfflineMutationQueue
Queues non-GET requests made while offline and flushes them in order once connectivity returns. Deliberately has no dependency on any specific connectivity package — wire isOnline to whatever you already use (connectivity_plus, an app-level health check, a simple "last request succeeded" flag, etc) and call flush when it flips back to true.
QueuedMutation
RequestAggregator
Fires several GET requests through the same Dio instance and returns them together as one logical result. Each request still goes through SwrInterceptor individually, so each gets its own cache entry, its own freshness window, and its own background revalidation.
RetryInterceptor
Retries idempotent requests (GET/HEAD/OPTIONS by default) on network errors or 5xx responses, with exponential backoff, up to maxRetries. If a circuitBreaker is supplied, a key that keeps failing gets short-circuited instead of retried indefinitely — see CircuitBreaker.
SwrCacheEntry
A single cached response, plus enough metadata to decide whether it's still fresh, still usable-while-revalidating, or fully expired.
SwrCacheStore
Storage backend for cached responses. MemoryCacheStore is provided out of the box; implement this yourself on top of Hive, sqflite, or shared_preferences if the cache needs to survive app restarts.
SwrEvent
Lifecycle events for background revalidation, keyed by cache key. Listen to SwrInterceptor.events to drive a "refreshing…" indicator, or to know when to re-read fresh data after a background update lands.
SwrInterceptor
Adds stale-while-revalidate caching to a Dio instance.
SwrOptions
SwrRevalidated
SwrRevalidating
SwrRevalidationFailed
TokenProvider
Supplies the current access token and knows how to refresh it. Implement this against whatever holds your session (secure storage, an auth SDK, a Bloc/Riverpod provider, etc) — this package doesn't care where tokens live, only when to ask for one.

Enums

AppErrorKind

Constants

swrExtraKey → const String
Attach per-request config like:

Functions

defaultCacheKeyBuilder(RequestOptions options) → String
method + base url + path + sorted query params. Does NOT factor in headers, so two requests that differ only by an Authorization header (e.g. different logged-in users hitting the same path) will collide. If that applies to you, pass a custom SwrOptions.cacheKey or a custom CacheKeyBuilder that folds in whatever distinguishes them (e.g. a user id you already have at call time).
defaultErrorMapper(DioException error) → AppError
Best-effort default mapping from Dio's exception types to one shape. Backend error bodies vary per API (some send {"message": ...}, some {"error": {"code": ...}}, some nothing useful at all) — this can only map what Dio itself already knows (timeout, no connection, status code). Write your own ErrorMapper that inspects error.response?.data if you want a real message/code out of your specific backend's error body; pass it into ErrorNormalizingInterceptor(mapper: yourMapper).

Typedefs

CacheKeyBuilder = String Function(RequestOptions options)
ErrorMapper = AppError Function(DioException error)

Exceptions / Errors

AppError
One error shape regardless of which upstream produced it. Read e.error as AppError after ErrorNormalizingInterceptor is installed.
MutationQueuedException
Thrown by OfflineMutationQueue.send when the request was queued instead of sent, so calling code can show "saved, will sync" rather than treating it as either a success or a failure.