diff --git a/src/main/kotlin/Macaroni.kt b/src/main/kotlin/Macaroni.kt index d914c59..589ad6a 100644 --- a/src/main/kotlin/Macaroni.kt +++ b/src/main/kotlin/Macaroni.kt @@ -4,7 +4,7 @@ class Macaroni( onRemoteObservable: suspend () -> Flow, getLocalData: suspend () -> T, onUpdateLocal: suspend (T) -> Unit, - onRemoteFailure: (Throwable) -> Unit + onRemoteFailure: (Throwable) -> Unit = {} ) { // remote // 'onRemoteObservable' should pass the logic diff --git a/src/main/kotlin/MacaroniFlow.kt b/src/main/kotlin/MacaroniFlow.kt new file mode 100644 index 0000000..7f4692b --- /dev/null +++ b/src/main/kotlin/MacaroniFlow.kt @@ -0,0 +1,47 @@ +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.drop +import kotlinx.coroutines.flow.first + +class MacaroniFlow constructor( + onRemoteObservable: suspend () -> Flow, + onUpdateLocal: suspend (T) -> Unit, + onLocalObservable: suspend () -> Flow, +) { + + private var onRemoteObservable: suspend () -> Flow + private var onUpdateLocal: suspend (T) -> Unit + private var onLocalObservable: suspend () -> Flow + + init { + this.onRemoteObservable = onRemoteObservable + this.onUpdateLocal = onUpdateLocal + this.onLocalObservable = onLocalObservable + } + + suspend fun fetch(onNext: (MacaroniStatus, T) -> Unit) { + val localData = onLocalObservable().first() + onLocalObservable() + .drop(1) + .collect { data -> + onNext(Success, data) + } + try { + runCatching { + onNext(Loading, localData) + onRemoteObservable() + }.onSuccess { + it.collect { data -> + if (localData != data) { + onUpdateLocal(data) + } else { + onNext(Success, data) + } + } + }.onFailure { + onNext(Error, localData) + } + } catch (e: Exception) { + onNext(Error, localData) + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/MacaroniFlowTest.kt b/src/test/kotlin/MacaroniFlowTest.kt new file mode 100644 index 0000000..57f95bf --- /dev/null +++ b/src/test/kotlin/MacaroniFlowTest.kt @@ -0,0 +1,28 @@ +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.flow + +private suspend fun main() { + val macaroni = MacaroniFlow( + onRemoteObservable = { + flow { + delay(100) + emit(TestStatus("onRemoteObservable", "test")) + } + }, + onUpdateLocal = { + delay(100) + println("onUpdateLocal") + }, + onLocalObservable = { + flow { + emit(TestStatus("getLocalData", "first")) + delay(200) + emit(TestStatus("changeLocal", "nice")) + } + } + ) + + macaroni.fetch { status, result -> + println("status: $status, result: $result") + } +} \ No newline at end of file