alexandre mommers
09/16/2025, 10:07 PMtapchicoma
09/17/2025, 7:37 AMjs() and wasmJs() targets
cc @Artem KobzarMichael Paus
09/17/2025, 8:15 AMArtem Kobzar
09/17/2025, 10:32 AMwasmJs has. Ideally, any wasmJsMain after renaming to webMain should work (with the only work should done: add import kotlin.js.* everywhere where some interop types like JsAny are used)Michael Paus
09/17/2025, 11:26 AMimport kotlinx.coroutines.promise cannot be resolved anymore. I use the promise extension function on CoroutineScope. This worked for wasmJs but does not seem to work anymore when I add JS.Artem Kobzar
09/17/2025, 11:35 AMwebMain and it should work, but the work should be done on the kotlinx.coroutines side.
What you can do for such cases as a work-around till it's fixed, is to add expect declaration in the web source set, and actualize it in the same way in wasmJs and js source sets.Michael Paus
09/17/2025, 11:48 AMDmitry Khalanskiy [JB]
09/17/2025, 12:07 PMpromise functions have different signatures and so belong to different source sets.
• On JS, the promise can return a Promise<T> for any Kotlin type T.
• On Wasm/JS, it's limited to returning Promise<T> for T that implement JsAny?, which does not include arbitrary Kotlin types.
In a shared signature, we would have to either return Promise<JsAny?>, losing the type information on JS, or limit T to JsAny?, preventing promises returning non-JS types on Wasm/JS.
If you see a way to maintain the flexibility of the signatures and still unify them, we'll gladly accept the proposed fix, of course!Artem Kobzar
09/17/2025, 12:13 PMweb source-set (that we've just introduced) the signature could be the same:
public fun <T: JsAny?> CoroutineScope.promise(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): Promise<T>
JsAny is actualized in Wasm as an external interface, and in JS as Any typeDmitry Khalanskiy [JB]
09/17/2025, 12:15 PMpromise<Boolean> { true } , for example, or even promise<Unit> { }.Artem Kobzar
09/17/2025, 12:17 PMJsBoolean and Boolean are not in a type relation for WasmJSDmitry Khalanskiy [JB]
09/17/2025, 12:17 PMArtem Kobzar
09/17/2025, 12:18 PMArtem Kobzar
09/17/2025, 12:19 PM// webMain
expect public fun <T> CoroutineScope.promise(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): Promise<JsAny?> // just repeat WasmJs signature
// wasmJsMain
actual public fun <T> CoroutineScope.promise(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): Promise<JsAny?> // remains the same
// jsMain
actual public fun <T> CoroutineScope.promise(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): Promise<T> // not sure if there isn't something like `incompatible actual return type` compilation errorDmitry Khalanskiy [JB]
09/17/2025, 12:29 PMe: file:///home/dkhalansky/IdeaProjects/kotlinx.coroutines/kotlinx-coroutines-core/js/src/Promise.kt:21:38 [ACTUAL_WITHOUT_EXPECT] 'actual fun <T> CoroutineScope.promise(context: CoroutineContext, start: CoroutineStart, block: suspend CoroutineScope.() -> T): Promise<T>' has no corresponding expected declaration
The following declaration is incompatible because return type is different:
expect fun <T> CoroutineScope.promise(context: CoroutineContext = ..., start: CoroutineStart = ..., block: suspend CoroutineScope.() -> T): Promise<JsAny?>Artem Kobzar
09/17/2025, 12:33 PMMichael Paus
09/17/2025, 1:14 PM@kotlin.js.ExperimentalWasmJsInterop on the JS side. Maybe this should also be renamed to ExperimentalWebInterop then.Artem Kobzar
09/17/2025, 1:25 PMMichael Paus
09/17/2025, 1:46 PMArtem Kobzar
09/17/2025, 2:40 PMturansky
09/17/2025, 3:06 PMCloneable - problem of IDEAturansky
09/17/2025, 3:06 PMturansky
09/17/2025, 3:11 PMPromise.await()
2. Promise.asDeferred()
3. CoroutineScope.promise(...)
already available in webMain 😉turansky
09/17/2025, 3:13 PMMichael Paus
09/17/2025, 3:16 PMturansky
09/17/2025, 3:31 PM@kotlin.js.ExperimentalWasmJsInterop by defaultMichael Paus
09/18/2025, 9:37 AMWhen accessing module declarations from UMD, they must be marked with both @JsModule and @JsNonModule.
Here is a shortened version of that code.
private suspend fun xxx(fs: FileSystem, filePath: Path) {
JSZip().apply {
val bytes = filePath.readBytes(fs)
file(filePath.toString(), bytes.toUint8Array())
}
}
The critical line is the one which starts with JSZip. It was a bit confusing that IJ indicates a different (false) error than the actual compiler error.
All in all I think that the common web folder is still good for some surprises 😢.turansky
09/18/2025, 9:42 AMtarget = "es2015"turansky
09/18/2025, 9:43 AMMichael Paus
09/18/2025, 9:57 AMtasks.withType<KotlinJsCompile>().configureEach {
compilerOptions {
target = "es2015"
}
}
to the build file, right?
After adding this the code does compile but what does that mean in practice now? Do I have to compile all my modules with that option now in order to ensure compatibility or not? What other compatibility problems are still lingering around?
Switching to the new common web folder is full of undocumented surprises 🤨.turansky
09/18/2025, 10:17 AMtarget = "es2015" - default, which we miss 😞turansky
09/18/2025, 10:18 AMturansky
09/18/2025, 10:18 AMturansky
09/18/2025, 10:22 AMDo I have to compile all my modules with that option now in order to ensure compatibility or not?We apply it for all subprojects. Reasons: 1. No legacy inspections 2. Tests, compiled in legacy mode will test something else
turansky
09/18/2025, 10:23 AMMichael Paus
09/18/2025, 12:14 PMArtem Kobzar
09/18/2025, 12:35 PMalexandre mommers
09/19/2025, 12:01 AMArtem Kobzar
09/19/2025, 6:39 AMMichael Paus
09/19/2025, 6:51 AMArtem Kobzar
09/19/2025, 6:55 AMsuresh
10/20/2025, 5:42 AMI’ve put it to my todo list to fix such a thing in KTOR@Artem Kobzar Any YT issue to track this progress as i am also facing the same issue where the
JS client engine is not available on webMain?Artem Kobzar
10/20/2025, 10:05 AMArtem Kobzar
10/26/2025, 1:32 PM