In the end I scrapped the idea of using kotlinx-se...
# javascript
e
In the end I scrapped the idea of using kotlinx-serialization to transform Kotlin classes to and from JS plain objects. The library was adding 350kb to the final bundle size, with the only benefit of encoding to and from
dynamic
. I'm trying to implement a comparable solution with KSP, that is, for each annotated class generating an external declaration + to/from converter functions. This seemed like the most optimal solution in terms of time and effort. Maybe this kind of stuff could be part of the plain object plugin?
a
How would it look like?
e
Something like what you do with external interfaces could be a valid idea I think. E.g. given:
Copy code
@JsExport
@JsSerializable // Marker annotation
class Example(val one: Int, val two: String)
We end up with the compiler plugin adding in a companion + the external interface:
Copy code
@JsExport
@JsSerializable // Marker annotation
class Example(val one: Int, val two: String) {
  companion object {
    fun toJso(value: Example): ExampleJso { ... }
    fun fromJso(jso: ExampleJso): Example { ... }
  }
}

// External added by compiler
@JsExport
external interface ExampleJso {
  val one: Int
  val two: String
}
This is invisible on the Kotlin side, but visible from JS/TS.
a
Interesting. And what use case do we cover with such conversions?
e
Being able to serialize and deserialize Kotlin classes, to for example, transfer them via
postMessage
. The fact an external interface is generated automatically means I don't have to create one myself on the TS side.
I'll post what I currently do on our project later, need to go grab a pizza 🍕
kodee loving 2
t
@Edoardo Luppi we already added
Serializable
marker interface in Kotlin Wrappers 😉. For future more strict API (
postMessage
for example).
Case, which you describe, looks like typical serialization use case. It has no sense to duplicate library and plugin one more time.
It would be better to check root cause of "big bundle" problem
e
t
I understand the problem - we already have such problem in other places in browser and Node.js
And
kotlinx-serialization
looks like common solution for them
e
The serialization library does not provide the plain type tho, it simply let's you serialize to
dynamic
, and deserialize from
dynamic
without any sort of type safety. I still need to manually code dozens of types in TS to represent the plain objects. Add in the size factor, and that's why I'm going down the KSP route.
t
Do you use enums in DTOs?
e
Sometimes, yes. I currently map them to strings on the TS side.
t
Serialization to JSO costs 55KB at start and looks like it can be optimized
And even 50KB with
whole-program
granularity
a
Please note that Js already has the implicit toJSON method. I’d always favor that.
e
toJSON
is mainly used to serialize to a string tho, not an object.
a
True, it is called by JSON.stringify but is used in order to create a transferrable object for any object or class.
e
I would prefer to have functions reusable in different contexts to be honest, instead of a single one.
a
that makes sense
e
@turansky thanks for the sample! I've also noticed that whole-program brings the size down quite a bit. That sample tho still has the problem of not having an
external interface
that maps to the DTO class, that's probably the most frustrating part to code manually.
t
@Edoardo Luppi there are 3 different scenario for JSO, which we already have in browser
Which of them do you need? 😉