https://kotlinlang.org logo
o

Oleg Yukhnevich

01/13/2023, 9:05 AM
Is it possible now to make declaration which returns Promise from JS accessible from K/WASM?
s

Svyatoslav Kuzmich [JB]

01/13/2023, 9:27 AM
Yes. Example from stdlib tests. APIs around promises and Dynamic are temporary and will change in the near future.
o

Oleg Yukhnevich

01/13/2023, 9:35 AM
Ah, now I see,
kotlin.js.Promise
is available only in 1.8.20-dev builds 🙂 Thx!
one more minor question, just to confirm my findings. In K/JS we have
js(code)
function, but on K/WASM we only have
JsFun
annotation, right? And so equivalent for JS:
Copy code
js("eval('require')('node:crypto').webcrypto").unsafeCast<WebCrypto>
in WASM will be:
Copy code
@JsFun("""() => eval('require')('node:crypto').webcrypto""")
private external fun getWebCrypto(): WebCrypto
(where WebCrypto is external interface) Correct?
s

Svyatoslav Kuzmich [JB]

01/13/2023, 9:42 AM
Correct.
eval
looks unnecessary.
kotlin.js.Promise
is available only in 1.8.20-dev builds
It’s a pure library class. You can copy it to use with earlier builds, if needed.
o

Oleg Yukhnevich

01/13/2023, 9:52 AM
eval
is needed to overcome this warning/error when running in browser:
Copy code
Module build failed: UnhandledSchemeError: Reading from "node:crypto" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.
related issue: https://youtrack.jetbrains.com/issue/KT-46082 But not sure, if it’s needed for K/WASM
It’s a pure library class
Yeah, I was trying to experiment with 1.8.0, but haven’t found any samples with Promise.
Now I have everything to continue my experiments, thx!~
b

bashor

01/13/2023, 12:12 PM
You can try this way:
Copy code
require(/* webpackIgnore: true */'node:crypto')
Also, maybe indirect call will help, like: •
(require)('node:crypto')
• or
var t = require; t('node:crypto')
o

Oleg Yukhnevich

01/13/2023, 12:17 PM
Will try of course, but what is the issue with ‘eval’ if it’s called once in single place for full lifetime of app?
b

bashor

01/13/2023, 12:59 PM
No big issue 🙂
Actually, there could be environments where eval is prohibited
o

Oleg Yukhnevich

01/13/2023, 1:14 PM
BTW, I have tried all those 3 variant, and all of them give the same warning… Only variant with
eval
works without warning
may be I have one more related question. As I think you already understand, that Im trying to wrap WebCrypto API via K/WASM (just experimenting a bit) But, I haven’t found in kotlin repository tests on how on current moment interop from K/WASM to JS arrays is implemented f.e. we have
WebCrypto.getRandomValues(array)
where array is
Int8Array
in JS. With K/JS we can path
ByteArray
there, as on K/JS
Int8Array == ByteArray
With K/WASM it’s not like this and
ByteArray
has underlying storage hodlin wasm array. Is it possible to path
kotlin.ByteArray
in K/WASM via jsinterop where
js.Int8Array
is expected? For now I have something like this and copy per byte (not efficient at all):
Copy code
private sealed external interface WasmByteArray
@JsFun("(size) => new Int8Array(size)")
private external fun newArray(size: Int): WasmByteArray

@JsFun("(array) => array.length")
private external fun arraySize(array: WasmByteArray): Int

@JsFun("(array, index) => array[index]")
private external fun arrayGet(array: WasmByteArray, index: Int): Byte

@JsFun("(array, index, value) => array[index] = value")
private external fun arraySet(array: WasmByteArray, index: Int, value: Byte): Byte

private sealed external interface WebCrypto {
    fun getRandomValues(array: WasmByteArray): WasmByteArray
}

private fun WasmByteArray.copyTo(destination: ByteArray): ByteArray {
    require(destination.size == arraySize(this))
    repeat(destination.size) { index ->
        destination[index] = arrayGet(this, index)
    }
    return destination
}

fun nextBytes(array: ByteArray): ByteArray {
    return crypto.getRandomValues(newArray(array.size)).copyTo(array)
}
s

Svyatoslav Kuzmich [JB]

01/13/2023, 1:28 PM
Currently Wasm arrays cannot interop with JS arrays. Copy is probably the best thing one can do.
b

bashor

01/13/2023, 1:30 PM
BTW, I have tried all those 3 variant, and all of them give the same warning…
Only variant with
eval
works without warning
Thanks for trying it out. It’s unexpected that
/* webpackIgnore: true */
doesn’t work for
require
, since we are using it for dynamic
import
. 🤷‍♂️
o

