mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2025-09-22 00:39:22 +00:00
Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
00acb9fddd | |||
de3d14dc41 | |||
67ff9cc9b3 | |||
af132103a0 | |||
3b1124a804 | |||
f226c2dfd6 | |||
69d6e63846 | |||
02c3d397ad | |||
67a1050646 | |||
8cd0775a6c | |||
162294d6c6 | |||
c4dd19dd00 | |||
d2314422f1 | |||
6fedd6f859 | |||
e52b59665f | |||
cda9d09689 | |||
c9237b3f00 | |||
18bba66c4a | |||
63418c4a8a | |||
2e66c6f4e3 |
40
CHANGELOG.md
40
CHANGELOG.md
@@ -1,5 +1,45 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.7.5
|
||||||
|
|
||||||
|
* `Versions`:
|
||||||
|
* `Klock`: `2.4.6` -> `2.4.7`
|
||||||
|
* `Ktor`: `1.6.4` -> `1.6.5`
|
||||||
|
* `Common`:
|
||||||
|
* Type `Either` got its own serializer
|
||||||
|
* `FSM`:
|
||||||
|
* `Common`:
|
||||||
|
* Add opportunity for comfortable adding default state handler
|
||||||
|
|
||||||
|
## 0.7.4
|
||||||
|
|
||||||
|
* `Common`:
|
||||||
|
* New type `Either`
|
||||||
|
* `Serialization`:
|
||||||
|
* `TypedSerializer`
|
||||||
|
* New factory fun which accept vararg pairs of type and its serializer
|
||||||
|
* `Repos`:
|
||||||
|
* `Common` (`Android`):
|
||||||
|
* `AbstractMutableAndroidCRUDRepo` flows now will have extra buffer capacity instead of reply. It means that
|
||||||
|
android crud repo _WILL NOT_ send previous events to the
|
||||||
|
* `Exposed`:
|
||||||
|
* New parameter `AbstractExposedWriteCRUDRepo#replyCacheInFlows`
|
||||||
|
* KeyValue realization `ExposedKeyValueRepo` properties `_onNewValue` and `_onValueRemoved` now are available in
|
||||||
|
inheritors
|
||||||
|
* `Pagination`:
|
||||||
|
* `Common`:
|
||||||
|
* New types `getAllBy*` for current, next and custom paging
|
||||||
|
|
||||||
|
## 0.7.3
|
||||||
|
|
||||||
|
* `Versions`:
|
||||||
|
* `Exposed`: `0.35.2` -> `0.35.3`
|
||||||
|
|
||||||
|
## 0.7.2
|
||||||
|
|
||||||
|
* `Versions`:
|
||||||
|
* `Klock`: `2.4.5` -> `2.4.6`
|
||||||
|
|
||||||
## 0.7.1
|
## 0.7.1
|
||||||
|
|
||||||
* `Versions`:
|
* `Versions`:
|
||||||
|
@@ -0,0 +1,151 @@
|
|||||||
|
package dev.inmo.micro_utils.common
|
||||||
|
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
import kotlinx.serialization.descriptors.*
|
||||||
|
import kotlinx.serialization.encoding.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Realization of this interface will contains at least one not null - [t1] or [t2]
|
||||||
|
*
|
||||||
|
* @see EitherFirst
|
||||||
|
* @see EitherSecond
|
||||||
|
* @see Either.Companion.first
|
||||||
|
* @see Either.Companion.second
|
||||||
|
* @see Either.onFirst
|
||||||
|
* @see Either.onSecond
|
||||||
|
*/
|
||||||
|
@Serializable(EitherSerializer::class)
|
||||||
|
sealed interface Either<T1, T2> {
|
||||||
|
val t1: T1?
|
||||||
|
val t2: T2?
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun <T1, T2> serializer(
|
||||||
|
t1Serializer: KSerializer<T1>,
|
||||||
|
t2Serializer: KSerializer<T2>,
|
||||||
|
): KSerializer<Either<T1, T2>> = EitherSerializer(t1Serializer, t2Serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EitherSerializer<T1, T2>(
|
||||||
|
t1Serializer: KSerializer<T1>,
|
||||||
|
t2Serializer: KSerializer<T2>,
|
||||||
|
) : KSerializer<Either<T1, T2>> {
|
||||||
|
@ExperimentalSerializationApi
|
||||||
|
@InternalSerializationApi
|
||||||
|
override val descriptor: SerialDescriptor = buildSerialDescriptor(
|
||||||
|
"TypedSerializer",
|
||||||
|
SerialKind.CONTEXTUAL
|
||||||
|
) {
|
||||||
|
element("type", String.serializer().descriptor)
|
||||||
|
element("value", ContextualSerializer(Either::class).descriptor)
|
||||||
|
}
|
||||||
|
private val t1EitherSerializer = EitherFirst.serializer(t1Serializer, t2Serializer)
|
||||||
|
private val t2EitherSerializer = EitherSecond.serializer(t1Serializer, t2Serializer)
|
||||||
|
|
||||||
|
@ExperimentalSerializationApi
|
||||||
|
@InternalSerializationApi
|
||||||
|
override fun deserialize(decoder: Decoder): Either<T1, T2> {
|
||||||
|
return decoder.decodeStructure(descriptor) {
|
||||||
|
var type: String? = null
|
||||||
|
lateinit var result: Either<T1, T2>
|
||||||
|
while (true) {
|
||||||
|
when (val index = decodeElementIndex(descriptor)) {
|
||||||
|
0 -> type = decodeStringElement(descriptor, 0)
|
||||||
|
1 -> {
|
||||||
|
result = when (type) {
|
||||||
|
"t1" -> decodeSerializableElement(
|
||||||
|
descriptor,
|
||||||
|
1,
|
||||||
|
t1EitherSerializer
|
||||||
|
)
|
||||||
|
"t2" -> decodeSerializableElement(
|
||||||
|
descriptor,
|
||||||
|
1,
|
||||||
|
t2EitherSerializer
|
||||||
|
)
|
||||||
|
else -> error("Unknown type of either: $type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CompositeDecoder.DECODE_DONE -> break
|
||||||
|
else -> error("Unexpected index: $index")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ExperimentalSerializationApi
|
||||||
|
@InternalSerializationApi
|
||||||
|
override fun serialize(encoder: Encoder, value: Either<T1, T2>) {
|
||||||
|
encoder.encodeStructure(descriptor) {
|
||||||
|
when (value) {
|
||||||
|
is EitherFirst -> {
|
||||||
|
encodeStringElement(descriptor, 0, "t1")
|
||||||
|
encodeSerializableElement(descriptor, 1, t1EitherSerializer, value)
|
||||||
|
}
|
||||||
|
is EitherSecond -> {
|
||||||
|
encodeStringElement(descriptor, 0, "t2")
|
||||||
|
encodeSerializableElement(descriptor, 1, t2EitherSerializer, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type [Either] will always have not nullable [t1]
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
|
data class EitherFirst<T1, T2>(
|
||||||
|
override val t1: T1
|
||||||
|
) : Either<T1, T2> {
|
||||||
|
override val t2: T2?
|
||||||
|
get() = null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type [Either] will always have not nullable [t2]
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
|
data class EitherSecond<T1, T2>(
|
||||||
|
override val t2: T2
|
||||||
|
) : Either<T1, T2> {
|
||||||
|
override val t1: T1?
|
||||||
|
get() = null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return New instance of [EitherFirst]
|
||||||
|
*/
|
||||||
|
inline fun <T1, T2> Either.Companion.first(t1: T1): Either<T1, T2> = EitherFirst(t1)
|
||||||
|
/**
|
||||||
|
* @return New instance of [EitherSecond]
|
||||||
|
*/
|
||||||
|
inline fun <T1, T2> Either.Companion.second(t2: T2): Either<T1, T2> = EitherSecond(t2)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will call [block] in case when [Either.t1] of [this] is not null
|
||||||
|
*/
|
||||||
|
inline fun <T1, T2, E : Either<T1, T2>> E.onFirst(crossinline block: (T1) -> Unit): E {
|
||||||
|
val t1 = t1
|
||||||
|
t1 ?.let(block)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will call [block] in case when [Either.t2] of [this] is not null
|
||||||
|
*/
|
||||||
|
inline fun <T1, T2, E : Either<T1, T2>> E.onSecond(crossinline block: (T2) -> Unit): E {
|
||||||
|
val t2 = t2
|
||||||
|
t2 ?.let(block)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T1, reified T2> Any.either() = when (this) {
|
||||||
|
is T1 -> Either.first<T1, T2>(this)
|
||||||
|
is T2 -> Either.second<T1, T2>(this)
|
||||||
|
else -> error("Incorrect type of either argument $this")
|
||||||
|
}
|
@@ -6,6 +6,9 @@ import org.w3c.files.File
|
|||||||
import org.w3c.files.FileReader
|
import org.w3c.files.FileReader
|
||||||
import kotlin.js.Promise
|
import kotlin.js.Promise
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @suppress
|
||||||
|
*/
|
||||||
actual typealias MPPFile = File
|
actual typealias MPPFile = File
|
||||||
|
|
||||||
fun MPPFile.readBytesPromise() = Promise<ByteArray> { success, failure ->
|
fun MPPFile.readBytesPromise() = Promise<ByteArray> { success, failure ->
|
||||||
@@ -23,10 +26,19 @@ fun MPPFile.readBytesPromise() = Promise<ByteArray> { success, failure ->
|
|||||||
|
|
||||||
private suspend fun MPPFile.dirtyReadBytes(): ByteArray = readBytesPromise().await()
|
private suspend fun MPPFile.dirtyReadBytes(): ByteArray = readBytesPromise().await()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @suppress
|
||||||
|
*/
|
||||||
actual val MPPFile.filename: FileName
|
actual val MPPFile.filename: FileName
|
||||||
get() = FileName(name)
|
get() = FileName(name)
|
||||||
|
/**
|
||||||
|
* @suppress
|
||||||
|
*/
|
||||||
actual val MPPFile.filesize: Long
|
actual val MPPFile.filesize: Long
|
||||||
get() = size.toLong()
|
get() = size.toLong()
|
||||||
|
/**
|
||||||
|
* @suppress
|
||||||
|
*/
|
||||||
@Warning("That is not optimized version of bytes allocator. Use asyncBytesAllocator everywhere you can")
|
@Warning("That is not optimized version of bytes allocator. Use asyncBytesAllocator everywhere you can")
|
||||||
actual val MPPFile.bytesAllocator: SuspendByteArrayAllocator
|
actual val MPPFile.bytesAllocator: SuspendByteArrayAllocator
|
||||||
get() = ::dirtyReadBytes
|
get() = ::dirtyReadBytes
|
||||||
|
@@ -4,12 +4,24 @@ import dev.inmo.micro_utils.coroutines.doInIO
|
|||||||
import dev.inmo.micro_utils.coroutines.doOutsideOfCoroutine
|
import dev.inmo.micro_utils.coroutines.doOutsideOfCoroutine
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @suppress
|
||||||
|
*/
|
||||||
actual typealias MPPFile = File
|
actual typealias MPPFile = File
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @suppress
|
||||||
|
*/
|
||||||
actual val MPPFile.filename: FileName
|
actual val MPPFile.filename: FileName
|
||||||
get() = FileName(name)
|
get() = FileName(name)
|
||||||
|
/**
|
||||||
|
* @suppress
|
||||||
|
*/
|
||||||
actual val MPPFile.filesize: Long
|
actual val MPPFile.filesize: Long
|
||||||
get() = length()
|
get() = length()
|
||||||
|
/**
|
||||||
|
* @suppress
|
||||||
|
*/
|
||||||
actual val MPPFile.bytesAllocator: SuspendByteArrayAllocator
|
actual val MPPFile.bytesAllocator: SuspendByteArrayAllocator
|
||||||
get() = {
|
get() = {
|
||||||
doInIO {
|
doInIO {
|
||||||
|
@@ -1,3 +1,6 @@
|
|||||||
package dev.inmo.micro_utils.crypto
|
package dev.inmo.micro_utils.crypto
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @suppress
|
||||||
|
*/
|
||||||
actual fun SourceBytes.md5(): MD5 = CryptoJS.MD5(decodeToString())
|
actual fun SourceBytes.md5(): MD5 = CryptoJS.MD5(decodeToString())
|
||||||
|
@@ -3,6 +3,9 @@ package dev.inmo.micro_utils.crypto
|
|||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @suppress
|
||||||
|
*/
|
||||||
actual fun SourceBytes.md5(): MD5 = BigInteger(
|
actual fun SourceBytes.md5(): MD5 = BigInteger(
|
||||||
1,
|
1,
|
||||||
MessageDigest.getInstance("MD5").digest(this)
|
MessageDigest.getInstance("MD5").digest(this)
|
||||||
|
@@ -13,10 +13,10 @@ repositories {
|
|||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
jvm()
|
jvm()
|
||||||
js(IR) {
|
// js(IR) {
|
||||||
browser()
|
// browser()
|
||||||
nodejs()
|
// nodejs()
|
||||||
}
|
// }
|
||||||
android {}
|
android {}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@@ -29,7 +29,7 @@ kotlin {
|
|||||||
it != project
|
it != project
|
||||||
&& it.hasProperty("kotlin")
|
&& it.hasProperty("kotlin")
|
||||||
&& it.kotlin.sourceSets.any { it.name.contains("commonMain") }
|
&& it.kotlin.sourceSets.any { it.name.contains("commonMain") }
|
||||||
&& it.kotlin.sourceSets.any { it.name.contains("jsMain") }
|
// && it.kotlin.sourceSets.any { it.name.contains("jsMain") }
|
||||||
&& it.kotlin.sourceSets.any { it.name.contains("jvmMain") }
|
&& it.kotlin.sourceSets.any { it.name.contains("jvmMain") }
|
||||||
&& it.kotlin.sourceSets.any { it.name.contains("androidMain") }
|
&& it.kotlin.sourceSets.any { it.name.contains("androidMain") }
|
||||||
) {
|
) {
|
||||||
@@ -38,22 +38,22 @@ kotlin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jsMain {
|
// jsMain {
|
||||||
dependencies {
|
// dependencies {
|
||||||
implementation kotlin('stdlib')
|
// implementation kotlin('stdlib')
|
||||||
|
|
||||||
project.parent.subprojects.forEach {
|
// project.parent.subprojects.forEach {
|
||||||
if (
|
// if (
|
||||||
it != project
|
// it != project
|
||||||
&& it.hasProperty("kotlin")
|
// && it.hasProperty("kotlin")
|
||||||
&& it.kotlin.sourceSets.any { it.name.contains("commonMain") }
|
// && it.kotlin.sourceSets.any { it.name.contains("commonMain") }
|
||||||
&& it.kotlin.sourceSets.any { it.name.contains("jsMain") }
|
// && it.kotlin.sourceSets.any { it.name.contains("jsMain") }
|
||||||
) {
|
// ) {
|
||||||
api it
|
// api it
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
jvmMain {
|
jvmMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation kotlin('stdlib')
|
implementation kotlin('stdlib')
|
||||||
@@ -116,9 +116,9 @@ tasks.dokkaHtml {
|
|||||||
sourceRoots.setFrom(findSourcesWithName("commonMain"))
|
sourceRoots.setFrom(findSourcesWithName("commonMain"))
|
||||||
}
|
}
|
||||||
|
|
||||||
named("jsMain") {
|
// named("jsMain") {
|
||||||
sourceRoots.setFrom(findSourcesWithName("jsMain", "commonMain"))
|
// sourceRoots.setFrom(findSourcesWithName("jsMain", "commonMain"))
|
||||||
}
|
// }
|
||||||
|
|
||||||
named("jvmMain") {
|
named("jvmMain") {
|
||||||
sourceRoots.setFrom(findSourcesWithName("jvmMain", "commonMain"))
|
sourceRoots.setFrom(findSourcesWithName("jvmMain", "commonMain"))
|
||||||
|
@@ -6,7 +6,7 @@ import kotlin.reflect.KClass
|
|||||||
* Default realization of [StatesHandler]. It will incapsulate checking of [State] type in [checkHandleable] and class
|
* Default realization of [StatesHandler]. It will incapsulate checking of [State] type in [checkHandleable] and class
|
||||||
* casting in [handleState]
|
* casting in [handleState]
|
||||||
*/
|
*/
|
||||||
class StateHandlerHolder<I : State>(
|
class StatesHandlerHolder<I : State>(
|
||||||
private val inputKlass: KClass<I>,
|
private val inputKlass: KClass<I>,
|
||||||
private val strict: Boolean = false,
|
private val strict: Boolean = false,
|
||||||
private val delegateTo: StatesHandler<I>
|
private val delegateTo: StatesHandler<I>
|
||||||
@@ -19,9 +19,20 @@ class StateHandlerHolder<I : State>(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls [delegateTo] method [StatesHandler.handleState] with [state] casted to [I]. Use [checkHandleable]
|
* Calls [delegateTo] method [StatesHandler.handleState] with [state] casted to [I]. Use [checkHandleable]
|
||||||
* to be sure that this [StateHandlerHolder] will be able to handle [state]
|
* to be sure that this [StatesHandlerHolder] will be able to handle [state]
|
||||||
*/
|
*/
|
||||||
override suspend fun StatesMachine.handleState(state: State): State? {
|
override suspend fun StatesMachine.handleState(state: State): State? {
|
||||||
return delegateTo.run { handleState(state as I) }
|
return delegateTo.run { handleState(state as I) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Renamed", ReplaceWith("StatesHandlerHolder"))
|
||||||
|
typealias StateHandlerHolder<T> = StatesHandlerHolder<T>
|
||||||
|
|
||||||
|
inline fun <reified T : State> StatesHandler<T>.holder(
|
||||||
|
strict: Boolean = true
|
||||||
|
) = StatesHandlerHolder(
|
||||||
|
T::class,
|
||||||
|
strict,
|
||||||
|
this
|
||||||
|
)
|
@@ -2,11 +2,10 @@ package dev.inmo.micro_utils.fsm.common
|
|||||||
|
|
||||||
import dev.inmo.micro_utils.coroutines.*
|
import dev.inmo.micro_utils.coroutines.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.flow.asFlow
|
|
||||||
|
|
||||||
private suspend fun <I : State> StatesMachine.launchStateHandling(
|
private suspend fun <I : State> StatesMachine.launchStateHandling(
|
||||||
state: State,
|
state: State,
|
||||||
handlers: List<StateHandlerHolder<out I>>
|
handlers: List<StatesHandlerHolder<out I>>
|
||||||
): State? {
|
): State? {
|
||||||
return handlers.firstOrNull { it.checkHandleable(state) } ?.run {
|
return handlers.firstOrNull { it.checkHandleable(state) } ?.run {
|
||||||
handleState(state)
|
handleState(state)
|
||||||
@@ -35,7 +34,7 @@ interface StatesMachine : StatesHandler<State> {
|
|||||||
*/
|
*/
|
||||||
operator fun invoke(
|
operator fun invoke(
|
||||||
statesManager: StatesManager,
|
statesManager: StatesManager,
|
||||||
handlers: List<StateHandlerHolder<*>>
|
handlers: List<StatesHandlerHolder<*>>
|
||||||
) = DefaultStatesMachine(statesManager, handlers)
|
) = DefaultStatesMachine(statesManager, handlers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +45,7 @@ interface StatesMachine : StatesHandler<State> {
|
|||||||
*/
|
*/
|
||||||
class DefaultStatesMachine (
|
class DefaultStatesMachine (
|
||||||
private val statesManager: StatesManager,
|
private val statesManager: StatesManager,
|
||||||
private val handlers: List<StateHandlerHolder<*>>
|
private val handlers: List<StatesHandlerHolder<*>>
|
||||||
) : StatesMachine {
|
) : StatesMachine {
|
||||||
/**
|
/**
|
||||||
* Will call [launchStateHandling] for state handling
|
* Will call [launchStateHandling] for state handling
|
||||||
|
@@ -2,25 +2,27 @@ package dev.inmo.micro_utils.fsm.common.dsl
|
|||||||
|
|
||||||
import dev.inmo.micro_utils.fsm.common.*
|
import dev.inmo.micro_utils.fsm.common.*
|
||||||
import dev.inmo.micro_utils.fsm.common.managers.*
|
import dev.inmo.micro_utils.fsm.common.managers.*
|
||||||
import dev.inmo.micro_utils.fsm.common.managers.InMemoryStatesManager
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
class FSMBuilder(
|
class FSMBuilder(
|
||||||
var statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo())
|
var statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||||
|
var defaultStateHandler: StatesHandler<State>? = StatesHandler { null }
|
||||||
) {
|
) {
|
||||||
private var states = mutableListOf<StateHandlerHolder<*>>()
|
private var states = mutableListOf<StatesHandlerHolder<*>>()
|
||||||
|
|
||||||
fun <I : State> add(kClass: KClass<I>, handler: StatesHandler<I>) {
|
fun <I : State> add(kClass: KClass<I>, handler: StatesHandler<I>) {
|
||||||
states.add(StateHandlerHolder(kClass, false, handler))
|
states.add(StatesHandlerHolder(kClass, false, handler))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <I : State> addStrict(kClass: KClass<I>, handler: StatesHandler<I>) {
|
fun <I : State> addStrict(kClass: KClass<I>, handler: StatesHandler<I>) {
|
||||||
states.add(StateHandlerHolder(kClass, true, handler))
|
states.add(StatesHandlerHolder(kClass, true, handler))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun build() = StatesMachine(
|
fun build() = StatesMachine(
|
||||||
statesManager,
|
statesManager,
|
||||||
states.toList()
|
states.toList().let { list ->
|
||||||
|
defaultStateHandler ?.let { list + it.holder(false) } ?: list
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,11 +10,11 @@ org.gradle.jvmargs=-Xmx2g
|
|||||||
kotlin_version=1.5.31
|
kotlin_version=1.5.31
|
||||||
kotlin_coroutines_version=1.5.2
|
kotlin_coroutines_version=1.5.2
|
||||||
kotlin_serialisation_core_version=1.3.0
|
kotlin_serialisation_core_version=1.3.0
|
||||||
kotlin_exposed_version=0.35.2
|
kotlin_exposed_version=0.35.3
|
||||||
|
|
||||||
ktor_version=1.6.4
|
ktor_version=1.6.5
|
||||||
|
|
||||||
klockVersion=2.4.5
|
klockVersion=2.4.7
|
||||||
|
|
||||||
github_release_plugin_version=2.2.12
|
github_release_plugin_version=2.2.12
|
||||||
|
|
||||||
@@ -45,5 +45,5 @@ dokka_version=1.5.31
|
|||||||
# Project data
|
# Project data
|
||||||
|
|
||||||
group=dev.inmo
|
group=dev.inmo
|
||||||
version=0.7.1
|
version=0.7.5
|
||||||
android_code_version=75
|
android_code_version=79
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
@file:Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
|
||||||
|
|
||||||
package dev.inmo.micro_utils.language_codes
|
package dev.inmo.micro_utils.language_codes
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
@file:Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
|
||||||
|
|
||||||
package dev.inmo.micro_utils.mime_types
|
package dev.inmo.micro_utils.mime_types
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
@@ -16,6 +16,16 @@ suspend fun <T> getAll(
|
|||||||
return results.toList()
|
return results.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun <T, R> R.getAllBy(
|
||||||
|
initialPagination: Pagination = FirstPagePagination(),
|
||||||
|
paginationMapper: R.(PaginationResult<T>) -> Pagination?,
|
||||||
|
block: suspend R.(Pagination) -> PaginationResult<T>
|
||||||
|
): List<T> = getAll(
|
||||||
|
initialPagination,
|
||||||
|
{ paginationMapper(it) },
|
||||||
|
{ block(it) }
|
||||||
|
)
|
||||||
|
|
||||||
suspend fun <T> getAllWithNextPaging(
|
suspend fun <T> getAllWithNextPaging(
|
||||||
initialPagination: Pagination = FirstPagePagination(),
|
initialPagination: Pagination = FirstPagePagination(),
|
||||||
block: suspend (Pagination) -> PaginationResult<T>
|
block: suspend (Pagination) -> PaginationResult<T>
|
||||||
@@ -25,6 +35,14 @@ suspend fun <T> getAllWithNextPaging(
|
|||||||
block
|
block
|
||||||
)
|
)
|
||||||
|
|
||||||
|
suspend fun <T, R> R.getAllByWithNextPaging(
|
||||||
|
initialPagination: Pagination = FirstPagePagination(),
|
||||||
|
block: suspend R.(Pagination) -> PaginationResult<T>
|
||||||
|
): List<T> = getAllWithNextPaging(
|
||||||
|
initialPagination,
|
||||||
|
{ block(it) }
|
||||||
|
)
|
||||||
|
|
||||||
suspend fun <T> getAllWithCurrentPaging(
|
suspend fun <T> getAllWithCurrentPaging(
|
||||||
initialPagination: Pagination = FirstPagePagination(),
|
initialPagination: Pagination = FirstPagePagination(),
|
||||||
block: suspend (Pagination) -> PaginationResult<T>
|
block: suspend (Pagination) -> PaginationResult<T>
|
||||||
@@ -33,3 +51,11 @@ suspend fun <T> getAllWithCurrentPaging(
|
|||||||
{ it.currentPageIfNotEmpty() },
|
{ it.currentPageIfNotEmpty() },
|
||||||
block
|
block
|
||||||
)
|
)
|
||||||
|
|
||||||
|
suspend fun <T, R> R.getAllByWithCurrentPaging(
|
||||||
|
initialPagination: Pagination = FirstPagePagination(),
|
||||||
|
block: suspend R.(Pagination) -> PaginationResult<T>
|
||||||
|
): List<T> = getAllWithCurrentPaging(
|
||||||
|
initialPagination,
|
||||||
|
{ block(it) }
|
||||||
|
)
|
||||||
|
@@ -6,13 +6,15 @@ import dev.inmo.micro_utils.repos.*
|
|||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
|
|
||||||
abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType>(
|
abstract class AbstractMutableAndroidCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||||
helper: StandardSQLHelper
|
helper: StandardSQLHelper,
|
||||||
|
replyInFlows: Int = 0,
|
||||||
|
extraBufferCapacityInFlows: Int = 64
|
||||||
) : WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>,
|
) : WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>,
|
||||||
AbstractAndroidCRUDRepo<ObjectType, IdType>(helper),
|
AbstractAndroidCRUDRepo<ObjectType, IdType>(helper),
|
||||||
StandardCRUDRepo<ObjectType, IdType, InputValueType> {
|
StandardCRUDRepo<ObjectType, IdType, InputValueType> {
|
||||||
protected val newObjectsChannel = MutableSharedFlow<ObjectType>(64)
|
protected val newObjectsChannel = MutableSharedFlow<ObjectType>(replyInFlows, extraBufferCapacityInFlows)
|
||||||
protected val updateObjectsChannel = MutableSharedFlow<ObjectType>(64)
|
protected val updateObjectsChannel = MutableSharedFlow<ObjectType>(replyInFlows, extraBufferCapacityInFlows)
|
||||||
protected val deleteObjectsIdsChannel = MutableSharedFlow<IdType>(64)
|
protected val deleteObjectsIdsChannel = MutableSharedFlow<IdType>(replyInFlows, extraBufferCapacityInFlows)
|
||||||
override val newObjectsFlow: Flow<ObjectType> = newObjectsChannel.asSharedFlow()
|
override val newObjectsFlow: Flow<ObjectType> = newObjectsChannel.asSharedFlow()
|
||||||
override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asSharedFlow()
|
override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asSharedFlow()
|
||||||
override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asSharedFlow()
|
override val deletedObjectsIdsFlow: Flow<IdType> = deleteObjectsIdsChannel.asSharedFlow()
|
||||||
|
@@ -10,15 +10,16 @@ import org.jetbrains.exposed.sql.transactions.transaction
|
|||||||
|
|
||||||
abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
abstract class AbstractExposedWriteCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||||
flowsChannelsSize: Int = 0,
|
flowsChannelsSize: Int = 0,
|
||||||
tableName: String = ""
|
tableName: String = "",
|
||||||
|
replyCacheInFlows: Int = 0
|
||||||
) :
|
) :
|
||||||
AbstractExposedReadCRUDRepo<ObjectType, IdType>(tableName),
|
AbstractExposedReadCRUDRepo<ObjectType, IdType>(tableName),
|
||||||
ExposedCRUDRepo<ObjectType, IdType>,
|
ExposedCRUDRepo<ObjectType, IdType>,
|
||||||
WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>
|
WriteStandardCRUDRepo<ObjectType, IdType, InputValueType>
|
||||||
{
|
{
|
||||||
protected val newObjectsChannel = MutableSharedFlow<ObjectType>(flowsChannelsSize)
|
protected val newObjectsChannel = MutableSharedFlow<ObjectType>(replyCacheInFlows, flowsChannelsSize)
|
||||||
protected val updateObjectsChannel = MutableSharedFlow<ObjectType>(flowsChannelsSize)
|
protected val updateObjectsChannel = MutableSharedFlow<ObjectType>(replyCacheInFlows, flowsChannelsSize)
|
||||||
protected val deleteObjectsIdsChannel = MutableSharedFlow<IdType>(flowsChannelsSize)
|
protected val deleteObjectsIdsChannel = MutableSharedFlow<IdType>(replyCacheInFlows, flowsChannelsSize)
|
||||||
|
|
||||||
override val newObjectsFlow: Flow<ObjectType> = newObjectsChannel.asSharedFlow()
|
override val newObjectsFlow: Flow<ObjectType> = newObjectsChannel.asSharedFlow()
|
||||||
override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asSharedFlow()
|
override val updatedObjectsFlow: Flow<ObjectType> = updateObjectsChannel.asSharedFlow()
|
||||||
|
@@ -19,8 +19,8 @@ open class ExposedKeyValueRepo<Key, Value>(
|
|||||||
valueColumnAllocator,
|
valueColumnAllocator,
|
||||||
tableName
|
tableName
|
||||||
) {
|
) {
|
||||||
private val _onNewValue = MutableSharedFlow<Pair<Key, Value>>()
|
protected val _onNewValue = MutableSharedFlow<Pair<Key, Value>>()
|
||||||
private val _onValueRemoved = MutableSharedFlow<Key>()
|
protected val _onValueRemoved = MutableSharedFlow<Key>()
|
||||||
|
|
||||||
override val onNewValue: Flow<Pair<Key, Value>> = _onNewValue.asSharedFlow()
|
override val onNewValue: Flow<Pair<Key, Value>> = _onNewValue.asSharedFlow()
|
||||||
override val onValueRemoved: Flow<Key> = _onValueRemoved.asSharedFlow()
|
override val onValueRemoved: Flow<Key> = _onValueRemoved.asSharedFlow()
|
||||||
|
@@ -86,3 +86,7 @@ operator fun <T : Any> TypedSerializer<T>.minusAssign(kClass: KClass<T>) {
|
|||||||
inline fun <reified T : Any> TypedSerializer(
|
inline fun <reified T : Any> TypedSerializer(
|
||||||
presetSerializers: Map<String, KSerializer<out T>> = emptyMap()
|
presetSerializers: Map<String, KSerializer<out T>> = emptyMap()
|
||||||
) = TypedSerializer(T::class, presetSerializers)
|
) = TypedSerializer(T::class, presetSerializers)
|
||||||
|
|
||||||
|
inline fun <reified T : Any> TypedSerializer(
|
||||||
|
vararg presetSerializers: Pair<String, KSerializer<out T>>
|
||||||
|
) = TypedSerializer(presetSerializers.toMap())
|
||||||
|
Reference in New Issue
Block a user