Skip to content

Commit

Permalink
Support MutableStore
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-ramotar committed May 5, 2024
1 parent 9451d0f commit fa0c42c
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ class PagerBuilder<Id : Comparable<Id>, K : Any, V : Identifiable<Id>, E : Any>(
onEachItemStoreResponse: ((id: Id, StoreReadResponse<V>) -> Unit)? = null
) =
apply {
this.pagingSource = PagingSourceBuilder(
this.pagingSource = PagingSourceBuilder<Id, K, V, E>(
dispatcher,
pageStore,
throwableConverter,
messageConverter
)
.pageStore(pageStore)
.itemStore(itemStore)
.apply {
onEachPagingSourceLoadResult?.let {
Expand All @@ -75,12 +75,12 @@ class PagerBuilder<Id : Comparable<Id>, K : Any, V : Identifiable<Id>, E : Any>(
onEachPagingSourceLoadResult: ((key: K, PagingSource.LoadResult<Id, K, V, E>) -> Unit)? = null,
) =
apply {
this.pagingSource = PagingSourceBuilder(
this.pagingSource = PagingSourceBuilder<Id, K, V, E>(
dispatcher,
pageStore,
throwableConverter,
messageConverter,
)
.pageStore(pageStore)
.apply {
onEachPagingSourceLoadResult?.let {
onEachPagingSourceLoadResult(it)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,44 @@
package org.mobilenativefoundation.storex.paging

import kotlinx.coroutines.CoroutineDispatcher
import org.mobilenativefoundation.store.core5.ExperimentalStoreApi
import org.mobilenativefoundation.store.store5.MutableStore
import org.mobilenativefoundation.store.store5.Store
import org.mobilenativefoundation.store.store5.StoreReadRequest
import org.mobilenativefoundation.store.store5.StoreReadResponse
import org.mobilenativefoundation.storex.paging.impl.StorePagingSource
import org.mobilenativefoundation.storex.paging.impl.StorePagingSourceStreamProvider


@OptIn(ExperimentalStoreApi::class)
class PagingSourceBuilder<Id : Comparable<Id>, K : Any, V : Identifiable<Id>, E : Any> internal constructor(
private val dispatcher: CoroutineDispatcher,
private val pageStore: Store<K, PagingSource.LoadResult.Data<Id, K, V, E>>,
private val throwableConverter: (Throwable) -> E,
private val messageConverter: (String) -> E,
) {
private var pageStore: Store<K, PagingSource.LoadResult.Data<Id, K, V, E>>? = null
private var mutablePageStore: MutableStore<K, PagingSource.LoadResult.Data<Id, K, V, E>>? = null
private var itemStore: Store<Id, V>? = null
private var mutableItemStore: MutableStore<Id, V>? = null

private var onEachPagingSourceLoadResult: ((key: K, PagingSource.LoadResult<Id, K, V, E>) -> Unit)? = null
private var onEachItemStoreResponse: ((id: Id, StoreReadResponse<V>) -> Unit)? = null

fun itemStore(
itemStore: Store<Id, V>
) = apply { this.itemStore = itemStore }
store: Store<Id, V>
) = apply { this.itemStore = store }

fun mutableItemStore(
store: MutableStore<Id, V>
) = apply { this.mutableItemStore = store }

fun pageStore(
store: Store<K, PagingSource.LoadResult.Data<Id, K, V, E>>
) = apply { this.pageStore = store }

fun mutablePageStore(
store: MutableStore<K, PagingSource.LoadResult.Data<Id, K, V, E>>
) = apply { this.mutablePageStore = store }

fun onEachPagingSourceLoadResult(handler: (key: K, PagingSource.LoadResult<Id, K, V, E>) -> Unit) = apply {
this.onEachPagingSourceLoadResult = handler
Expand All @@ -32,11 +50,18 @@ class PagingSourceBuilder<Id : Comparable<Id>, K : Any, V : Identifiable<Id>, E

internal fun build(): PagingSource<Id, K, V, E> {
fun createPageStream(params: PagingSource.LoadParams<K>) =
pageStore.paged(params, throwableConverter, messageConverter)
mutablePageStore?.paged(params, throwableConverter, messageConverter) ?: pageStore?.paged(
params,
throwableConverter,
messageConverter
) ?: error("A page Store is required")

val createItemStream = itemStore?.let { itemStore ->
{ id: Id -> itemStore.stream(StoreReadRequest.cached(id, false)) }
}
val createItemStream =
mutableItemStore?.let { mutableItemStore ->
{ id: Id -> mutableItemStore.stream<Any>(StoreReadRequest.cached(id, false)) }
} ?: itemStore?.let { itemStore ->
{ id: Id -> itemStore.stream(StoreReadRequest.cached(id, false)) }
}

val streamProvider = StorePagingSourceStreamProvider(
createPageStream = ::createPageStream,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ package org.mobilenativefoundation.storex.paging

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.mapNotNull
import org.mobilenativefoundation.store.core5.ExperimentalStoreApi
import org.mobilenativefoundation.store.store5.MutableStore
import org.mobilenativefoundation.store.store5.Store
import org.mobilenativefoundation.store.store5.StoreReadRequest
import org.mobilenativefoundation.store.store5.StoreReadResponse


@Suppress("UNCHECKED_CAST")
fun <Id : Comparable<Id>, K : Any, V : Identifiable<Id>, E : Any> Store<K, PagingSource.LoadResult.Data<Id, K, V, E>>.paged(
private fun <Id : Comparable<Id>, K : Any, V : Identifiable<Id>, E : Any> page(
params: PagingSource.LoadParams<K>,
throwableConverter: (Throwable) -> E,
messageConverter: (String) -> E,
streamer: (request: StoreReadRequest<K>) -> Flow<StoreReadResponse<PagingSource.LoadResult.Data<Id, K, V, E>>>
): Flow<PagingSource.LoadResult<Id, K, V, E>> {
val readRequest = when (params.strategy) {
is PagingSource.LoadParams.Strategy.CacheFirst -> StoreReadRequest.cached(
Expand All @@ -21,7 +25,7 @@ fun <Id : Comparable<Id>, K : Any, V : Identifiable<Id>, E : Any> Store<K, Pagin
PagingSource.LoadParams.Strategy.SkipCache -> StoreReadRequest.fresh(params.key)
}

return stream(readRequest).mapNotNull { response ->
return streamer(readRequest).mapNotNull { response ->
when (response) {
is StoreReadResponse.Data -> response.value

Expand All @@ -46,4 +50,24 @@ fun <Id : Comparable<Id>, K : Any, V : Identifiable<Id>, E : Any> Store<K, Pagin
StoreReadResponse.Initial -> PagingSource.LoadResult.Loading()
}
}
}


fun <Id : Comparable<Id>, K : Any, V : Identifiable<Id>, E : Any> Store<K, PagingSource.LoadResult.Data<Id, K, V, E>>.paged(
params: PagingSource.LoadParams<K>,
throwableConverter: (Throwable) -> E,
messageConverter: (String) -> E,
): Flow<PagingSource.LoadResult<Id, K, V, E>> {
return page(params, throwableConverter, messageConverter, ::stream)
}

@ExperimentalStoreApi
fun <Id : Comparable<Id>, K : Any, V : Identifiable<Id>, E : Any> MutableStore<K, PagingSource.LoadResult.Data<Id, K, V, E>>.paged(
params: PagingSource.LoadParams<K>,
throwableConverter: (Throwable) -> E,
messageConverter: (String) -> E,
): Flow<PagingSource.LoadResult<Id, K, V, E>> {
return page(params, throwableConverter, messageConverter) {
this.stream<Any>(it)
}
}

0 comments on commit fa0c42c

Please sign in to comment.