Oleg Yukhnevich

01/13/2023, 1:43 PM
From what I’ve found: https://github.com/webpack/webpack/issues/11311
webpackIgnore
for
require
was introduced only into webpack v5 and was not backported to v4 (as for what I’ve found) And kotlin still uses webpack v4 🙂
webpackIgnore
for
import
works for both v4 and v5
Currently Wasm arrays cannot interop with JS arrays. Copy is probably the best thing one can do.
OK, thx! will continue with copying…
s

Svyatoslav Kuzmich [JB]

01/13/2023, 1:57 PM
We hope that with the further development of the Wasm standard, we will be able to: • Copy in bulk instead of per-byte • Efficiently provide an array-like
array[index]
JS API without copy or
Proxy
• Maybe use primitive arrays as IntXArray without any adaptation
o

Oleg Yukhnevich

01/13/2023, 2:02 PM
Cool! That will be perfect! For now I will use what we have 🙂 Even now, JS interop is really easy and super useful. I will try to migrate to K/WASM other part of my WebCrypto K/JS interop code later in coming days. Should be rather straightforward
b

bashor

01/13/2023, 9:12 PM
And kotlin still uses webpack v4 🙂
I think we moved to v5 by default a long time ago (cc @Ilya Goncharov [JB])
h

hfhbd

01/13/2023, 9:24 PM
Since 1.5.0: https://youtrack.jetbrains.com/issue/KT-42921/KJS-Support-webpack-5 But you can use webpackv4 with this property:
kotlin.js.webpack.major.version=4
@Oleg Yukhnevich Maybe you still have this property stored in your gradle.properties.
o

Oleg Yukhnevich

01/13/2023, 9:31 PM
Hm, sorry for confusion regarding version 4 but, still, looks like support for
webpackIgnore
inside
require
is off by default - https://webpack.js.org/configuration/module/#moduleparserjavascriptcommonjsmagiccomments https://github.com/webpack/webpack/issues/15975#issuecomment-1166609374
Maybe you still have this property stored in your gradle.properties.
No 🙂 Didn’t know even about this property.
BTW, in the mean time, I was able to make WebCrypto work in K/WASM via jsinterop with kotlin 1.8.0! 🙂 Still, as far as I understand (from cryptic compiler errors), 1.8.0 doesn’t support wasm external declarations with generics (so no Promise<T> 😞 ) And also ideally I need coroutines built for wasm… I saw, that there is a build of them in https://maven.pkg.jetbrains.space/kotlin/p/wasm/experimental (found in skiko, hehe), but it’s a mess to make it working… Is there any timeline for having some experimental wasm coroutines, may be with kotlin 1.8.20 ? 🙂
b

bashor

01/16/2023, 8:32 PM
but it’s a mess to make it working…
what exactly is issue for you?
Is there any timeline for having some experimental wasm coroutines, may be with kotlin 1.8.20 ?
maybe, but not as part of official coroutines releases
s

Svyatoslav Kuzmich [JB]

01/16/2023, 8:35 PM
Published kx.coroutines (used in skiko) use expired dev build of Kotlin. We’ll republish them soon.
b

bashor

01/16/2023, 8:36 PM
likely we will use the repo for some time for some kotlin/wasm artifacts, so if you have any issue with it or expect any please let us know
o

Oleg Yukhnevich

01/16/2023, 9:47 PM
what exactly is issue for you?
as mentioned upper, some artifacts were not available, and while I tried to ignore them and use latest kotlin dev (like 5***), there were errors with compilation regarding some WasmRef not available using kotlin 1.8.0 for one module, but 1.8.20 for other also could cause issues in my case…
maybe, but not as part of official coroutines releases
that’s ok for me, if they will be based on non-expirable kotlin builds, at least with latest kotlin dev version (in my case, it’s needed only for running suspend tests) P.S. Im working on MPP cryptography library, so supporting K/WASM out of the box (at least via JS interop with WebCrypto), when it will be alpha/beta/stable sounds just interesting for me
s

Svyatoslav Kuzmich [JB]

01/17/2023, 7:25 AM
A smaller example project that uses published coroutines: https://github.com/skuzmich/kotlin-wasm-browser-example
o

Oleg Yukhnevich

01/17/2023, 8:04 AM
Thx! Is it possible to add there example on how to configure tests for wasm in browser? (for nodejs it was easy to setup) Or it will work both ways with such webpack config?
s

Svyatoslav Kuzmich [JB]

01/17/2023, 8:31 AM
Tests don’t seem to work out of the box. The only place with browser tests I know is skiko, and it has some extra karma config.
o

Oleg Yukhnevich

01/17/2023, 8:33 AM
ok, thx!
486 Views