From fa0c42c8fd8f07349515bbd59217682c9730f844 Mon Sep 17 00:00:00 2001 From: Matt Ramotar Date: Sun, 5 May 2024 18:36:04 -0400 Subject: [PATCH] Support MutableStore --- .../storex/paging/PagerBuilder.kt | 8 ++-- .../storex/paging/PagingSourceBuilder.kt | 39 +++++++++++++++---- .../storex/paging/Store.paged.kt | 28 ++++++++++++- 3 files changed, 62 insertions(+), 13 deletions(-) diff --git a/experimental/paging/src/commonMain/kotlin/org/mobilenativefoundation/storex/paging/PagerBuilder.kt b/experimental/paging/src/commonMain/kotlin/org/mobilenativefoundation/storex/paging/PagerBuilder.kt index 338659020..9d29e08e4 100644 --- a/experimental/paging/src/commonMain/kotlin/org/mobilenativefoundation/storex/paging/PagerBuilder.kt +++ b/experimental/paging/src/commonMain/kotlin/org/mobilenativefoundation/storex/paging/PagerBuilder.kt @@ -50,12 +50,12 @@ class PagerBuilder, K : Any, V : Identifiable, E : Any>( onEachItemStoreResponse: ((id: Id, StoreReadResponse) -> Unit)? = null ) = apply { - this.pagingSource = PagingSourceBuilder( + this.pagingSource = PagingSourceBuilder( dispatcher, - pageStore, throwableConverter, messageConverter ) + .pageStore(pageStore) .itemStore(itemStore) .apply { onEachPagingSourceLoadResult?.let { @@ -75,12 +75,12 @@ class PagerBuilder, K : Any, V : Identifiable, E : Any>( onEachPagingSourceLoadResult: ((key: K, PagingSource.LoadResult) -> Unit)? = null, ) = apply { - this.pagingSource = PagingSourceBuilder( + this.pagingSource = PagingSourceBuilder( dispatcher, - pageStore, throwableConverter, messageConverter, ) + .pageStore(pageStore) .apply { onEachPagingSourceLoadResult?.let { onEachPagingSourceLoadResult(it) diff --git a/experimental/paging/src/commonMain/kotlin/org/mobilenativefoundation/storex/paging/PagingSourceBuilder.kt b/experimental/paging/src/commonMain/kotlin/org/mobilenativefoundation/storex/paging/PagingSourceBuilder.kt index 84ade4956..88bca4513 100644 --- a/experimental/paging/src/commonMain/kotlin/org/mobilenativefoundation/storex/paging/PagingSourceBuilder.kt +++ b/experimental/paging/src/commonMain/kotlin/org/mobilenativefoundation/storex/paging/PagingSourceBuilder.kt @@ -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, K : Any, V : Identifiable, E : Any> internal constructor( private val dispatcher: CoroutineDispatcher, - private val pageStore: Store>, private val throwableConverter: (Throwable) -> E, private val messageConverter: (String) -> E, ) { + private var pageStore: Store>? = null + private var mutablePageStore: MutableStore>? = null private var itemStore: Store? = null + private var mutableItemStore: MutableStore? = null private var onEachPagingSourceLoadResult: ((key: K, PagingSource.LoadResult) -> Unit)? = null private var onEachItemStoreResponse: ((id: Id, StoreReadResponse) -> Unit)? = null fun itemStore( - itemStore: Store - ) = apply { this.itemStore = itemStore } + store: Store + ) = apply { this.itemStore = store } + + fun mutableItemStore( + store: MutableStore + ) = apply { this.mutableItemStore = store } + + fun pageStore( + store: Store> + ) = apply { this.pageStore = store } + + fun mutablePageStore( + store: MutableStore> + ) = apply { this.mutablePageStore = store } fun onEachPagingSourceLoadResult(handler: (key: K, PagingSource.LoadResult) -> Unit) = apply { this.onEachPagingSourceLoadResult = handler @@ -32,11 +50,18 @@ class PagingSourceBuilder, K : Any, V : Identifiable, E internal fun build(): PagingSource { fun createPageStream(params: PagingSource.LoadParams) = - 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(StoreReadRequest.cached(id, false)) } + } ?: itemStore?.let { itemStore -> + { id: Id -> itemStore.stream(StoreReadRequest.cached(id, false)) } + } val streamProvider = StorePagingSourceStreamProvider( createPageStream = ::createPageStream, diff --git a/experimental/paging/src/commonMain/kotlin/org/mobilenativefoundation/storex/paging/Store.paged.kt b/experimental/paging/src/commonMain/kotlin/org/mobilenativefoundation/storex/paging/Store.paged.kt index 84e7e30dd..c34b29a53 100644 --- a/experimental/paging/src/commonMain/kotlin/org/mobilenativefoundation/storex/paging/Store.paged.kt +++ b/experimental/paging/src/commonMain/kotlin/org/mobilenativefoundation/storex/paging/Store.paged.kt @@ -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 , K : Any, V : Identifiable, E : Any> Store>.paged( +private fun , K : Any, V : Identifiable, E : Any> page( params: PagingSource.LoadParams, throwableConverter: (Throwable) -> E, messageConverter: (String) -> E, + streamer: (request: StoreReadRequest) -> Flow>> ): Flow> { val readRequest = when (params.strategy) { is PagingSource.LoadParams.Strategy.CacheFirst -> StoreReadRequest.cached( @@ -21,7 +25,7 @@ fun , K : Any, V : Identifiable, E : Any> Store StoreReadRequest.fresh(params.key) } - return stream(readRequest).mapNotNull { response -> + return streamer(readRequest).mapNotNull { response -> when (response) { is StoreReadResponse.Data -> response.value @@ -46,4 +50,24 @@ fun , K : Any, V : Identifiable, E : Any> Store PagingSource.LoadResult.Loading() } } +} + + +fun , K : Any, V : Identifiable, E : Any> Store>.paged( + params: PagingSource.LoadParams, + throwableConverter: (Throwable) -> E, + messageConverter: (String) -> E, +): Flow> { + return page(params, throwableConverter, messageConverter, ::stream) +} + +@ExperimentalStoreApi +fun , K : Any, V : Identifiable, E : Any> MutableStore>.paged( + params: PagingSource.LoadParams, + throwableConverter: (Throwable) -> E, + messageConverter: (String) -> E, +): Flow> { + return page(params, throwableConverter, messageConverter) { + this.stream(it) + } } \ No newline at end of file