Hi! I'm trying to read a ZIP from within Wasm/JS. ...
# webassembly
p
Hi! I'm trying to read a ZIP from within Wasm/JS. I thought about using https://github.com/nodeca/pako through JS interop, however I'm getting the following problem when calling the library, the full stack trace is in the thread. The code is here. It's almost identical to what's done in Ashampoo's kim (code). @Stefan Oltmann maybe you have an idea what's wrong?
👀 1
Copy code
JsException: Exception was thrown while running JavaScript code

jarInspector.uninstantiated.mjs:128:1
    printError jarInspector.uninstantiated.mjs:128
    printError__externalAdapter ef33aed125668bddaa75.wasm:1214667
    printStackTrace ef33aed125668bddaa75.wasm:1264906
    doResume ef33aed125668bddaa75.wasm:2348882
    resumeWith ef33aed125668bddaa75.wasm:1231506
    resume ef33aed125668bddaa75.wasm:1741314
    dispatch ef33aed125668bddaa75.wasm:1740400
    dispatchResume ef33aed125668bddaa75.wasm:1631714
    resumeImpl ef33aed125668bddaa75.wasm:1632028
    resumeImpl$default ef33aed125668bddaa75.wasm:1632170
    resumeWith ef33aed125668bddaa75.wasm:1630566
    invoke ef33aed125668bddaa75.wasm:1661743
    notifyCompletion ef33aed125668bddaa75.wasm:1651623
    completeStateFinalization ef33aed125668bddaa75.wasm:1650590
    finalizeFinishingState ef33aed125668bddaa75.wasm:1649272
    continueCompleting ef33aed125668bddaa75.wasm:1658920
    invoke ef33aed125668bddaa75.wasm:1645135
    notifyCompletion ef33aed125668bddaa75.wasm:1651623
    completeStateFinalization ef33aed125668bddaa75.wasm:1650590
    finalizeFinishingState ef33aed125668bddaa75.wasm:1649272
    tryMakeCompletingSlowPath ef33aed125668bddaa75.wasm:1658575
    tryMakeCompleting ef33aed125668bddaa75.wasm:1658001
    makeCompletingOnce ef33aed125668bddaa75.wasm:1657719
    resumeWith ef33aed125668bddaa75.wasm:1619865
    resumeWith ef33aed125668bddaa75.wasm:1231761
    run ef33aed125668bddaa75.wasm:1739954
    process ef33aed125668bddaa75.wasm:1768678
    invoke ef33aed125668bddaa75.wasm:1774191
    invoke ef33aed125668bddaa75.wasm:1774201
    <jar-inspector>.kotlin.js.__callFunction_(()->Unit) ef33aed125668bddaa75.wasm:1214180
    kotlin.js.__convertKotlinClosureToJsClosure_(()->Unit)/< jarInspector.uninstantiated.mjs:126
    (Async: promise callback)
    createScheduleMessagePoster jarInspector.uninstantiated.mjs:1418
    kotlinx.coroutines.__callJsClosure_(()->Unit) jarInspector.uninstantiated.mjs:1419
    invoke ef33aed125668bddaa75.wasm:1774693
    invoke ef33aed125668bddaa75.wasm:1774702
    schedule ef33aed125668bddaa75.wasm:1774491
    enqueue ef33aed125668bddaa75.wasm:1768531
    dispatch ef33aed125668bddaa75.wasm:1767735
    safeDispatch ef33aed125668bddaa75.wasm:1737666
    resumeWith ef33aed125668bddaa75.wasm:1735850
    resumeWith ef33aed125668bddaa75.wasm:1232398
    invoke ef33aed125668bddaa75.wasm:2274997
    invoke ef33aed125668bddaa75.wasm:2275038
    <jar-inspector>.kotlin.js.__callFunction_((Js?)->Js?) ef33aed125668bddaa75.wasm:1215898
    kotlin.js.__convertKotlinClosureToJsClosure_((Js?)->Js?)/< jarInspector.uninstantiated.mjs:158
    (Async: promise callback)
    then_$external_fun jarInspector.uninstantiated.mjs:157
    then_$external_fun__externalAdapter ef33aed125668bddaa75.wasm:1215833
    invoke ef33aed125668bddaa75.wasm:2275357
    invoke ef33aed125668bddaa75.wasm:2275460
    doResume ef33aed125668bddaa75.wasm:2275676
    readChunk ef33aed125668bddaa75.wasm:2273771
    doResume ef33aed125668bddaa75.wasm:2274185
    resumeWith ef33aed125668bddaa75.wasm:1231506
    run ef33aed125668bddaa75.wasm:1739954
    process ef33aed125668bddaa75.wasm:1768678
    invoke ef33aed125668bddaa75.wasm:1774191
    invoke ef33aed125668bddaa75.wasm:1774201
    <jar-inspector>.kotlin.js.__callFunction_(()->Unit) ef33aed125668bddaa75.wasm:1214180
    kotlin.js.__convertKotlinClosureToJsClosure_(()->Unit)/< jarInspector.uninstantiated.mjs:126
    (Async: promise callback)
    createScheduleMessagePoster jarInspector.uninstantiated.mjs:1418
    kotlinx.coroutines.__callJsClosure_(()->Unit) jarInspector.uninstantiated.mjs:1419
    invoke ef33aed125668bddaa75.wasm:1774693
    invoke ef33aed125668bddaa75.wasm:1774702
    schedule ef33aed125668bddaa75.wasm:1774491
    enqueue ef33aed125668bddaa75.wasm:1768531
    dispatch ef33aed125668bddaa75.wasm:1767735
    safeDispatch ef33aed125668bddaa75.wasm:1737666
    resumeWith ef33aed125668bddaa75.wasm:1735850
    resumeWith ef33aed125668bddaa75.wasm:1232398
    invoke ef33aed125668bddaa75.wasm:2274997
    invoke ef33aed125668bddaa75.wasm:2275038
    <jar-inspector>.kotlin.js.__callFunction_((Js?)->Js?) ef33aed125668bddaa75.wasm:1215898
    kotlin.js.__convertKotlinClosureToJsClosure_((Js?)->Js?)/< jarInspector.uninstantiated.mjs:158
    (Async: promise callback)
    then_$external_fun jarInspector.uninstantiated.mjs:157
    then_$external_fun__externalAdapter ef33aed125668bddaa75.wasm:1215833
    invoke ef33aed125668bddaa75.wasm:2275357
    invoke ef33aed125668bddaa75.wasm:2275460
    doResume ef33aed125668bddaa75.wasm:2275676
    readChunk ef33aed125668bddaa75.wasm:2273771
    doResume ef33aed125668bddaa75.wasm:2274185
    resumeWith ef33aed125668bddaa75.wasm:1231506
    run ef33aed125668bddaa75.wasm:1739954
    process ef33aed125668bddaa75.wasm:1768678
    invoke ef33aed125668bddaa75.wasm:1774191
    invoke ef33aed125668bddaa75.wasm:1774201
    <jar-inspector>.kotlin.js.__callFunction_(()->Unit) ef33aed125668bddaa75.wasm:1214180
    kotlin.js.__convertKotlinClosureToJsClosure_(()->Unit)/< jarInspector.uninstantiated.mjs:126
    (Async: promise callback)
    createScheduleMessagePoster jarInspector.uninstantiated.mjs:1418
    kotlinx.coroutines.__callJsClosure_(()->Unit) jarInspector.uninstantiated.mjs:1419
