diff --git a/.github/workflows/compilation-check.yml b/.github/workflows/compilation-check.yml index a0d4c0e..3726409 100644 --- a/.github/workflows/compilation-check.yml +++ b/.github/workflows/compilation-check.yml @@ -12,10 +12,10 @@ jobs: steps: - uses: actions/checkout@v1 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v1 with: - java-version: 11 + java-version: 17 - name: Build and test run: ./gradlew build publishToMavenLocal syncMultiPlatformLibraryDebugFrameworkIosX64 - name: Install pods with kotlin diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 219f43b..d0d142e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -21,12 +21,15 @@ jobs: steps: - uses: actions/checkout@v1 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v1 with: - java-version: 11 - - name: Publish library - run: ./gradlew publish + java-version: 17 + - name: Prebuild library + run: ./gradlew publishToMavenLocal + - name: Publish + run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository + release: name: Create release needs: publish diff --git a/.gitignore b/.gitignore index da38b27..0c89de0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ .classpath .vscode .idea +.kotlin build *.iml Pods diff --git a/README.md b/README.md index 9820407..9016c9a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +![moko-javascript](https://user-images.githubusercontent.com/5010169/128704305-df9c8e9e-200c-4d34-801e-a5b01c80f0cb.png) [![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0) [![Download](https://img.shields.io/maven-central/v/dev.icerock.moko/javascript) ](https://repo1.maven.org/maven2/dev/icerock/moko/javascript) ![kotlin-version](https://kotlin-version.aws.icerock.dev/kotlin-version?group=dev.icerock.moko&name=javascript) # Mobile Kotlin javascript @@ -18,8 +19,8 @@ This is a Kotlin MultiPlatform library that allows you to run JavaScript code fr - Pass objects to JavaScript as global vars ## Requirements -- Gradle version 6.0+ -- Android API 16+ +- Gradle version 8.0+ +- Android API 21+ - iOS version 9.0+ ## Installation @@ -35,7 +36,7 @@ allprojects { project build.gradle ```groovy dependencies { - commonMainApi("dev.icerock.moko:javascript:0.3.0") + commonMainApi("dev.icerock.moko:javascript:0.4.0") } ``` diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 32a15eb..0000000 --- a/build.gradle +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2019 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. - */ - -buildscript { - repositories { - mavenCentral() - google() - } - dependencies { - classpath(":javascript-build-logic") - } -} - -allprojects { - plugins.withId("org.gradle.maven-publish") { - group = "dev.icerock.moko" - version = libs.versions.mokoJavascriptVersion.get() - } -} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..5c22092 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,34 @@ +/* + * Copyright 2025 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. + */ +apply(plugin = "dev.icerock.moko.gradle.publication.nexus") + +buildscript { + repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } + mavenCentral() + gradlePluginPortal() + } + dependencies { + classpath(libs.mokoGradlePlugin) + classpath("app.cash.zipline:zipline-gradle-plugin:1.23.0") + classpath(":javascript-build-logic") + } +} + +val mokoVersion = moko.versions.mokoJavascriptVersion.get() +allprojects { + group = "dev.icerock.moko" + version = mokoVersion +} + +tasks.register("clean", Delete::class).configure { + group = "build" + delete(rootProject.layout.buildDirectory) +} diff --git a/gradle.properties b/gradle.properties index 48b050a..cb8a3c6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,10 +3,8 @@ org.gradle.configureondemand=false org.gradle.parallel=true kotlin.code.style=official -kotlin.native.enableDependencyPropagation=false -kotlin.mpp.enableGranularSourceSetsMetadata=true -kotlin.mpp.enableCompatibilityMetadataVariant=true android.useAndroidX=true mobile.multiplatform.iosTargetWarning=false +kotlin.mpp.defaultHierarchies.template.enabled=false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bffb1ff..2c36814 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,29 +1,37 @@ [versions] -kotlinTestVersion = "1.6.21" -androidAppCompatVersion = "1.2.0" -materialDesignVersion = "1.0.0" -androidLifecycleVersion = "2.1.0" -androidCoreTestingVersion = "1.3.0" -testJUnitExtVersion = "1.1.2" -quickjsVersion = "0.9.2" -coroutinesVersion = "1.6.0-native-mt" -kotlinxSerializationVersion = "1.3.3" +kotlinVersion = "2.2.10" +androidAppCompatVersion = "1.7.1" +materialDesignVersion = "1.13.0" +androidLifecycleVersion = "2.2.0" +androidCoreTestingVersion = "1.7.0" +testJUnitExtVersion = "1.3.0" +coroutinesVersion = "1.10.2" +kotlinxSerializationVersion = "1.9.0" mokoTestVersion = "0.6.1" -mokoJavascriptVersion = "0.3.0" - +ziplineVersion = "1.23.0" +mokoMultiplatformVersion = "0.14.4" +androidGradleVersion = "8.12.3" +detektVersion = "1.23.8" [libraries] appCompat = { module = "androidx.appcompat:appcompat", version.ref = "androidAppCompatVersion" } material = { module = "com.google.android.material:material", version.ref = "materialDesignVersion" } lifecycle = { module = "androidx.lifecycle:lifecycle-extensions", version.ref = "androidLifecycleVersion" } -kotlinTestJUnit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlinTestVersion" } +kotlinTestJUnit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlinVersion" } testRunner = { module = "androidx.test:runner", version.ref = "androidCoreTestingVersion" } testRules = { module = "androidx.test:rules", version.ref = "androidCoreTestingVersion" } testJUnitExt = { module = "androidx.test.ext:junit", version.ref = "testJUnitExtVersion" } testJUnitExtKtx = { module = "androidx.test.ext:junit-ktx", version.ref = "testJUnitExtVersion" } -quickjs = { module = "app.cash.quickjs:quickjs-android", version.ref = "quickjsVersion" } +ziplineAndroid = { module = "app.cash.zipline:zipline-android", version.ref = "ziplineVersion" } coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutinesVersion" } kotlinSerialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationVersion" } -kotlinTest = { module = "org.jetbrains.kotlin:kotlin-test-common", version.ref = "kotlinTestVersion" } -kotlinTestAnnotations = { module = "org.jetbrains.kotlin:kotlin-test-annotations-common", version.ref = "kotlinTestVersion" } +kotlinTest = { module = "org.jetbrains.kotlin:kotlin-test-common", version.ref = "kotlinVersion" } +kotlinTestAnnotations = { module = "org.jetbrains.kotlin:kotlin-test-annotations-common", version.ref = "kotlinVersion" } mokoTest = { module = "dev.icerock.moko:test-core", version.ref = "mokoTestVersion" } + +mokoMultiplatform = { module = "dev.icerock:mobile-multiplatform", version.ref = "mokoMultiplatformVersion" } +kotlinGradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlinVersion" } +androidGradlePlugin = { module = "com.android.tools.build:gradle", version.ref = "androidGradleVersion" } +detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detektVersion" } +detektPlugin = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detektVersion" } +mokoGradlePlugin = { module = "dev.icerock.moko:moko-gradle-plugin", version = "0.5.1" } diff --git a/gradle/moko.versions.toml b/gradle/moko.versions.toml new file mode 100644 index 0000000..165aa55 --- /dev/null +++ b/gradle/moko.versions.toml @@ -0,0 +1,2 @@ +[versions] +mokoJavascriptVersion = "0.4.0" \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0f80bbf..7bcf456 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Mon Sep 15 18:35:34 NOVT 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/javascript-build-logic/build.gradle.kts b/javascript-build-logic/build.gradle.kts index c7206d5..d104cc4 100644 --- a/javascript-build-logic/build.gradle.kts +++ b/javascript-build-logic/build.gradle.kts @@ -3,15 +3,20 @@ plugins { } repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } mavenCentral() - google() - gradlePluginPortal() } dependencies { - api("dev.icerock:mobile-multiplatform:0.14.1") - api("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21") - api("com.android.tools.build:gradle:7.0.1") - api("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.15.0") + api(libs.mokoMultiplatform) + api(libs.kotlinGradlePlugin) + api(libs.androidGradlePlugin) + api(libs.detektPlugin) } diff --git a/javascript-build-logic/settings.gradle.kts b/javascript-build-logic/settings.gradle.kts new file mode 100644 index 0000000..7862700 --- /dev/null +++ b/javascript-build-logic/settings.gradle.kts @@ -0,0 +1,25 @@ +/* + * Copyright 2025 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. + */ + +rootProject.name = "javascript-build-logic" + +dependencyResolutionManagement { + repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } + + mavenCentral() + } + + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} diff --git a/javascript-build-logic/src/main/kotlin/android-app-convention.gradle.kts b/javascript-build-logic/src/main/kotlin/android-app-convention.gradle.kts index 2859874..a744cb3 100644 --- a/javascript-build-logic/src/main/kotlin/android-app-convention.gradle.kts +++ b/javascript-build-logic/src/main/kotlin/android-app-convention.gradle.kts @@ -9,10 +9,6 @@ plugins { } android { - dexOptions { - javaMaxHeapSize = "2g" - } - buildTypes { getByName("release") { isMinifyEnabled = true @@ -24,9 +20,13 @@ android { } } - packagingOptions { - exclude("META-INF/*.kotlin_module") - exclude("META-INF/AL2.0") - exclude("META-INF/LGPL2.1") + packaging { + resources { + excludes += listOf( + "META-INF/*.kotlin_module", + "META-INF/AL2.0", + "META-INF/LGPL2.1" + ) + } } } diff --git a/javascript-build-logic/src/main/kotlin/android-base-convention.gradle.kts b/javascript-build-logic/src/main/kotlin/android-base-convention.gradle.kts index 5f97e66..c23cbbb 100644 --- a/javascript-build-logic/src/main/kotlin/android-base-convention.gradle.kts +++ b/javascript-build-logic/src/main/kotlin/android-base-convention.gradle.kts @@ -5,10 +5,15 @@ import com.android.build.gradle.BaseExtension configure { - compileSdkVersion(30) + compileSdkVersion(36) defaultConfig { - minSdkVersion(18) - targetSdkVersion(30) + minSdk = 21 + targetSdk = 36 + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } } diff --git a/javascript-build-logic/src/main/kotlin/detekt-convention.gradle.kts b/javascript-build-logic/src/main/kotlin/detekt-convention.gradle.kts index 68343a8..b4c2900 100644 --- a/javascript-build-logic/src/main/kotlin/detekt-convention.gradle.kts +++ b/javascript-build-logic/src/main/kotlin/detekt-convention.gradle.kts @@ -7,9 +7,9 @@ plugins { } detekt { - input.setFrom("src/commonMain/kotlin", "src/androidMain/kotlin", "src/iosMain/kotlin", "src/main/kotlin") + source.setFrom("src/commonMain/kotlin", "src/androidMain/kotlin", "src/iosMain/kotlin", "src/main/kotlin") } dependencies { - "detektPlugins"("io.gitlab.arturbosch.detekt:detekt-formatting:1.15.0") + detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.23.8") } diff --git a/javascript-build-logic/src/main/kotlin/multiplatform-library-convention.gradle.kts b/javascript-build-logic/src/main/kotlin/multiplatform-library-convention.gradle.kts index 1b29c1a..d1d5085 100644 --- a/javascript-build-logic/src/main/kotlin/multiplatform-library-convention.gradle.kts +++ b/javascript-build-logic/src/main/kotlin/multiplatform-library-convention.gradle.kts @@ -10,29 +10,50 @@ plugins { } kotlin { - ios() + iosX64() + iosArm64() iosSimulatorArm64() - android { + androidTarget { publishLibraryVariants("release", "debug") } + sourceSets { + val commonMain by getting + val iosX64Main by getting + val iosArm64Main by getting val iosSimulatorArm64Main by getting - val iosSimulatorArm64Test by getting - val mobileDeviceTest by creating - - val commonTest by getting - val iosMain by getting - val iosTest by getting - val androidAndroidTest by getting + val iosMain by creating { + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + iosMain.dependsOn(commonMain) - iosSimulatorArm64Main.dependsOn(iosMain) - iosSimulatorArm64Test.dependsOn(iosTest) + val iosX64Test by getting + val iosArm64Test by getting + val iosSimulatorArm64Test by getting - mobileDeviceTest.dependsOn(commonTest) - iosTest.dependsOn(mobileDeviceTest) - androidAndroidTest.dependsOn(mobileDeviceTest) + val commonTest by getting + val mobileDeviceTestNative by creating { + kotlin.srcDir("src/mobileDeviceTest/kotlin") + dependsOn(commonTest) + } + + val iosTest by creating { + iosX64Test.dependsOn(this) + iosArm64Test.dependsOn(this) + iosSimulatorArm64Test.dependsOn(this) + dependsOn(mobileDeviceTestNative) + } + + val mobileDeviceTestAndroid by creating { + kotlin.srcDir("src/mobileDeviceTest/kotlin") + } + + val androidInstrumentedTest by getting { + dependsOn(mobileDeviceTestAndroid) + } } } - diff --git a/javascript-build-logic/src/main/kotlin/publication-convention.gradle.kts b/javascript-build-logic/src/main/kotlin/publication-convention.gradle.kts index 9307b13..d85d6c6 100644 --- a/javascript-build-logic/src/main/kotlin/publication-convention.gradle.kts +++ b/javascript-build-logic/src/main/kotlin/publication-convention.gradle.kts @@ -1,25 +1,14 @@ /* - * Copyright 2021 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2025 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. */ import java.util.Base64 plugins { - id("javadoc-stub-convention") id("org.gradle.maven-publish") - id("signing") } publishing { - repositories.maven("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") { - name = "OSSRH" - - credentials { - username = System.getenv("OSSRH_USER") - password = System.getenv("OSSRH_KEY") - } - } - publications.withType { // Provide artifacts information requited by Maven Central pom { @@ -61,15 +50,22 @@ publishing { } } +val signingKeyId: String? = System.getenv("SIGNING_KEY_ID") +if (signingKeyId != null) { + apply(plugin = "signing") + + configure { + val signingPassword: String? = System.getenv("SIGNING_PASSWORD") + val signingKey: String? = System.getenv("SIGNING_KEY")?.let { base64Key -> + String(Base64.getDecoder().decode(base64Key)) + } -signing { - val signingKeyId: String? = System.getenv("SIGNING_KEY_ID") - val signingPassword: String? = System.getenv("SIGNING_PASSWORD") - val signingKey: String? = System.getenv("SIGNING_KEY")?.let { base64Key -> - String(Base64.getDecoder().decode(base64Key)) - } - if (signingKeyId != null) { useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword) sign(publishing.publications) } + + val signingTasks = tasks.withType() + tasks.withType().configureEach { + dependsOn(signingTasks) + } } diff --git a/javascript/build.gradle.kts b/javascript/build.gradle.kts index 787677f..4df8a6c 100644 --- a/javascript/build.gradle.kts +++ b/javascript/build.gradle.kts @@ -7,27 +7,26 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent plugins { id("multiplatform-library-convention") - id("dev.icerock.mobile.multiplatform.android-manifest") id("publication-convention") + id("app.cash.zipline") } android { - testOptions.unitTests.isIncludeAndroidResources = true + namespace = "dev.icerock.moko.javascript" + defaultConfig { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } - sourceSets { - getByName("androidTest").java.srcDirs( - file("src/androidAndroidTest/kotlin"), - file("src/mobileDeviceTest/kotlin") - ) + testOptions { + unitTests.isIncludeAndroidResources = true } } dependencies { - androidMainImplementation(libs.quickjs) + androidMainImplementation(libs.ziplineAndroid) commonMainImplementation(libs.kotlinSerialization) + commonTestImplementation(libs.kotlinTest) commonTestImplementation(libs.kotlinTestAnnotations) commonTestImplementation(libs.mokoTest) diff --git a/javascript/src/androidMain/AndroidManifest.xml b/javascript/src/androidMain/AndroidManifest.xml deleted file mode 100644 index 309ebc8..0000000 --- a/javascript/src/androidMain/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/javascript/src/androidMain/kotlin/dev/icerock/moko/javascript/ContextProvider.kt b/javascript/src/androidMain/kotlin/dev/icerock/moko/javascript/ContextProvider.kt index 678b674..5311102 100644 --- a/javascript/src/androidMain/kotlin/dev/icerock/moko/javascript/ContextProvider.kt +++ b/javascript/src/androidMain/kotlin/dev/icerock/moko/javascript/ContextProvider.kt @@ -4,7 +4,9 @@ package dev.icerock.moko.javascript -internal interface ContextProvider { +import app.cash.zipline.ZiplineService + +internal interface ContextProvider : ZiplineService { fun getBool(name: String): Boolean fun getDouble(name: String): Double diff --git a/javascript/src/androidMain/kotlin/dev/icerock/moko/javascript/ContextProviderDynamic.kt b/javascript/src/androidMain/kotlin/dev/icerock/moko/javascript/ContextProviderDynamic.kt index 281fe05..17ba05e 100644 --- a/javascript/src/androidMain/kotlin/dev/icerock/moko/javascript/ContextProviderDynamic.kt +++ b/javascript/src/androidMain/kotlin/dev/icerock/moko/javascript/ContextProviderDynamic.kt @@ -4,6 +4,8 @@ package dev.icerock.moko.javascript +import java.util.Collections.emptyMap + internal class ContextProviderDynamic : ContextProvider { var context: Map = emptyMap() var activeScript: String = "" diff --git a/javascript/src/androidMain/kotlin/dev/icerock/moko/javascript/JavaScriptEngine.kt b/javascript/src/androidMain/kotlin/dev/icerock/moko/javascript/JavaScriptEngine.kt index be92142..fba299d 100644 --- a/javascript/src/androidMain/kotlin/dev/icerock/moko/javascript/JavaScriptEngine.kt +++ b/javascript/src/androidMain/kotlin/dev/icerock/moko/javascript/JavaScriptEngine.kt @@ -4,26 +4,30 @@ package dev.icerock.moko.javascript -import app.cash.quickjs.QuickJs -import app.cash.quickjs.QuickJsException +import app.cash.zipline.EngineApi +import app.cash.zipline.QuickJsException +import app.cash.zipline.Zipline +import kotlinx.coroutines.Dispatchers import kotlinx.serialization.SerializationException import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonArray import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject -actual class JavaScriptEngine actual constructor() { - private val quickJs: QuickJs = QuickJs.create() - private val json: Json = Json.Default +@OptIn(EngineApi::class) +actual class JavaScriptEngine { + + private val json: Json = Json private val jsContext: ContextProviderDynamic = ContextProviderDynamic() + private val zipline: Zipline = Zipline.create(dispatcher = Dispatchers.IO) @Volatile var isClosed = false private set init { - quickJs.set("mokoJsContext", ContextProvider::class.java, jsContext) - quickJs.evaluate( + zipline.bind("mokoJsContext", jsContext) + zipline.quickJs.evaluate( """ function mokoJavaScriptProcessResult(result) { if (typeof result === 'object') return JSON.stringify(result); @@ -41,7 +45,7 @@ actual class JavaScriptEngine actual constructor() { val scriptWithContext: String = buildString { fillContext(scriptContext) } - quickJs.evaluate(scriptWithContext) + zipline.quickJs.evaluate(scriptWithContext) } actual fun evaluate(context: Map, script: String): JsType { @@ -56,7 +60,7 @@ actual class JavaScriptEngine actual constructor() { actual fun close() { if (isClosed) return - quickJs.close() + zipline.quickJs.close() isClosed = true } @@ -71,7 +75,7 @@ actual class JavaScriptEngine actual constructor() { fillContext(context) append("mokoJavaScriptProcessResult(eval(mokoJsContext.getScript()));") } - val result: Any? = quickJs.evaluate(scriptWithContext) + val result: Any? = zipline.quickJs.evaluate(scriptWithContext) return handleQuickJsResult(result) } @@ -104,9 +108,9 @@ actual class JavaScriptEngine actual constructor() { val jsonElement: JsonElement = json.parseToJsonElement(result) if (jsonElement is JsonObject || jsonElement is JsonArray) JsType.Json(jsonElement) else JsType.Str(result) - } catch (ex: SerializationException) { + } catch (_: SerializationException) { JsType.Str(result) - } catch (ex: IllegalStateException) { + } catch (_: IllegalStateException) { JsType.Str(result) } else -> throw JavaScriptEvaluationException( diff --git a/javascript/src/iosMain/kotlin/dev/icerock/moko/javascript/JavaScriptEngine.kt b/javascript/src/iosMain/kotlin/dev/icerock/moko/javascript/JavaScriptEngine.kt index 42e4a0f..b8553bb 100644 --- a/javascript/src/iosMain/kotlin/dev/icerock/moko/javascript/JavaScriptEngine.kt +++ b/javascript/src/iosMain/kotlin/dev/icerock/moko/javascript/JavaScriptEngine.kt @@ -4,6 +4,8 @@ package dev.icerock.moko.javascript +import kotlinx.cinterop.BetaInteropApi +import kotlinx.cinterop.ExperimentalForeignApi import kotlinx.serialization.SerializationException import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonArray @@ -24,7 +26,7 @@ import platform.JavaScriptCore.JSContext import platform.JavaScriptCore.JSValue import platform.JavaScriptCore.setObject -actual class JavaScriptEngine actual constructor() { +actual class JavaScriptEngine { private val jsContext = JSContext().apply { exceptionHandler = { exceptionContext, exception -> @@ -43,6 +45,7 @@ actual class JavaScriptEngine actual constructor() { ) } + @OptIn(BetaInteropApi::class) actual fun setContextObjects(vararg context: Pair) { context.forEach { (key, value) -> val contextObject: Any? = prepareValueForJsContext(value) @@ -53,6 +56,7 @@ actual class JavaScriptEngine actual constructor() { } } + @OptIn(BetaInteropApi::class) actual fun evaluate(context: Map, script: String): JsType { context.forEach { (key, value) -> jsContext.setObject( @@ -94,22 +98,24 @@ actual class JavaScriptEngine actual constructor() { } } +@OptIn(ExperimentalForeignApi::class, BetaInteropApi::class) private fun JsonObject.toNSDictionary(): NSDictionary { val data = NSString.create(string = this.toString()).dataUsingEncoding(NSUTF8StringEncoding) ?: return NSDictionary() return (NSJSONSerialization.JSONObjectWithData( data = data, - options = 0, + options = 0u, error = null ) as? NSDictionary) ?: NSDictionary() } +@OptIn(ExperimentalForeignApi::class, BetaInteropApi::class) private fun JsonArray.toNSArray(): NSArray { val data = NSString.create(string = this.toString()).dataUsingEncoding(NSUTF8StringEncoding) ?: return NSArray() return (NSJSONSerialization.JSONObjectWithData( data = data, - options = 0, + options = 0u, error = null ) as? NSArray) ?: NSArray() } @@ -128,9 +134,9 @@ private fun JSValue.toMokoJSType(): JsType { val jsonElement: JsonElement = json.parseToJsonElement(toString_().orEmpty()) if (jsonElement is JsonObject || jsonElement is JsonArray) JsType.Json(jsonElement) else JsType.Str(toString_().orEmpty()) - } catch (ex: SerializationException) { + } catch (_: SerializationException) { JsType.Str(toString_().orEmpty()) - } catch (ex: IllegalStateException) { + } catch (_: IllegalStateException) { JsType.Str(toString_().orEmpty()) } isNumber -> JsType.DoubleNum(toDouble()) @@ -156,7 +162,7 @@ private fun Any?.toJsonElement(): JsonElement { is NSString -> JsonPrimitive(this as String) is NSNumber -> JsonPrimitive(this.doubleValue) is NSDictionary -> (this as Map).toJson() - is NSArray -> (this as List<*>).map { it.toJsonElement() }.let { JsonArray(it) } + is NSArray -> JsonArray((this as List<*>).map { it.toJsonElement() }) else -> throw IllegalArgumentException("unknown JSValue type $this") } } diff --git a/javascript/src/mobileDeviceTest/kotlin/dev/icerock/moko/javascript/JavaScriptEngineCrossTypesTests.kt b/javascript/src/mobileDeviceTest/kotlin/dev/icerock/moko/javascript/JavaScriptEngineCrossTypesTests.kt index bba83f5..226dbd4 100644 --- a/javascript/src/mobileDeviceTest/kotlin/dev/icerock/moko/javascript/JavaScriptEngineCrossTypesTests.kt +++ b/javascript/src/mobileDeviceTest/kotlin/dev/icerock/moko/javascript/JavaScriptEngineCrossTypesTests.kt @@ -8,7 +8,6 @@ import kotlinx.serialization.json.Json import kotlinx.serialization.json.encodeToJsonElement import kotlin.test.AfterTest import kotlin.test.BeforeTest -import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals diff --git a/sample/android-app/build.gradle.kts b/sample/android-app/build.gradle.kts index 24459bf..3db250f 100644 --- a/sample/android-app/build.gradle.kts +++ b/sample/android-app/build.gradle.kts @@ -4,10 +4,10 @@ plugins { id("android-app-convention") - id("kotlin-android") } android { + namespace = "com.icerockdev.app" defaultConfig { applicationId = "dev.icerock.moko.samples.javascript" diff --git a/sample/android-app/src/main/AndroidManifest.xml b/sample/android-app/src/main/AndroidManifest.xml index adf12eb..2ff1829 100644 --- a/sample/android-app/src/main/AndroidManifest.xml +++ b/sample/android-app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:tools="http://schemas.android.com/tools"> @@ -10,7 +9,8 @@ android:theme="@style/Theme.AppCompat.DayNight" tools:ignore="GoogleAppIndexingWarning"> - + diff --git a/sample/mpp-library/build.gradle.kts b/sample/mpp-library/build.gradle.kts index ac7d979..aaf5d6f 100644 --- a/sample/mpp-library/build.gradle.kts +++ b/sample/mpp-library/build.gradle.kts @@ -12,8 +12,14 @@ plugins { } kotlin { - android() - ios() + androidTarget() + iosArm64() + iosSimulatorArm64() + iosX64() +} + +android { + namespace = "com.icerockdev.library" } dependencies { diff --git a/sample/mpp-library/src/androidMain/AndroidManifest.xml b/sample/mpp-library/src/androidMain/AndroidManifest.xml deleted file mode 100644 index 42af3a2..0000000 --- a/sample/mpp-library/src/androidMain/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index c6ccb10..c0fdc25 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,20 +1,33 @@ /* - * Copyright 2021 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2025 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license. */ -enableFeaturePreview("VERSION_CATALOGS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") dependencyResolutionManagement { repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } mavenCentral() - google() + } - jcenter() + versionCatalogs { + create("moko") { + from(files("gradle/moko.versions.toml")) + } } } -includeBuild("javascript-build-logic") +rootProject.name = "moko-javascript" + +if (gradle.parent == null) { + includeBuild("javascript-build-logic") +} include(":javascript") include(":sample:android-app")