commonMain.contextual.ContextualCacheAdapter.kt Maven / Gradle / Ivy
package opensavvy.cache.contextual
import opensavvy.cache.Cache
import opensavvy.state.coroutines.ProgressiveFlow
import opensavvy.state.coroutines.captureProgress
import opensavvy.state.outcome.Outcome
internal class ContextualCacheAdapter(
private val query: suspend (I, C) -> Outcome,
) : ContextualCache {
override fun get(id: I, context: C): ProgressiveFlow = captureProgress { query(id, context) }
override suspend fun update(values: Collection>) {
// This cache layer has no state, nothing to do
}
override suspend fun expire(ids: Collection) {
// This cache layer has no state, nothing to do
}
override suspend fun expireContextual(ids: Collection>) {
// This cache layer has no state, nothing to do
}
override suspend fun expireAll() {
// This cache layer has no state, nothing to do
}
companion object
}
/**
* Cache implementation which calls a given [transform] suspending function.
*
* This adapter is meant to be used as the first layer in a layer chain. By itself, it does no caching (all calls to [get][ContextualCache.get] call [transform]).
* To learn more about layer chaining, see [Cache].
* To learn more about the type parameters, see [ContextualCache].
*
* ### Example
*
* ```kotlin
* class User
* class SearchFilters
* data class Page(val number: Int)
* data class Post(…)
*
* suspend fun getTimeline(filters: SearchFilters, user: User, page: Page): List = …
*
* val cachedTimeline = cache, Nothing, List> { it, (user, page) ->
* getTimeline(filters, user, page).success()
* }
*
* val me = User()
* val filters = SearchFilters()
*
* println(cachedTimeline[filters, me to Page(0)].now())
* println(cachedTimeline[filters, me to Page(1)].now())
* ```
*
* @see opensavvy.cache.cache Non-contextual equivalent
*/
fun cache(transform: suspend (Identifier, Context) -> Outcome): ContextualCache =
ContextualCacheAdapter(transform)