Skip to content

v0.1.0

Choose a tag to compare

@dbjpanda dbjpanda released this 18 Aug 10:31
· 55 commits to main since this release

Async server-state management for Android — caching, deduplication,
stale-while-revalidate, mutations, offline support, and a cache that survives
process death.

A TanStack Query equivalent for Kotlin,
built for how Android actually behaves.

Install

Not on Maven Central yet. JitPack builds it from this tag.

// settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven("https://jitpack.io")
    }
}

// build.gradle.kts
dependencies {
    implementation("com.github.dbjpanda.kwery:kwery-core:v0.1.0")
    implementation("com.github.dbjpanda.kwery:kwery-android:v0.1.0")   // focus + connectivity
    implementation("com.github.dbjpanda.kwery:kwery-compose:v0.1.0")   // rememberQuery
    implementation("com.github.dbjpanda.kwery:kwery-persist:v0.1.0")   // cache across process death
    testImplementation("com.github.dbjpanda.kwery:kwery-test:v0.1.0")  // TestQueryClient
}

What is in it

19 of 24 features complete through spec, tests and documentation, behind
367 tests — none of which use a real delay(), so the suite runs in
seconds rather than minutes.

  • Queries with staleTime / gcTime, deduplication, and two orthogonal
    status axes so success + fetching (background refresh) and pending +
    paused (cold start, offline) are both expressible
  • Mutations with optimistic updates, typed rollback context, and scopes that
    serialise writes which must not race
  • Offline: queries pause rather than fail, and writes queue durably and
    replay after process death
  • Persistence with hydration that preserves each entry's original age, so a
    restored cache is judged fresh or stale correctly
  • Infinite and paginated queries, with retry applied per page
  • Compose bindings and a Flow-first core that works equally well from a
    ViewModel

Android-specific choices

These are where Kwery diverges from a direct port, and why it exists:

  • Rotation costs nothing. A reattach inside a five-second grace window is a
    continuation, not a new mount, so it skips the staleness check. Measured:
    without it, rotation at the default staleTime = 0 fires a redundant request
    every time.
  • Connectivity means a validated network. A captive portal reports a
    perfectly good network on which every request fails; treating "connected" as
    "online" means refetching into a black hole.
  • Focus is process lifecycle, not Activity focus — per-Activity focus fires
    on dialogs, permission prompts and the app switcher.
  • The cache is bounded by count as well as time. A browser tab gets
    reloaded; an Android process can live for days.

What is not in it

Stated plainly, because a version number is a promise:

  • Not on Maven Central — needs GPG signing and a Portal namespace
  • Persistence is file-backed only. Benchmarked: 10 000 entries restore in
    3–5 ms, so this is not a startup problem. The cost is write amplification —
    every change rewrites the whole file
  • Three tests need a device: R8 key-encoding survival, captive-portal
    detection, and Compose render paths
  • Devtools, cross-process sync and streamed queries are specified and unbuilt

RELEASE.md is the
full inventory, including nine things deliberately not built and the reason for
each. Documentation is 22
pages, and every identifier in them is checked against the published API on
every build.

Apache-2.0. Feedback and bug reports very welcome — this is early.