MobileNativeFoundation / Store

A Kotlin Multiplatform library for building network-resilient applications
https://mobilenativefoundation.github.io/Store/
Apache License 2.0
3.16k stars 197 forks source link

[Feature Request] Synchronization #598

Closed xVemu closed 8 months ago

xVemu commented 8 months ago

Is your feature request related to a problem? Please describe. I'm trying to:

  1. Display data from local room DB.
  2. Display Refresh Indicator.
  3. Download, display and store data from network.

Does this package support such a feature?

matt-ramotar commented 8 months ago

Hey there, yes Store supports that. Also check out the current site for an overview of Fetcher, SourceOfTruth, and StoreBuilder. For now, here's a simple getting started:

Create Your Fetcher


suspend fun makeNetworkRequest(args: Args): Data {
  TODO()
}

val fetcher = Fetcher.of<Args, Data> { args ->
  flowOf(makeNetworkRequest(args))
}

Create Your SourceOfTruth

val sourceOfTruth = SourceOfTruth.of<Args, Data, Data>(
    reader = {args: Args ->
        flowOf(db.get(args))
    },
    writer = { (args: Args, data: Data) ->
        db.put(args, data)
    }
)

Build Your Store with StoreBuilder

val storeBuilder = StoreBuilder.from(
    fetcher = fetcher,
    sourceOfTruth = sourceOfTruth
)

val store = storeBuilder.build()

Stream Store Response

// In your ViewModel

val request = StoreReadRequest.fresh(args)
val stream = store.stream(request).collect { response: StoreReadResponse ->
  when (response) {
    is StoreReadResponse.Loading -> setState { Loading }
    is StoreReadResponse.Data -> setState { Data(response.data) }
    is StoreReadResponse.Error -> setState { Error }
  }
}

Display Refresh Indicator When Loading

// In your View

val state = viewModel.collectAsState()
when (state.value) {
  is Loading -> displayLoadingView()
  is Data -> displayLoadedView()
  is Error -> displayErrorView()
}
xVemu commented 7 months ago

Display Refresh Indicator When Loading

// In your View

val state = viewModel.collectAsState()
when (state.value) {
  is Loading -> displayLoadingView()
  is Data -> displayLoadedView()
  is Error -> displayErrorView()
}

But when state is a type of Loading, I lose access to data, right?

matt-ramotar commented 7 months ago

Store's loading response doesn't include data. If I were solving that, my view model would be responsible for merging isRefreshing and lastData into one view state.