mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2025-09-05 16:19:41 +00:00
@@ -1,5 +1,13 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.26.2
|
||||||
|
|
||||||
|
* `Versions`:
|
||||||
|
* `Ktor`: `3.2.2` -> `3.2.3`
|
||||||
|
* `Okio`: `3.15.0` -> `3.16.0`
|
||||||
|
* `Coroutines`:
|
||||||
|
* Rename `SpecialMutableStateFlow` to `MutableRedeliverStateFlow`
|
||||||
|
|
||||||
## 0.26.1
|
## 0.26.1
|
||||||
|
|
||||||
* `Versions`:
|
* `Versions`:
|
||||||
|
@@ -2,11 +2,9 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.ui.test.ExperimentalTestApi
|
import androidx.compose.ui.test.ExperimentalTestApi
|
||||||
import androidx.compose.ui.test.runComposeUiTest
|
import androidx.compose.ui.test.runComposeUiTest
|
||||||
import dev.inmo.micro_utils.common.compose.LoadableComponent
|
import dev.inmo.micro_utils.common.compose.LoadableComponent
|
||||||
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
|
import dev.inmo.micro_utils.coroutines.MutableRedeliverStateFlow
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.firstOrNull
|
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
@@ -16,8 +14,8 @@ class LoadableComponentTests {
|
|||||||
@Test
|
@Test
|
||||||
@TestOnly
|
@TestOnly
|
||||||
fun testSimpleLoad() = runComposeUiTest {
|
fun testSimpleLoad() = runComposeUiTest {
|
||||||
val loadingFlow = SpecialMutableStateFlow<Int>(0)
|
val loadingFlow = MutableRedeliverStateFlow<Int>(0)
|
||||||
val loadedFlow = SpecialMutableStateFlow<Int>(0)
|
val loadedFlow = MutableRedeliverStateFlow<Int>(0)
|
||||||
setContent {
|
setContent {
|
||||||
LoadableComponent<Int>({
|
LoadableComponent<Int>({
|
||||||
loadingFlow.filter { it == 1 }.first()
|
loadingFlow.filter { it == 1 }.first()
|
||||||
|
@@ -3,7 +3,7 @@ package dev.inmo.micro_utils.coroutines.compose
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
|
import dev.inmo.micro_utils.coroutines.MutableRedeliverStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.debounce
|
import kotlinx.coroutines.flow.debounce
|
||||||
@@ -16,7 +16,7 @@ import org.jetbrains.compose.web.css.StyleSheet
|
|||||||
* to add `Style(stylesheet)` on every compose function call
|
* to add `Style(stylesheet)` on every compose function call
|
||||||
*/
|
*/
|
||||||
object StyleSheetsAggregator {
|
object StyleSheetsAggregator {
|
||||||
private val _stylesFlow = SpecialMutableStateFlow<Set<CSSRulesHolder>>(emptySet())
|
private val _stylesFlow = MutableRedeliverStateFlow<Set<CSSRulesHolder>>(emptySet())
|
||||||
val stylesFlow: StateFlow<Set<CSSRulesHolder>> = _stylesFlow.asStateFlow()
|
val stylesFlow: StateFlow<Set<CSSRulesHolder>> = _stylesFlow.asStateFlow()
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@@ -2,7 +2,7 @@ import androidx.compose.material.Button
|
|||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.ui.test.*
|
import androidx.compose.ui.test.*
|
||||||
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
|
import dev.inmo.micro_utils.coroutines.MutableRedeliverStateFlow
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ class FlowStateTests {
|
|||||||
@Test
|
@Test
|
||||||
@TestOnly
|
@TestOnly
|
||||||
fun simpleTest() = runComposeUiTest {
|
fun simpleTest() = runComposeUiTest {
|
||||||
val flowState = SpecialMutableStateFlow(0)
|
val flowState = MutableRedeliverStateFlow(0)
|
||||||
setContent {
|
setContent {
|
||||||
Button({ flowState.value++ }) { Text("Click") }
|
Button({ flowState.value++ }) { Text("Click") }
|
||||||
Text(flowState.collectAsState().value.toString())
|
Text(flowState.collectAsState().value.toString())
|
||||||
|
@@ -1,7 +1,5 @@
|
|||||||
package dev.inmo.micro_utils.coroutines
|
package dev.inmo.micro_utils.coroutines
|
||||||
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.InternalCoroutinesApi
|
import kotlinx.coroutines.InternalCoroutinesApi
|
||||||
import kotlinx.coroutines.channels.BufferOverflow
|
import kotlinx.coroutines.channels.BufferOverflow
|
||||||
@@ -11,13 +9,12 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.internal.SynchronizedObject
|
import kotlinx.coroutines.internal.SynchronizedObject
|
||||||
import kotlinx.coroutines.internal.synchronized
|
import kotlinx.coroutines.internal.synchronized
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Works like [StateFlow], but guarantee that latest value update will always be delivered to
|
* Works like [StateFlow], but guarantee that latest value update will always be delivered to
|
||||||
* each active subscriber
|
* each active subscriber
|
||||||
*/
|
*/
|
||||||
open class SpecialMutableStateFlow<T>(
|
open class MutableRedeliverStateFlow<T>(
|
||||||
initialValue: T
|
initialValue: T
|
||||||
) : MutableStateFlow<T>, FlowCollector<T>, MutableSharedFlow<T> {
|
) : MutableStateFlow<T>, FlowCollector<T>, MutableSharedFlow<T> {
|
||||||
@OptIn(InternalCoroutinesApi::class)
|
@OptIn(InternalCoroutinesApi::class)
|
||||||
@@ -68,3 +65,6 @@ open class SpecialMutableStateFlow<T>(
|
|||||||
|
|
||||||
override suspend fun collect(collector: FlowCollector<T>) = sharingFlow.collect(collector)
|
override suspend fun collect(collector: FlowCollector<T>) = sharingFlow.collect(collector)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Renamed to MutableRedeliverStateFlow", ReplaceWith("MutableRedeliverStateFlow<T>"))
|
||||||
|
typealias SpecialMutableStateFlow<T> = MutableRedeliverStateFlow<T>
|
@@ -1,7 +1,6 @@
|
|||||||
package dev.inmo.micro_utils.coroutines
|
package dev.inmo.micro_utils.coroutines
|
||||||
|
|
||||||
import kotlinx.coroutines.currentCoroutineContext
|
import kotlinx.coroutines.currentCoroutineContext
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
@@ -44,7 +43,7 @@ sealed interface SmartMutex {
|
|||||||
* @param locked Preset state of [isLocked] and its internal [_lockStateFlow]
|
* @param locked Preset state of [isLocked] and its internal [_lockStateFlow]
|
||||||
*/
|
*/
|
||||||
class Mutable(locked: Boolean = false) : SmartMutex {
|
class Mutable(locked: Boolean = false) : SmartMutex {
|
||||||
private val _lockStateFlow = SpecialMutableStateFlow<Boolean>(locked)
|
private val _lockStateFlow = MutableRedeliverStateFlow<Boolean>(locked)
|
||||||
override val lockStateFlow: StateFlow<Boolean> = _lockStateFlow.asStateFlow()
|
override val lockStateFlow: StateFlow<Boolean> = _lockStateFlow.asStateFlow()
|
||||||
|
|
||||||
private val internalChangesMutex = Mutex()
|
private val internalChangesMutex = Mutex()
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
package dev.inmo.micro_utils.coroutines
|
package dev.inmo.micro_utils.coroutines
|
||||||
|
|
||||||
import kotlinx.coroutines.currentCoroutineContext
|
import kotlinx.coroutines.currentCoroutineContext
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
@@ -47,7 +46,7 @@ sealed interface SmartSemaphore {
|
|||||||
*/
|
*/
|
||||||
class Mutable(permits: Int, acquiredPermits: Int = 0) : SmartSemaphore {
|
class Mutable(permits: Int, acquiredPermits: Int = 0) : SmartSemaphore {
|
||||||
override val maxPermits: Int = permits
|
override val maxPermits: Int = permits
|
||||||
private val _freePermitsStateFlow = SpecialMutableStateFlow<Int>(permits - acquiredPermits)
|
private val _freePermitsStateFlow = MutableRedeliverStateFlow<Int>(permits - acquiredPermits)
|
||||||
override val permitsStateFlow: StateFlow<Int> = _freePermitsStateFlow.asStateFlow()
|
override val permitsStateFlow: StateFlow<Int> = _freePermitsStateFlow.asStateFlow()
|
||||||
|
|
||||||
private val internalChangesMutex = Mutex(false)
|
private val internalChangesMutex = Mutex(false)
|
||||||
|
@@ -1,33 +1,31 @@
|
|||||||
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
|
import dev.inmo.micro_utils.coroutines.MutableRedeliverStateFlow
|
||||||
import dev.inmo.micro_utils.coroutines.asDeferred
|
|
||||||
import dev.inmo.micro_utils.coroutines.subscribe
|
import dev.inmo.micro_utils.coroutines.subscribe
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
|
||||||
|
|
||||||
class SpecialMutableStateFlowTests {
|
class SpecialMutableStateFlowTests {
|
||||||
@Test
|
@Test
|
||||||
fun simpleTest() = runTest {
|
fun simpleTest() = runTest {
|
||||||
val specialMutableStateFlow = SpecialMutableStateFlow(0)
|
val mutableRedeliverStateFlow = MutableRedeliverStateFlow(0)
|
||||||
specialMutableStateFlow.value = 1
|
mutableRedeliverStateFlow.value = 1
|
||||||
specialMutableStateFlow.first { it == 1 }
|
mutableRedeliverStateFlow.first { it == 1 }
|
||||||
assertEquals(1, specialMutableStateFlow.value)
|
assertEquals(1, mutableRedeliverStateFlow.value)
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
fun specialTest() = runTest {
|
fun specialTest() = runTest {
|
||||||
val specialMutableStateFlow = SpecialMutableStateFlow(0)
|
val mutableRedeliverStateFlow = MutableRedeliverStateFlow(0)
|
||||||
lateinit var subscriberJob: Job
|
lateinit var subscriberJob: Job
|
||||||
subscriberJob = specialMutableStateFlow.subscribe(this) {
|
subscriberJob = mutableRedeliverStateFlow.subscribe(this) {
|
||||||
when (it) {
|
when (it) {
|
||||||
1 -> specialMutableStateFlow.value = 2
|
1 -> mutableRedeliverStateFlow.value = 2
|
||||||
2 -> subscriberJob.cancel()
|
2 -> subscriberJob.cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
specialMutableStateFlow.value = 1
|
mutableRedeliverStateFlow.value = 1
|
||||||
subscriberJob.join()
|
subscriberJob.join()
|
||||||
assertEquals(2, specialMutableStateFlow.value)
|
assertEquals(2, mutableRedeliverStateFlow.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -18,5 +18,5 @@ crypto_js_version=4.1.1
|
|||||||
# Project data
|
# Project data
|
||||||
|
|
||||||
group=dev.inmo
|
group=dev.inmo
|
||||||
version=0.26.1
|
version=0.26.2
|
||||||
android_code_version=300
|
android_code_version=301
|
||||||
|
@@ -17,19 +17,19 @@ sqlite = "3.50.1.0"
|
|||||||
korlibs = "5.4.0"
|
korlibs = "5.4.0"
|
||||||
uuid = "0.8.4"
|
uuid = "0.8.4"
|
||||||
|
|
||||||
ktor = "3.2.2"
|
ktor = "3.2.3"
|
||||||
|
|
||||||
gh-release = "2.5.2"
|
gh-release = "2.5.2"
|
||||||
|
|
||||||
koin = "4.1.0"
|
koin = "4.1.0"
|
||||||
|
|
||||||
okio = "3.15.0"
|
okio = "3.16.0"
|
||||||
|
|
||||||
ksp = "2.2.0-2.0.2"
|
ksp = "2.2.0-2.0.2"
|
||||||
kotlin-poet = "2.2.0"
|
kotlin-poet = "2.2.0"
|
||||||
|
|
||||||
versions = "0.52.0"
|
versions = "0.52.0"
|
||||||
nmcp = "1.0.1"
|
nmcp = "1.0.2"
|
||||||
|
|
||||||
android-gradle = "8.9.+"
|
android-gradle = "8.9.+"
|
||||||
dexcount = "4.0.0"
|
dexcount = "4.0.0"
|
||||||
@@ -38,8 +38,8 @@ android-coreKtx = "1.16.0"
|
|||||||
android-recyclerView = "1.4.0"
|
android-recyclerView = "1.4.0"
|
||||||
android-appCompat = "1.7.1"
|
android-appCompat = "1.7.1"
|
||||||
android-fragment = "1.8.8"
|
android-fragment = "1.8.8"
|
||||||
android-espresso = "3.6.1"
|
android-espresso = "3.7.0"
|
||||||
android-test = "1.2.1"
|
android-test = "1.3.0"
|
||||||
|
|
||||||
android-props-minSdk = "21"
|
android-props-minSdk = "21"
|
||||||
android-props-compileSdk = "36"
|
android-props-compileSdk = "36"
|
||||||
|
@@ -1,9 +1,8 @@
|
|||||||
package dev.inmo.micro_utils.pagination.compose
|
package dev.inmo.micro_utils.pagination.compose
|
||||||
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
|
import dev.inmo.micro_utils.coroutines.MutableRedeliverStateFlow
|
||||||
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
|
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
|
||||||
import dev.inmo.micro_utils.coroutines.runCatchingLogging
|
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@@ -27,8 +26,8 @@ class InfinityPagedComponentContext<T> internal constructor(
|
|||||||
private val loader: suspend InfinityPagedComponentContext<T>.(Pagination) -> PaginationResult<T>
|
private val loader: suspend InfinityPagedComponentContext<T>.(Pagination) -> PaginationResult<T>
|
||||||
) {
|
) {
|
||||||
internal val startPage = SimplePagination(page, size)
|
internal val startPage = SimplePagination(page, size)
|
||||||
internal val latestLoadedPage = SpecialMutableStateFlow<PaginationResult<T>?>(null)
|
internal val latestLoadedPage = MutableRedeliverStateFlow<PaginationResult<T>?>(null)
|
||||||
internal val dataState = SpecialMutableStateFlow<List<T>?>(null)
|
internal val dataState = MutableRedeliverStateFlow<List<T>?>(null)
|
||||||
internal var loadingJob: Job? = null
|
internal var loadingJob: Job? = null
|
||||||
internal val loadingMutex = Mutex()
|
internal val loadingMutex = Mutex()
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
package dev.inmo.micro_utils.pagination.compose
|
package dev.inmo.micro_utils.pagination.compose
|
||||||
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
|
import dev.inmo.micro_utils.coroutines.MutableRedeliverStateFlow
|
||||||
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
|
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
|
||||||
import dev.inmo.micro_utils.pagination.*
|
import dev.inmo.micro_utils.pagination.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@@ -28,8 +28,8 @@ class PagedComponentContext<T> internal constructor(
|
|||||||
private val loader: suspend PagedComponentContext<T>.(Pagination) -> PaginationResult<T>
|
private val loader: suspend PagedComponentContext<T>.(Pagination) -> PaginationResult<T>
|
||||||
) {
|
) {
|
||||||
internal val startPage = SimplePagination(initialPage, size)
|
internal val startPage = SimplePagination(initialPage, size)
|
||||||
internal val latestLoadedPage = SpecialMutableStateFlow<PaginationResult<T>?>(null)
|
internal val latestLoadedPage = MutableRedeliverStateFlow<PaginationResult<T>?>(null)
|
||||||
internal val dataState = SpecialMutableStateFlow<PaginationResult<T>?>(null)
|
internal val dataState = MutableRedeliverStateFlow<PaginationResult<T>?>(null)
|
||||||
internal var loadingJob: Job? = null
|
internal var loadingJob: Job? = null
|
||||||
internal val loadingMutex = Mutex()
|
internal val loadingMutex = Mutex()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user