diff --git a/gradle.properties b/gradle.properties index fe3c444eb..605d6f609 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,13 +2,14 @@ kotlin.code.style=official org.gradle.jvmargs=-Xmx4g -Dfile.encoding=UTF-8 org.gradle.parallel=true org.gradle.caching=true +org.gradle.configuration-cache=true + # AndroidX package structure to make it clearer which packages are bundled with the # Android operating system, and which are packaged with the app's APK android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true -kotlin.mpp.androidSourceSetLayoutVersion=2 kotlin.mpp.applyDefaultHierarchyTemplate=false # For compatibility with Kotlin 1.9.0, see https://github.com/badoo/Reaktive/issues/697 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f6bcfb43e..611136e55 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,18 +1,14 @@ [versions] kotlin = "1.9.21" -kotlinx-coroutines = "1.7.3" +kotlinx-coroutines = "1.8.0-RC2" detekt = "1.22.0" [libraries] kotlin-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } -kotlin-stdlib-js = { module = "org.jetbrains.kotlin:kotlin-stdlib-js", version.ref = "kotlin" } -kotlin-stdlib-common = { module = "org.jetbrains.kotlin:kotlin-stdlib-common", version.ref = "kotlin" } -kotlin-test-common = { module = "org.jetbrains.kotlin:kotlin-test-common", version.ref = "kotlin" } -kotlin-test-js = { module = "org.jetbrains.kotlin:kotlin-test-js", version.ref = "kotlin" } -kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" } -kotlin-test-annotations = { module = "org.jetbrains.kotlin:kotlin-test-annotations-common", version.ref = "kotlin" } +kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } +kotlin-test-annotations = { module = "org.jetbrains.kotlin:kotlin-test-annotations", version.ref = "kotlin" } kotlinx-compatibility = "org.jetbrains.kotlinx:binary-compatibility-validator:0.13.2" kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } diff --git a/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/JsPlugin.kt b/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/JsPlugin.kt index 8604f007d..f75882988 100644 --- a/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/JsPlugin.kt +++ b/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/JsPlugin.kt @@ -13,7 +13,7 @@ class JsPlugin : Plugin { private fun configureJsCompilation(target: Project) { target.extensions.configure(KotlinMultiplatformExtension::class.java) { - js(IR) { + js { browser { testTask { useKarma { @@ -31,12 +31,12 @@ class JsPlugin : Plugin { } sourceSets.getByName("jsMain") { dependencies { - implementation(project.getLibrary("kotlin-stdlib-js")) + implementation(project.getLibrary("kotlin-stdlib")) } } sourceSets.getByName("jsTest") { dependencies { - implementation(project.getLibrary("kotlin-test-js")) + implementation(project.getLibrary("kotlin-test")) } } } diff --git a/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/MppConfigurationPlugin.kt b/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/MppConfigurationPlugin.kt index 8b379825b..7667bd1d1 100644 --- a/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/MppConfigurationPlugin.kt +++ b/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/MppConfigurationPlugin.kt @@ -27,10 +27,9 @@ class MppConfigurationPlugin : Plugin { target.version = target.findProperty("reaktive_version") as Any target.extensions.configure(KotlinMultiplatformExtension::class.java) { sourceSets { - maybeCreate("commonMain").dependencies { implementation(target.getLibrary("kotlin-stdlib-common")) } + maybeCreate("commonMain").dependencies { implementation(target.getLibrary("kotlin-stdlib")) } maybeCreate("commonTest").dependencies { - implementation(target.getLibrary("kotlin-test-common")) - implementation(target.getLibrary("kotlin-test-annotations")) + implementation(target.getLibrary("kotlin-test")) } } @@ -48,6 +47,7 @@ class MppConfigurationPlugin : Plugin { setupAndroidTarget(project) setupJvmTarget(project) setupJsTarget(project) + setupWasmJsTarget(project) setupLinuxX64Target(project) setupIosTargets(project) @@ -80,8 +80,14 @@ class MppConfigurationPlugin : Plugin { maybeCreate("androidMain").dependsOn(getByName("jvmCommonMain")) maybeCreate("androidUnitTest").dependsOn(getByName("jvmCommonTest")) - maybeCreate("jsMain").dependsOn(getByName("jvmJsCommonMain")) - maybeCreate("jsTest").dependsOn(getByName("jvmJsCommonTest")) + maybeCreate("jsCommonMain").dependsOn(getByName("jvmJsCommonMain")) + maybeCreate("jsCommonTest").dependsOn(getByName("jvmJsCommonTest")) + + maybeCreate("jsMain").dependsOn(getByName("jsCommonMain")) + maybeCreate("jsTest").dependsOn(getByName("jsCommonTest")) + + maybeCreate("wasmJsMain").dependsOn(getByName("jsCommonMain")) + maybeCreate("wasmJsTest").dependsOn(getByName("jsCommonTest")) maybeCreate("nativeCommonMain").dependsOn(getByName("jvmNativeCommonMain")) maybeCreate("nativeCommonTest").dependsOn(getByName("jvmNativeCommonTest")) @@ -162,7 +168,7 @@ class MppConfigurationPlugin : Plugin { } sourceSets { maybeCreate("androidMain").dependencies { implementation(project.getLibrary("kotlin-stdlib")) } - maybeCreate("androidUnitTest").dependencies { implementation(project.getLibrary("kotlin-test-junit")) } + maybeCreate("androidUnitTest").dependencies { implementation(project.getLibrary("kotlin-test")) } } } } @@ -179,7 +185,7 @@ class MppConfigurationPlugin : Plugin { } sourceSets { maybeCreate("jvmMain").dependencies { implementation(project.getLibrary("kotlin-stdlib")) } - maybeCreate("jvmTest").dependencies { implementation(project.getLibrary("kotlin-test-junit")) } + maybeCreate("jvmTest").dependencies { implementation(project.getLibrary("kotlin-test")) } } } } @@ -188,6 +194,10 @@ class MppConfigurationPlugin : Plugin { project.apply() } + private fun setupWasmJsTarget(project: Project) { + project.apply() + } + private fun setupLinuxX64Target(project: Project) { project.kotlin { linuxX64 { diff --git a/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/Target.kt b/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/Target.kt index 3083f5757..e75af2cfc 100644 --- a/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/Target.kt +++ b/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/Target.kt @@ -13,6 +13,7 @@ enum class Target( ALL_LINUX_HOSTED(linuxHosted = true, macOsHosted = false), JVM(linuxHosted = true, macOsHosted = false), JS(linuxHosted = true, macOsHosted = false), + WASM_JS(linuxHosted = true, macOsHosted = false), LINUX(linuxHosted = true, macOsHosted = false), ALL_MACOS_HOSTED(linuxHosted = false, macOsHosted = true), IOS(linuxHosted = false, macOsHosted = true), diff --git a/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/WasmJsPlugin.kt b/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/WasmJsPlugin.kt new file mode 100644 index 000000000..d8b5178dc --- /dev/null +++ b/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/configuration/WasmJsPlugin.kt @@ -0,0 +1,34 @@ +package com.badoo.reaktive.configuration + +import com.badoo.reaktive.getLibrary +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl + +@OptIn(ExperimentalWasmDsl::class) +class WasmJsPlugin : Plugin { + + override fun apply(target: Project) { + configureWasmJsCompilation(target) + } + + private fun configureWasmJsCompilation(target: Project) { + target.extensions.configure(KotlinMultiplatformExtension::class.java) { + wasmJs { + browser() + disableIfUndefined(Target.WASM_JS) + } + sourceSets.getByName("wasmJsMain") { + dependencies { + implementation(project.getLibrary("kotlin-stdlib")) + } + } + sourceSets.getByName("wasmJsTest") { + dependencies { + implementation(project.getLibrary("kotlin-test")) + } + } + } + } +} diff --git a/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/publish/PublishConfigurationPlugin.kt b/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/publish/PublishConfigurationPlugin.kt index 042dcd3ab..60726094d 100644 --- a/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/publish/PublishConfigurationPlugin.kt +++ b/includedBuild/gradleConfiguration/src/main/kotlin/com/badoo/reaktive/publish/PublishConfigurationPlugin.kt @@ -128,6 +128,7 @@ class PublishConfigurationPlugin : Plugin { KotlinMultiplatformPlugin.METADATA_TARGET_NAME to Target.shouldPublishTarget(project, Target.META), "jvm" to Target.shouldPublishTarget(project, Target.JVM), "js" to Target.shouldPublishTarget(project, Target.JS), + "wasmJs" to Target.shouldPublishTarget(project, Target.WASM_JS), "androidDebug" to Target.shouldPublishTarget(project, Target.JVM), "androidRelease" to Target.shouldPublishTarget(project, Target.JVM), "linuxX64" to Target.shouldPublishTarget(project, Target.LINUX), diff --git a/reaktive-testing/src/commonMain/kotlin/com/badoo/reaktive/test/single/AsyncTestResult.kt b/reaktive-testing/src/commonMain/kotlin/com/badoo/reaktive/test/single/AsyncTestResult.kt new file mode 100644 index 000000000..861775c7d --- /dev/null +++ b/reaktive-testing/src/commonMain/kotlin/com/badoo/reaktive/test/single/AsyncTestResult.kt @@ -0,0 +1,3 @@ +package com.badoo.reaktive.test.single + +expect class AsyncTestResult diff --git a/reaktive-testing/src/commonMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt b/reaktive-testing/src/commonMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt index 88533eb54..7277131ba 100644 --- a/reaktive-testing/src/commonMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt +++ b/reaktive-testing/src/commonMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt @@ -50,4 +50,4 @@ import com.badoo.reaktive.single.Single * @param assertSuccess when provided, it will be called in case of [Single] success. * This gives an opportunity to assert the result. */ -expect fun Single.testAwait(assertError: ((Throwable) -> Unit)? = null, assertSuccess: (T) -> Unit) +expect fun Single.testAwait(assertError: ((Throwable) -> Unit)? = null, assertSuccess: (T) -> Unit): AsyncTestResult diff --git a/reaktive-testing/src/commonTest/kotlin/com/badoo/reaktive/test/single/TestAwaitTest.kt b/reaktive-testing/src/commonTest/kotlin/com/badoo/reaktive/test/single/TestAwaitTest.kt index 52040e97e..1f64ee34f 100644 --- a/reaktive-testing/src/commonTest/kotlin/com/badoo/reaktive/test/single/TestAwaitTest.kt +++ b/reaktive-testing/src/commonTest/kotlin/com/badoo/reaktive/test/single/TestAwaitTest.kt @@ -19,7 +19,7 @@ class TestAwaitTest { .testAwait(assertSuccess = { assertEquals(1, it) }) @Test - fun succeeds_WHEN_upstream_failed_and_assertError_did_not_throw() { + fun succeeds_WHEN_upstream_failed_and_assertError_did_not_throw(): AsyncTestResult { val error = Exception() return singleOfError(error) diff --git a/reaktive-testing/src/jsMain/kotlin/com/badoo/reaktive/test/single/AsyncTestResult.kt b/reaktive-testing/src/jsMain/kotlin/com/badoo/reaktive/test/single/AsyncTestResult.kt new file mode 100644 index 000000000..a50a37da4 --- /dev/null +++ b/reaktive-testing/src/jsMain/kotlin/com/badoo/reaktive/test/single/AsyncTestResult.kt @@ -0,0 +1,7 @@ +package com.badoo.reaktive.test.single + +@Suppress("UnusedPrivateMember") +@JsName("Promise") +actual external class AsyncTestResult( + executor: (resolve: (Unit) -> Unit, reject: (Throwable) -> Unit) -> Unit, +) diff --git a/reaktive-testing/src/jsMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt b/reaktive-testing/src/jsMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt index f7fb98e8e..9e018e12d 100644 --- a/reaktive-testing/src/jsMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt +++ b/reaktive-testing/src/jsMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt @@ -1,15 +1,15 @@ package com.badoo.reaktive.test.single import com.badoo.reaktive.single.Single -import com.badoo.reaktive.single.asPromise import com.badoo.reaktive.single.doOnBeforeSuccess import com.badoo.reaktive.single.map import com.badoo.reaktive.single.onErrorReturn +import com.badoo.reaktive.single.subscribe -actual fun Single.testAwait(assertError: ((Throwable) -> Unit)?, assertSuccess: (T) -> Unit): dynamic = +actual fun Single.testAwait(assertError: ((Throwable) -> Unit)?, assertSuccess: (T) -> Unit): AsyncTestResult = if (assertError == null) { doOnBeforeSuccess(assertSuccess) - .asPromise() + .asTestResult() } else { map { TestAwaitResult.Success(it) } .onErrorReturn { TestAwaitResult.Error(it) } @@ -19,7 +19,15 @@ actual fun Single.testAwait(assertError: ((Throwable) -> Unit)?, assertSu is TestAwaitResult.Error -> assertError(result.error) } } - .asPromise() + .asTestResult() + } + +private fun Single.asTestResult(): AsyncTestResult = + AsyncTestResult { resolve, reject -> + subscribe( + onSuccess = { resolve(Unit) }, + onError = reject, + ) } private sealed class TestAwaitResult { diff --git a/reaktive-testing/src/jvmNativeCommonMain/kotlin/com/badoo/reaktive/test/single/AsyncTestResult.kt b/reaktive-testing/src/jvmNativeCommonMain/kotlin/com/badoo/reaktive/test/single/AsyncTestResult.kt new file mode 100644 index 000000000..f6da6d313 --- /dev/null +++ b/reaktive-testing/src/jvmNativeCommonMain/kotlin/com/badoo/reaktive/test/single/AsyncTestResult.kt @@ -0,0 +1,4 @@ +package com.badoo.reaktive.test.single + +@Suppress("ACTUAL_WITHOUT_EXPECT") // We never instantiate TestResult, see https://youtrack.jetbrains.com/issue/KT-64199 +actual typealias AsyncTestResult = Unit diff --git a/reaktive-testing/src/jvmNativeCommonMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt b/reaktive-testing/src/jvmNativeCommonMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt index a7ac5e6f0..907a4cfff 100644 --- a/reaktive-testing/src/jvmNativeCommonMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt +++ b/reaktive-testing/src/jvmNativeCommonMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt @@ -17,4 +17,6 @@ actual fun Single.testAwait(assertError: ((Throwable) -> Unit)?, assertSu assertSuccess(result) } + + return } diff --git a/reaktive-testing/src/wasmJsMain/kotlin/com/badoo/reaktive/test/single/AsyncTestResult.kt b/reaktive-testing/src/wasmJsMain/kotlin/com/badoo/reaktive/test/single/AsyncTestResult.kt new file mode 100644 index 000000000..779973e71 --- /dev/null +++ b/reaktive-testing/src/wasmJsMain/kotlin/com/badoo/reaktive/test/single/AsyncTestResult.kt @@ -0,0 +1,7 @@ +package com.badoo.reaktive.test.single + +@Suppress("UnusedPrivateMember") +@JsName("Promise") +actual external class AsyncTestResult( + executor: (resolve: (JsAny) -> Unit, reject: (JsAny) -> Unit) -> Unit, +) diff --git a/reaktive-testing/src/wasmJsMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt b/reaktive-testing/src/wasmJsMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt new file mode 100644 index 000000000..4d1d9302e --- /dev/null +++ b/reaktive-testing/src/wasmJsMain/kotlin/com/badoo/reaktive/test/single/TestAwait.kt @@ -0,0 +1,36 @@ +package com.badoo.reaktive.test.single + +import com.badoo.reaktive.single.Single +import com.badoo.reaktive.single.doOnBeforeSuccess +import com.badoo.reaktive.single.map +import com.badoo.reaktive.single.onErrorReturn +import com.badoo.reaktive.single.subscribe + +actual fun Single.testAwait(assertError: ((Throwable) -> Unit)?, assertSuccess: (T) -> Unit): AsyncTestResult = + if (assertError == null) { + doOnBeforeSuccess(assertSuccess) + .asTestResult() + } else { + map { TestAwaitResult.Success(it) } + .onErrorReturn { TestAwaitResult.Error(it) } + .doOnBeforeSuccess { result -> + when (result) { + is TestAwaitResult.Success -> assertSuccess(result.value) + is TestAwaitResult.Error -> assertError(result.error) + } + } + .asTestResult() + } + +private fun Single.asTestResult(): AsyncTestResult = + AsyncTestResult { resolve, reject -> + subscribe( + onSuccess = { resolve(Unit.toJsReference()) }, + onError = { reject(it.toJsReference()) }, + ) + } + +private sealed class TestAwaitResult { + class Success(val value: T) : TestAwaitResult() + class Error(val error: Throwable) : TestAwaitResult() +} diff --git a/reaktive/src/commonTest/kotlin/com/badoo/reaktive/observable/RepeatWhenTest.kt b/reaktive/src/commonTest/kotlin/com/badoo/reaktive/observable/RepeatWhenTest.kt index d593b61c1..2c48bb519 100644 --- a/reaktive/src/commonTest/kotlin/com/badoo/reaktive/observable/RepeatWhenTest.kt +++ b/reaktive/src/commonTest/kotlin/com/badoo/reaktive/observable/RepeatWhenTest.kt @@ -170,8 +170,8 @@ class RepeatWhenTest : ObservableToObservableTests by ObservableToObservableTest .test() upstream.onComplete() - assertSame(timeRef, 1) + assertEquals(timeRef, 1) upstream.onComplete() - assertSame(timeRef, 2) + assertEquals(timeRef, 2) } } diff --git a/reaktive/src/commonTest/kotlin/com/badoo/reaktive/single/RepeatWhenTest.kt b/reaktive/src/commonTest/kotlin/com/badoo/reaktive/single/RepeatWhenTest.kt index 3ebb7a9d5..a2606fb34 100644 --- a/reaktive/src/commonTest/kotlin/com/badoo/reaktive/single/RepeatWhenTest.kt +++ b/reaktive/src/commonTest/kotlin/com/badoo/reaktive/single/RepeatWhenTest.kt @@ -190,8 +190,8 @@ class RepeatWhenTest : SingleToObservableTests by SingleToObservableTestsImpl({ .test() upstream.onComplete() - assertSame(attemptVar, 1) + assertEquals(attemptVar, 1) upstream.onComplete() - assertSame(attemptVar, 2) + assertEquals(attemptVar, 2) } } diff --git a/reaktive/src/commonTest/kotlin/com/badoo/reaktive/subject/SubjectGenericTests.kt b/reaktive/src/commonTest/kotlin/com/badoo/reaktive/subject/SubjectGenericTests.kt index e49f426ba..fe1f0aada 100644 --- a/reaktive/src/commonTest/kotlin/com/badoo/reaktive/subject/SubjectGenericTests.kt +++ b/reaktive/src/commonTest/kotlin/com/badoo/reaktive/subject/SubjectGenericTests.kt @@ -120,7 +120,7 @@ private class SubjectGenericTestsImpl( subject.onNext(0) subject.onComplete() - observers.forEach(TestObservableObserver<*>::assertComplete) + observers.forEach { it.assertComplete() } } override fun delivers_error_to_all_observers_WHEN_error_produced() { diff --git a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/base/exceptions/CompositeException.kt b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/base/exceptions/CompositeException.kt similarity index 100% rename from reaktive/src/jsMain/kotlin/com/badoo/reaktive/base/exceptions/CompositeException.kt rename to reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/base/exceptions/CompositeException.kt diff --git a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/disposable/Various.kt b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/disposable/Various.kt similarity index 96% rename from reaktive/src/jsMain/kotlin/com/badoo/reaktive/disposable/Various.kt rename to reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/disposable/Various.kt index 8d3f9cdd5..d3d2f9e29 100644 --- a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/disposable/Various.kt +++ b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/disposable/Various.kt @@ -1,5 +1,7 @@ package com.badoo.reaktive.disposable +import kotlin.js.JsName + @JsName("disposableWithCallback") @Suppress("FunctionName") actual inline fun Disposable(crossinline onDispose: () -> Unit): Disposable = diff --git a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/CreateComputationScheduler.kt b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/CreateComputationScheduler.kt similarity index 100% rename from reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/CreateComputationScheduler.kt rename to reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/CreateComputationScheduler.kt diff --git a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/CreateIoScheduler.kt b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/CreateIoScheduler.kt similarity index 100% rename from reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/CreateIoScheduler.kt rename to reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/CreateIoScheduler.kt diff --git a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/CreateMainScheduler.kt b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/CreateMainScheduler.kt similarity index 100% rename from reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/CreateMainScheduler.kt rename to reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/CreateMainScheduler.kt diff --git a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/CreateNewThreadScheduler.kt b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/CreateNewThreadScheduler.kt similarity index 100% rename from reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/CreateNewThreadScheduler.kt rename to reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/CreateNewThreadScheduler.kt diff --git a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/CreateSingleScheduler.kt b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/CreateSingleScheduler.kt similarity index 100% rename from reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/CreateSingleScheduler.kt rename to reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/CreateSingleScheduler.kt diff --git a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/CreateTrampolineScheduler.kt b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/CreateTrampolineScheduler.kt similarity index 100% rename from reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/CreateTrampolineScheduler.kt rename to reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/CreateTrampolineScheduler.kt diff --git a/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/JsFunctions.kt b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/JsFunctions.kt new file mode 100644 index 000000000..ba3a4889d --- /dev/null +++ b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/JsFunctions.kt @@ -0,0 +1,9 @@ +package com.badoo.reaktive.scheduler + +internal expect fun jsSetTimeout(task: () -> Unit, delayMillis: Int): TimeoutId + +internal expect fun jsSetInterval(task: () -> Unit, delayMillis: Int): TimeoutId + +internal expect fun jsClearTimeout(id: TimeoutId) + +internal expect fun jsClearInterval(id: TimeoutId) diff --git a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/MainScheduler.kt b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/MainScheduler.kt similarity index 61% rename from reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/MainScheduler.kt rename to reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/MainScheduler.kt index af1abc163..6d878c020 100644 --- a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/MainScheduler.kt +++ b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/MainScheduler.kt @@ -3,7 +3,6 @@ package com.badoo.reaktive.scheduler import com.badoo.reaktive.disposable.CompositeDisposable import com.badoo.reaktive.disposable.minusAssign import com.badoo.reaktive.disposable.plusAssign -import com.badoo.reaktive.global.external.globalThis import com.badoo.reaktive.utils.coerceAtLeastZero import kotlin.time.Duration @@ -16,13 +15,13 @@ internal class MainScheduler : Scheduler { override fun destroy() = disposables.dispose() private class MainThreadExecutor( - private val disposables: CompositeDisposable + private val disposables: CompositeDisposable, ) : Scheduler.Executor { private var _isDisposed = false - private val timeoutIds = mutableSetOf() - private val intervalIds = mutableSetOf() + private val timeoutIds = mutableSetOf() + private val intervalIds = mutableSetOf() init { disposables += this @@ -49,38 +48,31 @@ internal class MainScheduler : Scheduler { } private fun setTimeout(delay: Duration, task: () -> Unit) { - var id: dynamic = undefined - - id = - globalThis.setTimeout( - { - timeoutIds.remove(id) - task() - }, - delay.coerceAtLeastZero().inWholeMilliseconds.toInt(), - ) + var timeoutId: TimeoutId? = null + + timeoutId = jsSetTimeout( + task = { + timeoutIds.remove(timeoutId) + task() + }, + delayMillis = delay.coerceAtLeastZero().inWholeMilliseconds.toInt() + ) - timeoutIds.add(id) + timeoutIds.add(timeoutId) } private fun setInterval(period: Duration, task: () -> Unit) { - var id: dynamic = undefined - - id = - globalThis.setInterval( - { - intervalIds.remove(id) - task() - }, - period.coerceAtLeastZero().inWholeMilliseconds.toInt(), + intervalIds.add( + jsSetInterval( + task = task, + delayMillis = period.coerceAtLeastZero().inWholeMilliseconds.toInt(), ) - - intervalIds.add(id) + ) } override fun cancel() { - timeoutIds.forEach { globalThis.clearTimeout(it) } - intervalIds.forEach { globalThis.clearInterval(it) } + timeoutIds.forEach { jsClearTimeout(it) } + intervalIds.forEach { jsClearInterval(it) } } override val isDisposed: Boolean diff --git a/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/TimeoutId.kt b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/TimeoutId.kt new file mode 100644 index 000000000..1301ebc0b --- /dev/null +++ b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/scheduler/TimeoutId.kt @@ -0,0 +1,3 @@ +package com.badoo.reaktive.scheduler + +internal expect class TimeoutId diff --git a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/utils/CreateDefaultUncaughtErrorHandler.kt b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/CreateDefaultUncaughtErrorHandler.kt similarity index 100% rename from reaktive/src/jsMain/kotlin/com/badoo/reaktive/utils/CreateDefaultUncaughtErrorHandler.kt rename to reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/CreateDefaultUncaughtErrorHandler.kt diff --git a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/utils/SynchronizedCompat.kt b/reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/SynchronizedCompat.kt similarity index 100% rename from reaktive/src/jsMain/kotlin/com/badoo/reaktive/utils/SynchronizedCompat.kt rename to reaktive/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/SynchronizedCompat.kt diff --git a/reaktive/src/jsCommonTest/kotlin/com/badoo/reaktive/scheduler/MainSchedulerTest.kt b/reaktive/src/jsCommonTest/kotlin/com/badoo/reaktive/scheduler/MainSchedulerTest.kt new file mode 100644 index 000000000..da2069e72 --- /dev/null +++ b/reaktive/src/jsCommonTest/kotlin/com/badoo/reaktive/scheduler/MainSchedulerTest.kt @@ -0,0 +1,80 @@ +package com.badoo.reaktive.scheduler + +import com.badoo.reaktive.observable.flatMapSingle +import com.badoo.reaktive.observable.observableOf +import com.badoo.reaktive.observable.toList +import com.badoo.reaktive.single.doOnBeforeFinally +import com.badoo.reaktive.single.map +import com.badoo.reaktive.single.singleTimer +import com.badoo.reaktive.test.single.AsyncTestResult +import com.badoo.reaktive.test.single.testAwait +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue +import kotlin.time.Duration.Companion.milliseconds + +class MainSchedulerTest { + @Test + fun submits_task_to_executor() { + val scheduler = MainScheduler() + val executor = scheduler.newExecutor() + executor.submit {} + } + + @Test + fun delayed_task_executed_with_delay(): AsyncTestResult { + val scheduler = MainScheduler() + val executor = scheduler.newExecutor() + var executed = false + executor.submit(200.milliseconds) { executed = true } + + return observableOf(100.milliseconds, 300.milliseconds) + .flatMapSingle { timeout -> + singleTimer(timeout, scheduler = scheduler) + .map { executed } + } + .toList() + .testAwait { (before, after) -> + assertFalse(before) + assertTrue(after) + } + } + + @Test + fun interval_task_executed_at_interval(): AsyncTestResult { + val scheduler = MainScheduler() + val executor = scheduler.newExecutor() + var counter = 0 + val items = mutableListOf() + + executor.submit(period = 100.milliseconds) { + items.add(counter++) + } + + val checkTicks = + observableOf(50.milliseconds, 150.milliseconds, 250.milliseconds, 350.milliseconds, 450.milliseconds) + .flatMapSingle { timeout -> + singleTimer(timeout, scheduler = scheduler) + .map { items.toList() } + } + + val expectedResults = + listOf( + emptyList(), + listOf(0), + listOf(0, 1), + listOf(0, 1, 2), + listOf(0, 1, 2, 3), + ) + + return checkTicks + .toList() + // Required to pass test on NodeJS environment since runtime waits + // for all tasks to cancel or finish their work. + .doOnBeforeFinally(executor::cancel) + .testAwait { results -> + assertEquals(expectedResults, results) + } + } +} diff --git a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/JsFunctions.kt b/reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/JsFunctions.kt new file mode 100644 index 000000000..ce84e7aff --- /dev/null +++ b/reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/JsFunctions.kt @@ -0,0 +1,17 @@ +package com.badoo.reaktive.scheduler + +import com.badoo.reaktive.global.external.globalThis + +internal actual fun jsSetTimeout(task: () -> Unit, delayMillis: Int): TimeoutId = + TimeoutId(globalThis.setTimeout(task, delayMillis)) + +internal actual fun jsSetInterval(task: () -> Unit, delayMillis: Int): TimeoutId = + TimeoutId(globalThis.setInterval(task, delayMillis)) + +internal actual fun jsClearTimeout(id: TimeoutId) { + globalThis.clearTimeout(id.id) +} + +internal actual fun jsClearInterval(id: TimeoutId) { + globalThis.clearInterval(id.id) +} diff --git a/reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/TimeoutId.kt b/reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/TimeoutId.kt new file mode 100644 index 000000000..2dc417a7b --- /dev/null +++ b/reaktive/src/jsMain/kotlin/com/badoo/reaktive/scheduler/TimeoutId.kt @@ -0,0 +1,3 @@ +package com.badoo.reaktive.scheduler + +internal actual class TimeoutId(val id: dynamic) diff --git a/reaktive/src/jsTest/kotlin/com/badoo/reaktive/scheduler/MainSchedulerTest.kt b/reaktive/src/jsTest/kotlin/com/badoo/reaktive/scheduler/MainSchedulerTest.kt deleted file mode 100644 index 78cb96b04..000000000 --- a/reaktive/src/jsTest/kotlin/com/badoo/reaktive/scheduler/MainSchedulerTest.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.badoo.reaktive.scheduler - -import kotlin.test.Test - -class MainSchedulerTest { - @Test - fun submits_task_to_executor() { - val scheduler = MainScheduler() - val executor = scheduler.newExecutor() - executor.submit {} - } -} diff --git a/reaktive/src/wasmJsMain/kotlin/com/badoo/reaktive/scheduler/JsFunctions.kt b/reaktive/src/wasmJsMain/kotlin/com/badoo/reaktive/scheduler/JsFunctions.kt new file mode 100644 index 000000000..45f6bbfe3 --- /dev/null +++ b/reaktive/src/wasmJsMain/kotlin/com/badoo/reaktive/scheduler/JsFunctions.kt @@ -0,0 +1,17 @@ +package com.badoo.reaktive.scheduler + +import kotlinx.browser.window + +internal actual fun jsSetTimeout(task: () -> Unit, delayMillis: Int): TimeoutId = + window.setTimeout({ task().toJsReference() }, delayMillis) + +internal actual fun jsSetInterval(task: () -> Unit, delayMillis: Int): TimeoutId = + window.setInterval({ task().toJsReference() }, delayMillis) + +internal actual fun jsClearTimeout(id: TimeoutId) { + window.clearTimeout(id) +} + +internal actual fun jsClearInterval(id: TimeoutId) { + window.clearInterval(id) +} diff --git a/reaktive/src/wasmJsMain/kotlin/com/badoo/reaktive/scheduler/TimeoutId.kt b/reaktive/src/wasmJsMain/kotlin/com/badoo/reaktive/scheduler/TimeoutId.kt new file mode 100644 index 000000000..23755e218 --- /dev/null +++ b/reaktive/src/wasmJsMain/kotlin/com/badoo/reaktive/scheduler/TimeoutId.kt @@ -0,0 +1,5 @@ +package com.badoo.reaktive.scheduler + +// Required until Kotlin 2.0.0 https://youtrack.jetbrains.com/issue/KT-37316 +@Suppress("ACTUAL_WITHOUT_EXPECT") +internal actual typealias TimeoutId = Int diff --git a/reaktive/src/wasmJsMain/kotlin/com/badoo/reaktive/utils/PrintError.kt b/reaktive/src/wasmJsMain/kotlin/com/badoo/reaktive/utils/PrintError.kt new file mode 100644 index 000000000..bb1627b40 --- /dev/null +++ b/reaktive/src/wasmJsMain/kotlin/com/badoo/reaktive/utils/PrintError.kt @@ -0,0 +1,14 @@ +package com.badoo.reaktive.utils + +internal actual fun printError(error: Any?) { + when (error) { + is Throwable -> error.printStackTrace() + is String -> actualPrint(error) + else -> actualPrint(error.toString()) + } +} + +@Suppress("UnusedPrivateMember") +private fun actualPrint(str: String) { + js("console.log(str)") +} diff --git a/sample-js-browser-app/build.gradle b/sample-js-browser-app/build.gradle deleted file mode 100644 index ace9331e2..000000000 --- a/sample-js-browser-app/build.gradle +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Use the following Gradle tasks to run your application: - * :jsBrowserProductionRun - release mode - * :jsBrowserDevelopmentRun - debug mode - */ - -plugins { - id 'kotlin-multiplatform' -} - -kotlin { - js(IR) { - browser() - binaries.executable() - } - - sourceSets { - jsMain { - dependencies { - implementation project(':reaktive') - implementation project(':sample-mpp-module') - } - } - } -} diff --git a/sample-js-browser-app/build.gradle.kts b/sample-js-browser-app/build.gradle.kts new file mode 100644 index 000000000..614cb04c0 --- /dev/null +++ b/sample-js-browser-app/build.gradle.kts @@ -0,0 +1,31 @@ +/* + * Use the following Gradle tasks to run your application: + * :jsBrowserProductionRun - release mode JS + * :jsBrowserDevelopmentRun - debug mode JS + * :wasmJsBrowserProductionRun - release mode WASM-JS + * :wasmJsBrowserDevelopmentRun - debug mode WASM-JS + */ +import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl + +plugins { + id("kotlin-multiplatform") +} + +kotlin { + js { + browser() + binaries.executable() + } + @OptIn(ExperimentalWasmDsl::class) + wasmJs { + binaries.executable() + browser() + } + + sourceSets { + commonMain.dependencies { + implementation(project(":reaktive")) + implementation(project(":sample-mpp-module")) + } + } +} diff --git a/sample-js-browser-app/src/jsMain/resources/favicon.ico b/sample-js-browser-app/src/commonMain/resources/favicon.ico similarity index 100% rename from sample-js-browser-app/src/jsMain/resources/favicon.ico rename to sample-js-browser-app/src/commonMain/resources/favicon.ico diff --git a/sample-js-browser-app/src/jsMain/resources/index.html b/sample-js-browser-app/src/commonMain/resources/index.html similarity index 85% rename from sample-js-browser-app/src/jsMain/resources/index.html rename to sample-js-browser-app/src/commonMain/resources/index.html index cec8abc4e..bc032195c 100644 --- a/sample-js-browser-app/src/jsMain/resources/index.html +++ b/sample-js-browser-app/src/commonMain/resources/index.html @@ -18,6 +18,8 @@ + +
diff --git a/sample-js-browser-app/src/jsMain/kotlin/com/badoo/main.kt b/sample-js-browser-app/src/jsMain/kotlin/com/badoo/main.kt index e7b1c3c1d..1232943f3 100644 --- a/sample-js-browser-app/src/jsMain/kotlin/com/badoo/main.kt +++ b/sample-js-browser-app/src/jsMain/kotlin/com/badoo/main.kt @@ -2,24 +2,25 @@ package com.badoo import com.badoo.reaktive.samplemppmodule.Counter import com.badoo.reaktive.samplemppmodule.Counter.Event -import com.badoo.reaktive.observable.subscribe import kotlinx.browser.document import org.w3c.dom.HTMLElement +import kotlin.time.Duration.Companion.seconds fun main() { document.addEventListener(type = "DOMContentLoaded", callback = { onLoaded() }) } private fun onLoaded() { - console.log("Loaded") val counter = Counter() - val valueText = document.getElementById("value") as HTMLElement - val loader = document.getElementById("loader") as HTMLElement - val incrementButton = document.getElementById("button-increment") as HTMLElement - val decrementButton = document.getElementById("button-decrement") as HTMLElement + val valueText = document.getElementById("value") as HTMLElement + val loader = document.getElementById("loader") as HTMLElement + val incrementButton = document.getElementById("button-increment") as HTMLElement + val decrementButton = document.getElementById("button-decrement") as HTMLElement val resetButton = document.getElementById("button-reset") as HTMLElement - val fibonacciButton = document.getElementById("button-fibonacci") as HTMLElement + val fibonacciButton = document.getElementById("button-fibonacci") as HTMLElement + val increaseAfter1s = document.getElementById("button-increase-after-1s") as HTMLElement + val increaseEvery1s = document.getElementById("button-increase-every-1s") as HTMLElement counter.state.subscribe { state -> valueText.innerHTML = state.value.toString() @@ -30,4 +31,12 @@ private fun onLoaded() { decrementButton.onclick = { counter.onEvent(Event.Decrement) } resetButton.onclick = { counter.onEvent(Event.Reset) } fibonacciButton.onclick = { counter.onEvent(Event.Fibonacci) } + + increaseAfter1s.onclick = { + counter.onEvent(Event.IncrementAfter(1.seconds)) + } + + increaseEvery1s.onclick = { + counter.onEvent(Event.IncrementEvery(1.seconds)) + } } diff --git a/sample-js-browser-app/src/wasmJsMain/kotlin/com/badoo/main.kt b/sample-js-browser-app/src/wasmJsMain/kotlin/com/badoo/main.kt new file mode 100644 index 000000000..c2bc9832b --- /dev/null +++ b/sample-js-browser-app/src/wasmJsMain/kotlin/com/badoo/main.kt @@ -0,0 +1,39 @@ +package com.badoo + +import com.badoo.reaktive.samplemppmodule.Counter +import com.badoo.reaktive.samplemppmodule.Counter.Event +import kotlinx.browser.document +import org.w3c.dom.HTMLElement +import kotlin.time.Duration.Companion.seconds + +fun main() { + val counter = Counter() + + val valueText = document.getElementById("value") as HTMLElement + val loader = document.getElementById("loader") as HTMLElement + val incrementButton = document.getElementById("button-increment") as HTMLElement + val decrementButton = document.getElementById("button-decrement") as HTMLElement + val resetButton = document.getElementById("button-reset") as HTMLElement + val fibonacciButton = document.getElementById("button-fibonacci") as HTMLElement + val increaseAfter1s = document.getElementById("button-increase-after-1s") as HTMLElement + val increaseEvery1s = document.getElementById("button-increase-every-1s") as HTMLElement + + counter.state.subscribe { state -> + valueText.innerHTML = state.value.toString() + loader.hidden = !state.isLoading + } + + incrementButton.onclick = { counter.onEvent(Event.Increment) } + decrementButton.onclick = { counter.onEvent(Event.Decrement) } + resetButton.onclick = { counter.onEvent(Event.Reset) } + fibonacciButton.onclick = { counter.onEvent(Event.Fibonacci) } + + increaseAfter1s.onclick = { + counter.onEvent(Event.IncrementAfter(1.seconds)) + } + + increaseEvery1s.onclick = { + counter.onEvent(Event.IncrementEvery(1.seconds)) + } +} + diff --git a/sample-mpp-module/src/commonMain/kotlin/com/badoo/reaktive/samplemppmodule/Counter.kt b/sample-mpp-module/src/commonMain/kotlin/com/badoo/reaktive/samplemppmodule/Counter.kt index e07b84870..5d27ab618 100644 --- a/sample-mpp-module/src/commonMain/kotlin/com/badoo/reaktive/samplemppmodule/Counter.kt +++ b/sample-mpp-module/src/commonMain/kotlin/com/badoo/reaktive/samplemppmodule/Counter.kt @@ -4,16 +4,20 @@ import com.badoo.reaktive.base.invoke import com.badoo.reaktive.disposable.scope.DisposableScope import com.badoo.reaktive.observable.BehaviorObservableWrapper import com.badoo.reaktive.observable.Observable +import com.badoo.reaktive.observable.doOnAfterNext import com.badoo.reaktive.observable.map import com.badoo.reaktive.observable.observableFromFunction +import com.badoo.reaktive.observable.observableInterval import com.badoo.reaktive.observable.observableOf import com.badoo.reaktive.observable.observableOfEmpty +import com.badoo.reaktive.observable.observableTimer import com.badoo.reaktive.observable.observeOn import com.badoo.reaktive.observable.startWithValue import com.badoo.reaktive.observable.subscribeOn import com.badoo.reaktive.observable.wrap import com.badoo.reaktive.scheduler.computationScheduler import com.badoo.reaktive.scheduler.mainScheduler +import kotlin.time.Duration class Counter : DisposableScope by DisposableScope() { @@ -27,7 +31,8 @@ class Counter : DisposableScope by DisposableScope() { val state: BehaviorObservableWrapper = feature.state.wrap() - private fun onEvent(event: Event, state: State): Observable { + private fun onEvent(event: Event, getState: () -> State): Observable { + val state = getState() if (state.isLoading) { return observableOfEmpty() } @@ -37,6 +42,17 @@ class Counter : DisposableScope by DisposableScope() { is Event.Decrement -> observableOf(Msg.Set(value = state.value - 1L)) is Event.Reset -> observableOf(Msg.Set(value = 0L)) is Event.Fibonacci -> fibonacci(n = state.value) + is Event.IncrementAfter -> { + observableTimer(delay = event.duration, scheduler = mainScheduler) + .doOnAfterNext { println("IncrementAfter: $event") } + .map { Msg.Set(value = getState().value + 1L) } + } + + is Event.IncrementEvery -> { + observableInterval(period = event.duration, scheduler = mainScheduler) + .doOnAfterNext { println("IncrementEvery: $event") } + .map { Msg.Set(value = getState().value + 1L) } + } } } @@ -68,6 +84,8 @@ class Counter : DisposableScope by DisposableScope() { object Decrement : Event object Reset : Event object Fibonacci : Event + class IncrementAfter(val duration: Duration) : Event + class IncrementEvery(val duration: Duration) : Event } private sealed interface Msg { diff --git a/sample-mpp-module/src/commonMain/kotlin/com/badoo/reaktive/samplemppmodule/Feature.kt b/sample-mpp-module/src/commonMain/kotlin/com/badoo/reaktive/samplemppmodule/Feature.kt index 7c09ba9b6..6ce2080c6 100644 --- a/sample-mpp-module/src/commonMain/kotlin/com/badoo/reaktive/samplemppmodule/Feature.kt +++ b/sample-mpp-module/src/commonMain/kotlin/com/badoo/reaktive/samplemppmodule/Feature.kt @@ -4,8 +4,8 @@ import com.badoo.reaktive.base.Consumer import com.badoo.reaktive.disposable.Disposable import com.badoo.reaktive.disposable.scope.DisposableScope import com.badoo.reaktive.observable.Observable -import com.badoo.reaktive.observable.flatMap import com.badoo.reaktive.observable.map +import com.badoo.reaktive.observable.switchMap import com.badoo.reaktive.subject.behavior.BehaviorObservable import com.badoo.reaktive.subject.behavior.BehaviorSubject import com.badoo.reaktive.subject.publish.PublishSubject @@ -18,7 +18,7 @@ internal interface Feature : Consumer, Dis @Suppress("FunctionNaming") // Factory function internal fun Feature( initialState: State, - actor: (Event, State) -> Observable, + actor: (Event, () -> State) -> Observable, reducer: State.(Msg) -> State, ): Feature = object : Feature, DisposableScope by DisposableScope() { @@ -28,7 +28,7 @@ internal fun Feature( init { wishes - .flatMap { event -> actor(event, _state.value) } + .switchMap { event -> actor(event) { _state.value } } .map { msg -> _state.value.reducer(msg) } .subscribeScoped(onNext = _state::onNext) } diff --git a/utils-internal/src/jsMain/kotlin/com/badoo/reaktive/utils/CurrentThread.kt b/utils-internal/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/CurrentThread.kt similarity index 100% rename from utils-internal/src/jsMain/kotlin/com/badoo/reaktive/utils/CurrentThread.kt rename to utils-internal/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/CurrentThread.kt diff --git a/utils-internal/src/jsMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicBoolean.kt b/utils-internal/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicBoolean.kt similarity index 100% rename from utils-internal/src/jsMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicBoolean.kt rename to utils-internal/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicBoolean.kt diff --git a/utils-internal/src/jsMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicInt.kt b/utils-internal/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicInt.kt similarity index 100% rename from utils-internal/src/jsMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicInt.kt rename to utils-internal/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicInt.kt diff --git a/utils-internal/src/jsMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicLong.kt b/utils-internal/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicLong.kt similarity index 100% rename from utils-internal/src/jsMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicLong.kt rename to utils-internal/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicLong.kt diff --git a/utils-internal/src/jsMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicReference.kt b/utils-internal/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicReference.kt similarity index 100% rename from utils-internal/src/jsMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicReference.kt rename to utils-internal/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/atomic/AtomicReference.kt diff --git a/utils-internal/src/jsMain/kotlin/com/badoo/reaktive/utils/lock/ConditionLock.kt b/utils-internal/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/lock/ConditionLock.kt similarity index 100% rename from utils-internal/src/jsMain/kotlin/com/badoo/reaktive/utils/lock/ConditionLock.kt rename to utils-internal/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/lock/ConditionLock.kt diff --git a/utils-internal/src/jsMain/kotlin/com/badoo/reaktive/utils/lock/Lock.kt b/utils-internal/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/lock/Lock.kt similarity index 100% rename from utils-internal/src/jsMain/kotlin/com/badoo/reaktive/utils/lock/Lock.kt rename to utils-internal/src/jsCommonMain/kotlin/com/badoo/reaktive/utils/lock/Lock.kt