andylamax
10/26/2021, 11:33 AMList<T>
on my @JsExport
models. Not only the fields mangled but it almost unusable in kotlin/js
.
At the moment I am exporting every List<T>
propery with a field that exposes an array, like so
class Person(val names: List<String> = listOf("John","Doe")) {
val namesArray get() = names.toTypedArray()
}
but that is now becoming tedious. So, any one experiencing this?
I wouldn't want my properties to not be Lists, but would need them to easily be consumable from the JS side when we export our library
I have a feeling if the kotlin-stdlib-js could export type bindings for all collections, List, Map, Set e.t.c, It could have been of much help. But I wanna know how others are tackling this.
Thoughs?hfhbd
10/26/2021, 11:38 AMArray
in the shared module, but this is also not perfect, because now equals does not use the content. So in every test we use toList
again.Grégory Lureau
10/26/2021, 11:39 AMclass Person(val names: List<String> = listOf("John","Doe")) // commonMain
// jsMain
@JsExport
class PersonJs(val names: Array<String>) {
@JsName("default") constructor() : this(listOf("John", "Doe"))
val namesArray get() = names.toTypedArray()
}
We're also working with KSP to auto-generate these facades as it's more complex if you want proper import/export behaviours.andylamax
10/26/2021, 11:41 AMandylamax
10/26/2021, 11:43 AMGrégory Lureau
10/26/2021, 11:43 AM// jsMain
@JsExport
class PersonJs internal constructor(val common: Person) {
@JsName("create") constructor(val names: Array<String>) : this(Person(listOf("John", "Doe")))
val namesArray get() = common.namesArray.toTypedArray()
}
To be honest we're not stable on what we really want on the facade. There are a lot of limitations we're learning (like for generics for example) and we need to have a proper understanding.
I'd love to open-source that when it's stable (don't expect a perfect solution but it may be a starting point).Grégory Lureau
10/26/2021, 11:44 AMandylamax
10/26/2021, 11:46 AMankushg
10/26/2021, 3:08 PMGrégory Lureau
10/26/2021, 6:34 PMankushg
10/26/2021, 6:37 PMGreg Steckman
10/27/2021, 2:59 AMankushg
10/27/2021, 3:00 AMandylamax
11/09/2021, 12:52 AMandylamax
11/09/2021, 12:56 AMimport kotlin.collections.Collection as KCollection
expect interface Collection<out E> : Iterable<E>, KCollection<E>
Collection.kt //JsMain
@file:JsExport
@file:Suppress("NON_EXPORTABLE_TYPE", "WRONG_EXPORTED_DECLARATION")
package kotlinx.collections.interoperable
import kotlin.collections.Collection as KCollection
actual interface Collection<out E> : Iterable<E>, KCollection<E> {
fun toArray(): Array<out E> {
val array: Array<in Any?> = Array(size) { null }
forEachWithIndex { e, index -> array[index] = e }
return array as Array<out E>
}
}
List.kt // CommonMain
@file:JsExport
@file:Suppress("NON_EXPORTABLE_TYPE", "WRONG_EXPORTED_DECLARATION")
package kotlinx.collections.interoperable
import kotlinx.collections.interoperable.serializers.ListSerializer
import kotlinx.serialization.Serializable
import kotlin.js.JsExport
import kotlin.collections.List as KList
@Serializable(with = ListSerializer::class)
interface List<out E> : Collection<E>, KList<E>
I also have MutableList<E>:List<E>
, have, Set
and MutableSet
as well. which do resemble the above code snippet.
I have tested this and it does work, and all my consumers just have to call toArray()
to fully easily use it with javascript/typescript.andylamax
11/09/2021, 12:58 AMkotlin.collections
.
I strongly believe this can be done in the stdlib and will surely ease the interop saga in the js communityandylamax
11/09/2021, 12:59 AMGrégory Lureau
11/09/2021, 9:35 AMankushg
11/09/2021, 5:21 PMGrégory Lureau
11/09/2021, 5:32 PMMyClass<MyData>
is fine, but MyClass<T: MyData>
is not) and it has a serious increase in JS bundle size due to multiple classes required for wrapping.
I think an even better approach could be to rework directly js and d.ts files directly : detect the unwanted types exposed in typescript and rewrote both files with a better facade without requiring a big increase in bundle size. No idea how to do that rn.goncalossilva
11/19/2021, 4:26 PMList
, interface
, and Long
). Are you planning to publish this? I've been trying to use this as source dependency or project dependency (via submodule).Grégory Lureau
11/19/2021, 4:30 PM