high-level, what I'd like to achieve is inspecting a JAR from a browser app, use Kotlin for it, and avoid having to host a server with the JVM 😉 The fact that I'm using Pako and WasmJS is not something I'm tied to, I'm open to other approaches
t
Do you need all browsers support?
j
Okio has zip reading and wasm targets
👀 1
s
The Browser support library was added, so that’s not the issue. I’m glad that it works in Kim, but I don’t fully understand that. I had help from the community there. To me JS-interop is kind of a black box. The error messages from it are indeed not very useful. Is Okio also using Pako or did they implement native zlib support?
j
Hmm it may actually only be JVM+native because those are the two platforms which offer deflate out of the box
It's been a while since I've looked
s
Korge is the only lib with a pure Kotlin implementation I know of, but I can’t depend on a whole game engine with lots of other stuff.
j
Yep, just checked. JVM/native only, unfortunately
👍 1
s
@Sargun Vohra recently told me he’s going to port zlib C to pure Kotlin, so we may see soon see a lib solving that issue. https://kotlinlang.slack.com/archives/C0BJ0GTE2/p1752685072564719?thread_ts=1752655968.101249&channel=C0BJ0GTE2&message_ts=1752685072.564719
j
That's a pretty risky approach. And they're going to maintain fixes for life? Would rather just compile zlib directly and interop.
🤔 1
s
For that you have to know how to do that… and I have no idea. Maybe you should make a lib for that. 😄
I think if it’s once working a zlib lib won’t see too many changes… Pako isn’t changing much, too. And the Korge implementation works, too, I assume.
I just want my JS interop requirement to go away. If it goes wrong like in this case I have no idea where to look.
j
You can look at libraries like Skiko for how to embed native assets into Wasm. We only do it for JVM and native today, but it's probably not that dissimilar.
👀 1
s
I guess I wait until someone who really understands the stuff provides a zlib Multiplatform lib that does just that. I feel that more people need zlib.
@Sargun Vohra What do you think about that approach for your lib?
s
> That's a pretty risky approach. And they're going to maintain fixes for life? Would rather just compile zlib directly and interop. > I'm doing it this way because I'd like to better understand how deflate works, and I'm curious about how a pure kotlin implementation performs. Of course I can't commit to maintaining it myself for life, like all other volunteer open source work. It'll get maintained as long as anyone (including me) wants to use it and is inclined to do the work to maintain it. Agreed that for risk averse use cases, it's better to use a mature library with many maintainers, even if it results in more complex build logic. So yeah, embedding a wasm build of zlib in your kotlin wasm build is an interesting approach.
👍 1
m
Why not just use https://github.com/JetBrains/kotlin-wrappers/tree/master/kotlin-jszip? I have just done some experiments with it and it worked. I also used the approach via pako in some other project and it worked too but not the way you tried to do it. You first have to parse your ZIP file to get at an item stored inside it and once you have the bytes of this item isolated you can use Pako to inflate it. A ZIP (or JAR) file is a container and the items contained in it are deflated individually. In order to get that working I copied the ZIP code from Okio and just added the compression/decompression via Pako. That way I implemented the openZip function of Okio which returns a ZIP file system that you can then use like any other file system.
👍 1
t
Pako declarations will be available in next release. 😉
👍 3
🎉 3
s
That’s great 😀
t
Release
2025.8.2
with Pako is ready! 😉
K 2
Please share cool declarations with community 😉 Kotlin Wrappers infrastructure is ready for common (for Kotlin/JS and Kotlin/WasmJS) declarations.
m
Something went wrong here: https://github.com/JetBrains/kotlin-wrappers/blob/master/kotlin-pako/README.md The README.md is pointing to kotlin-vscode.
thank you color 1
1