Skip to content

Lightweight State Management for Async Operations in Kotlin Multiplatform

License

Notifications You must be signed in to change notification settings

VoirDev/stately

Repository files navigation

Stately – Lightweight State Management for Async Operations in Kotlin Multiplatform

Stately is a lightweight Kotlin Multiplatform library that simplifies handling async data flows like fetching and actions across platforms (Android, JVM, iOS).

Inspired by React hooks like useSWR, useMutation, useQuery, Stately aims to provide:

  • Consistent state management for async flows (loading, error, data)
  • Built-in revalidation (polling) for fetch
  • Action management with loading/error callbacks
  • Clean UI integration in Jetpack Compose

Not Yet Published

This library is not currently published to any public Maven repository.

To use it in your own project:


Step 1: Publish to Maven Local

Run the following command from the root of the project:

./gradlew publishToMavenLocal

This will install the library to your local Maven cache (~/.m2).


Step 2: Add mavenLocal() to your build

In your build.gradle.kts or build.gradle:

repositories {
    mavenLocal()
    // other repositories like mavenCentral(), google(), etc.
}

Step 3: Declare the dependency

In your module's dependencies block:

dependencies {
    implementation("dev.voir:stately:<version>")
}

Replace <version> with the version from your build.gradle.kts. Currently 1.0.0-alpha01


Note

Make sure to rerun publishToMavenLocal every time you change the library.

Modules

stately

Includes:

  • StatelyFetch<Data, Payload>: declarative data fetching with polling and payload support
  • StatelyAction<Payload, Response>: single-shot mutation-like execution
  • StatelyFetchResult and StatelyActionResult: unified state containers

sample

A sample Jetpack Compose app with:

  • Navigation
  • Examples for StatelyFetch, StatelyAction
  • Demo with StatelyFetchContent, StatelyFetchBoundary
  • Dynamic config panel to toggle revalidation, lazy load, errors

Core Concepts

StatelyFetch

val fetch = StatelyFetch<String, String>(
    fetcher = { payload -> api.loadData(payload) },
    revalidateInterval = 5000L,
    lazy = false,
    initialData = null,
    initialPayload = "",
)
  • .state: exposes loading, error, and data
  • .revalidate(payload?): triggers a new fetch
  • Revalidates periodically if revalidateInterval is set

StatelyAction

val action = StatelyAction(
    action = { payload -> api.sendSomething(payload) },
    onSuccess = { result -> println("✅ Success") },
    onError = { error -> println("❌ Failed") }
)

action.execute(payload)

Testing

Tests are written using pure kotlin.test, kotlinx.coroutines.test

Run all tests

./gradlew stately:check

Helper UI Components

StatelyFetchContent

Composable for rendering based on StatelyFetchResult:

StatelyFetchContent(
    state = state,
    loading = { Text("Loading") },
    error = { e -> Text("Error: ${e.message}") },
    content = { data -> Text("Data: $data") }
)

StatelyFetchBoundary

A wrapper that handles everything:

StatelyFetchBoundary(
    fetcher = { api.getSomething() },
    content = { data -> Text(data) }
)

Kotlin Multiplatform Targets

  • ✅ Android
  • ✅ iOS
  • ✅ JVM

Contributing

This library is still under active development. PRs and feedback are welcome.

  • File issues
  • Suggest features
  • Write sample apps for other targets

License

MIT License – see LICENSE for full details.

About

Lightweight State Management for Async Operations in Kotlin Multiplatform

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages