So Iโ€™m trying to use JS -> Kotlin. But every ti...
# javascript
s
So Iโ€™m trying to use JS -> Kotlin. But every time I try and use a method the names are scrambled. I want to have
commonLib.myTestMap.get("key")
But the method available to me is
commonLib.myTestMap.get_11rb$("key")
Is there any way of having a standard getter for the keys in the map?
a
As far as I know there is no way to change the builtin Map member names. What you could do is create a proxy class and use
@JsName
to set the desired name manually. For example:
Copy code
class MapProxy<K, V>(private val map: Map<K, V>) {
    
    @JsName("get")
    operator fun get(key: K): V? = map[key]
}

fun main() {    
    val map = MapProxy(mutableMapOf<String, String>("a" to "b"))
    
    println(map["a"]) // JS: println(map.get('a'));
}
s
This could work for me, thank you! ๐Ÿ™‚ I'll let you know how I get on with it.
๐Ÿ‘ 1
a
By the way, could you briefly describe the way you use Kotlin/JS generated code from JS? Is this issue a matter of convenience (nobody wants to type
11rb$
)? Is there something more to this?
s
I'm building a multiplatform library for clients on JS, iOS and Android to cover the core networking layer for clients, so clean calls are essential ๐Ÿ™‚
It's published using NPM and will be the main library in the company. I've been tasked with unifying the FE codebases on all three platforms, so multiplatform was the way forward as far as I could see.
a
Understood. Clean API is vital indeed in this case.
s
I've chatted with all of our web teams and they are quite excited about the possiblity of building SDKs in kotlin. I think if the support or guidelines where in place, or even a tutorial, you would really push hard into the web world with KMP.
a
Great to hear that ๐Ÿ™‚ This use case seems to be exactly what we want to target. Could you also answer a few more questions? It'll be helpful for us to understand how well our anticipations map to the real world ๐Ÿ™‚ - Does your company already use Kotlin? On Android maybe? - Do you plan to use the resulting JS library from TypeScript? Is providing
.d.ts
declarations important for you? - Which ES standard do your web teams use? - How big do you think the library will get? - What layout do you have in mind for the library? (e.g. a single library, a bunch of small libraries, etc.) - How much effort do your web teams put into slimming down the resulting JS artifacts? - Do web teams need to use different parts of this common library? Will they need to be able to cut away the parts they don't use? - Is there something missing that's needed for your use case? Thanks!
s
Of course! All for the greater good
Copy code
- Does your company already use Kotlin? On Android maybe?
We are a 100% kotlin codebase on Android. We also have some Spring Servers written in Kotlin, Iโ€™m looking to introduce Ktor in the coming months as a Server Framework.
Copy code
- Do you plan to use the resulting JS library from TypeScript? Is providing .d.ts declarations important for you?
All our codebases are in JS at the moment. I have been put in charge of the architecture of the system. With that said, we are moving everything to TS. I dont want to see JS next year, im looking to achieve TS and Kotlin everywhere. The web team share a similar mindset.
Copy code
- Which ES standard do your web teams use?
We build with ES6 and webpack bundles it for ES5
Copy code
- How big do you think the library will get?
Currently, its all business logic, we need to make it as small as possible. But we want webpack to clean it up for us on the client side. So lib size is important but not the end of the world if its a little larger than normal. This should also shrink with Kotlin 1.4.0
Copy code
- What layout do you have in mind for the library? (e.g. a single library, a bunch of small libraries, etc.)
We will have one large core lib but can consider pulling this out into smaller libs for features such as Analytics and Feature Flagging, this would help other teams, we can use these libs to create a larger core SDK for clients.
Copy code
- How much effort do your web teams put into slimming down the resulting JS artifacts?
We dont currently have any JS SDKโ€™s in the company but we are a platform company so its definitely needed. We treeshake with webpack as far as I know.
Copy code
- Do web teams need to use different parts of this common library? Will they need to be able to cut away the parts they don't use?
There is about 4 web teams working on different projects, so cutting the parts they dont need can be beneficial over all to allow other teams use the features they need.
Copy code
- Is there something missing that's needed for your use case?
Yes, there is no clean way of creating a NPM module to be used with JS. What I have found is that the minified version of Kotlin.js cannot be used with web, the variables are unable to be accessed without object functions. Ill post a snipped before and after.
๐Ÿ‘ 2
This is the output of a very simple module that only contains vars. With this code we cannot access them in JS.
Copy code
(function (root, factory) {
  if (typeof define === 'function' && define.amd)
    define(['exports', 'kotlin'], factory);
  else if (typeof exports === 'object')
    factory(module.exports, require('kotlin'));
  else {
    if (typeof kotlin === 'undefined') {
      throw new Error("Error loading module 'common'. Its dependency 'kotlin' was not found. Please, check whether 'kotlin' is loaded prior to 'common'.");
    }root['common'] = factory(typeof this['common'] === 'undefined' ? {} : this['common'], kotlin);
  }
}(this, function (_, Kotlin) {
  'use strict';
  var hello;
  hello = 'HELLO WORLD';
}));
But if I bundle them with the unzipped jar version they can be accessed. This is the unzipped jar output.
Copy code
(function (root, factory) {
  if (typeof define === 'function' && define.amd)
    define(['exports', 'kotlin'], factory);
  else if (typeof exports === 'object')
    factory(module.exports, require('kotlin'));
  else {
    if (typeof kotlin === 'undefined') {
      throw new Error("Error loading module 'common'. Its dependency 'kotlin' was not found. Please, check whether 'kotlin' is loaded prior to 'common'.");
    }root['Kcommon'] = factory(typeof this['common'] === 'undefined' ? {} : this['common'], kotlin);
  }
}(this, function (_, Kotlin) {
  'use strict';
  var name;
  Object.defineProperty(_, 'hello', {
    get: function () {
      return hello;
    },
    set: function (value) {
      hello = value;
    }
  });
  hello = 'HELLO WORLD';
  Kotlin.defineModule('common', _);
  return _;
}));
We had another issue with
require(kotlin)
and had to write a script to bundle all the deps correctly. It was still pulling in the full kotlin lib in the client so I had to iterate over all the files and replace any
require(kotlin)
with
require(./kotlin.js)
. There was a lot of moving dependacies to create a working output. It would be great if this just happened for us. Or even guidance on how we should do this would help a lot. Here is the script.
Copy code
tasks {
    register("buildNpm") {
        doLast {
            copy {
                from(zipTree("$buildDir/libs/common-js-$version.jar"))
                eachFile {
                    filter { line ->
                        line.replace("require('kotlin')", "require('./kotlin.js')")
                    }
                }
                into("$buildDir/npm")
            }
            copy {
                from("${rootProject.buildDir}/js/packages/common/kotlin-dce/kotlin.js")
                into("$buildDir/npm")
            }
        }
    }
    named("buildNpm") {
        dependsOn("jsJar", "processDceJsKotlinJs")
    }
    named("build") {
        dependsOn("buildNpm")
    }
}
As you can see this is not ideal. But I am a huge Kotlin avocate. and I really want this to work for us so any help at all would be greatly appreciated. I was also chatting to @Sebastian Aigner on this issue and raised the same concerns.
๐Ÿ‘ 1
a
Thank you very much for your answers. Looks like your use case is moreless aligned with our expectations. If everything goes according to plan, we should be able to make your experience better in the future.
๐Ÿ‘ 1
Regarding the issues with NPM. Looks like the DCE cuts out the property exports. I don't think that is supposed to happen, could it be misconfigured somehow?
@Ilya Goncharov [JB] could you take a look? Does this look like a configuration problem?
i
Yes of course, I would like to see relevant part of build script, related with kotlin extension Something like
Copy code
kotlin {
    js {
       browser {
          ...
       }
    }
}
s
This is my gradle config currently.
Copy code
import org.jetbrains.kotlin.gradle.plugin.mpp.Framework
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget

plugins {
    id("com.android.library")
    id("org.jetbrains.kotlin.multiplatform")
    id("org.jetbrains.kotlin.native.cocoapods")
    id("kotlin-dce-js")
}

version = Versions.cocoapodVersion

kotlin {

    cocoapods {
        summary = "Shared Code for Android and iOS"
        homepage = "Link to a Kotlin/Native module homepage"
    }

    android()
    
    js() {
        targets {
            browser {
//                @Suppress("EXPERIMENTAL_API_USAGE")
//                dceTask { keep("kotlin.defineModule") }
            }
        }
    }

    val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
        if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
            ::iosArm64
        else
            ::iosX64

    iOSTarget("ios") {
        compilations {
            val main by getting {
                kotlinOptions.freeCompilerArgs = listOf("-Xobjc-generics")
            }
        }
    }

    sourceSets["commonMain"].dependencies {
        implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:${Versions.coroutinesCore}")
        implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:${Versions.serializationCommon}")
        implementation("io.ktor:ktor-client-core:${Versions.ktor}")
        implementation("io.ktor:ktor-client-json:${Versions.ktor}")
        implementation("io.ktor:ktor-client-serialization:${Versions.ktor}")
        implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
    }

    sourceSets["iosMain"].dependencies {
        implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-native:${Versions.coroutinesCore}")
        implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:${Versions.serializationCommon}")
        implementation("io.ktor:ktor-client-ios:${Versions.ktor}")
        implementation("io.ktor:ktor-client-json-native:${Versions.ktor}")
        implementation("io.ktor:ktor-client-serialization-native:${Versions.ktor}")
        implementation("org.jetbrains.kotlin:kotlin-stdlib")
    }

    sourceSets["jsMain"].dependencies {
        implementation(kotlin("stdlib-js"))
    }
}

android {
    compileSdkVersion(App.compileSdk)

    sourceSets {
        getByName("main") {
            manifest.srcFile("src/androidMain/AndroidManifest.xml")
            java.srcDirs("src/androidMain/kotlin")
            res.srcDirs("src/androidMain/res")
        }
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.coroutinesCore}")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:${Versions.serializationCommon}")
    implementation("io.ktor:ktor-client-android:${Versions.ktor}")
    implementation("io.ktor:ktor-client-json-jvm:${Versions.ktor}")
    implementation("io.ktor:ktor-client-serialization-jvm:${Versions.ktor}")

    implementation("androidx.lifecycle:lifecycle-extensions:${Versions.lifecycleVersion}")
    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:${Versions.lifecycleVersion}")

    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("androidx.core:core-ktx:+")
}

tasks {
    register("buildNpm") {
        doLast {
            copy {
                from(zipTree("$buildDir/libs/common-js-$version.jar"))
                eachFile {
                    filter { line ->
                        line.replace("require('kotlin')", "require('./kotlin.js')")
                    }
                }
                into("$buildDir/npm")
            }
            copy {
                from("${buildDir}/kotlin-js-min/js/main/kotlin.js")
                into("$buildDir/npm")
            }
        }
    }
    named("buildNpm") {
        dependsOn("jsJar")
    }
    named("build") {
        dependsOn("buildNpm")
    }
}
I had used DCE with the EAP version of kotlin 1.3.70 but I had issues with autocomplete on the other targets, switching back to 1.3.61 sorted this, but now the DCE task is not available. This means my gradle task doesnt work because the DCE kotlin.js is ripping out
defineModule
i
So if you want dce to save declaration
hello
you need to add it to keep
keep(<module-name>.<package>.hello)
where
<module-name>
is file which is produced in
build/js/packages
, usually is
<root-project>-<project-name>
s
I would, but dceTask doesnt exist when I try with 1.3.61
e
Could there be an issue with the way you're defining the version? I had a working build which is pretty similar to yours, but it broke once I added the nebula release plugin:
Copy code
plugins {
    id("org.jetbrains.kotlin.multiplatform") version "1.3.70-eap-274"
    id("nebula.release") version "13.0.0"
}
It's as if
js.browser.dceTask { keep(...) }
is simply not there anymore.
s
I had a pretty clean root gradle file.
Copy code
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {

    repositories {
        google()
        jcenter()
        mavenCentral()
    }

    dependencies {
        classpath("com.android.tools.build:gradle:${Versions.gradle}")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}")
        //classpath("org.jetbrains.kotlin:kotlin-frontend-plugin:${Web.frontEndPlugin}")

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle.kts files
    }
}

allprojects {

    repositories {
        google()
        jcenter()
        mavenCentral()
    }
}
e
For me, just commenting out the nebula.release plugin makes
keep
work again. Dce works either way, but
kotlin.defineModule
is not kept.
๐Ÿ‘ 1
s
Copy code
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {

    repositories {
        google()
        jcenter()
        mavenCentral()
        maven(url = "<https://dl.bintray.com/kotlin/kotlin-eap>")

    }

    dependencies {
        classpath("com.android.tools.build:gradle:${Versions.gradle}")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}")
        //classpath("org.jetbrains.kotlin:kotlin-frontend-plugin:${Web.frontEndPlugin}")

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle.kts files
    }
}

allprojects {

    repositories {
        google()
        jcenter()
        mavenCentral()
        maven(url = "<https://dl.bintray.com/kotlin/kotlin-eap>")
    }
}
This was my EAP setup
Ok, tried again and found my issue. I didnt have the 1.3.70 compiler installed in the IDE. Needs to be set from the Kotlin compiler page.
a
^^ @Ilya Goncharov [JB] is this how it is supposed to work?
i
I think, that compiler in IDE should not matter, because you can use terminal to build Gradle
โ˜๏ธ 1
s
I think this is correct. The issue was, when you pull everything from the EAP in the gradle files, and compile it still uses the
1.3.61
. But once set to use the beta
1.3.70-eap
. Changing this actually sorted the autocomplete issue when I was using AS with iOS. I agree upon build of the gradle file from term it didnt complain.
๐Ÿ†— 1
๐Ÿ™ 1
e
This thread covers several different issues, but regarding the missing
Kotlin.defineModule
(under certain circumstances, in spite of
keep("kotlin.defineModule")
), I ended up just hacking this into the task that assembles my npm module with bits and pieces from the
nodejs
and
browser
tasks:
Copy code
copy {
    from("$buildDir/js/packages/${rootProject.name}/kotlin-dce/kotlin.js") {
        filter { it.replace("var _ = Kotlin;", "var _ = Kotlin; Kotlin.defineModule = function (id, declaration) {};") }
    }
    into("$buildDir/npm")
}
Hopefully not a long-time solution, but it works for me for now. I haven't figured out why
keep
breaks with the nebula release plugin.
s
Where did you put this? In the buildNPM script? Does this prevent the
kotlin.defineModule
from being removed?
e
I put it in a custom task in
build.gradle.kts
. No, it doesn't prevent it from being removed, but it adds it back in into the DCE-ed
kotlin.js
. It's just an empty function in the working DCE-ed
kotlin.js
too, so it might be better to just remove it from the generated project js, but this is less code, since
kotlin.js
needs to be copied anyway.
a
@Eivind Nilsbakken Why do you care about
Kotlin.defineModule
being removed? Are you coupling a DCE-ed
kotlin.js
with a non-DCE-ed module?
e
Yes, that's exactly why. I need the DCE-ed
kotlin.js
from
browser
for creating a
nodejs
module which is to be used outside of a kotlin multiplatform project, and the non-DCE-ed
kotlin
dependency is a hefty 2MB.
๐Ÿ‘ 1
If there are better ways to achieve this, I'd be happy to learn how.
a
Sorry, I'm not sure I understand. Where do the non-DCE-ed modules come from? How do you know the non-DCE-ed module won't use some other random API from
kotlin.js
?
e
There's only my own generated module and its dependency on
kotlin
in the non-DCE-ed result of the
nodejs
target. I'd expect to be able to make it work by adding other random API-calls to
keep
, but as I mentioned that broke when I added a dependency on the nebula release plugin, for reasons that remain a mystery to me. I'm not sure how to explain it better, but I have a demo project on GitLab: https://gitlab.com/fleskesvor/tabletop-enums
s
By unzipping the
common.jar
The reason for this is as explained above. The variables from the DCE'd common code cannot be accessed from JS. But when bundled with Kotlin it becomes over 2mb in size. So by using the DCE version of Kotlin and the unzipped Jarg version of common it results in a lib which is a fraction of the size. As Eivind has said above, if there is a better way of doing this or even a web-pack sample for treeshaking on the client side, please let us know.
โ˜๏ธ 1
a
Ah, I think get it now. Sorry, this is a long thread, I must have already forgotten where it all started from. Let me ask a few questions to verify. So for various reasons the
keep
feature didn't work for both of you, so you coupled the non-DCE'd module output with the DCE'd
kotlin.js
as a workaround, didn't you? Interesting! @Sean Keane does updating the plugin to 1.3.70-... fix this issue for you (i.e. let you use the
keep
feature to prevent DCE from removing the exported `var`s) ? @Eivind Nilsbakken is this "nebula release plugin" breaks the
keep
feature issue present in the
tabletop-enums
project?
๐Ÿ‘ 1
s
Yes, I have now updated to
1.3.70-eap
correctly and it has sorted the issue with autocomplete in iOS and
dceTask { keep "" }
That is exactly what we did. The JS variables where not accessible so by using the non-DCE'd module with the DCE'd kotlin we could keep all dependencies within the one module with a large reduced size.
๐Ÿ™ 1
๐Ÿ‘ 2
e
@anton.bannykh Yeah, that's a good summary. ๐Ÿ™‚ I don't think it's the only issue Sean has presented in this thread, but it's the one we have in common (I only have use for JVM and Javascript/Typescript targets). The issue with the nebula release plugin is currently present in head of
master
. If you comment it out from
build.gradle.kts
, you will get a working build in
build/npm
, which you can
npm link
with other projects.
a
I see!
i
@Eivind Nilsbakken Why do you copy content to
npm
folder not from
kotlin-dce
like
kotlin.js
but from
.jar
It seems, that you can copy from
kotlin-dce
and everything should work
a
@Ilya Goncharov [JB] As far as I know for some reason the
keep
doesn't work, and as a result all exports are removed.
e
That's a good question. I think there was a reason for it, but it could just be that I expected
nodejs
to be made for my use-case, realized it wasn't, and ended up adding more and more hacks. I'll have to check, but I don't think
kotlin-dce
includes any
package.json
at least. Not even the one from my
resource
directory.
s
Hitting a world of hurt also with dependency issues when trying to make a network request. Seems non of the networking libs for 1.3.70 are available on NPM and I keep getting this error.
Copy code
Could not determine the dependencies of task ':kotlinNpmInstall'.
> org.jetbrains.kotlin.gradle.targets.js.npm.KotlinNpmResolutionManager$ResolutionState$Installed cannot be cast to org.jetbrains.kotlin.gradle.targets.js.npm.KotlinNpmResolutionManager$ResolutionState$Configuring
this is the gradle dependencies for JS.
Copy code
sourceSets["jsMain"].dependencies {
        implementation(kotlin("stdlib-js"))
        implementation("io.ktor:ktor-client-js:${Versions.ktor}")
        implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:${Versions.coroutinesCore}")
        implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:${Versions.serializationCommon}")
    }
I've tried bundling them but there is a lot of issues here.
Strange... switching back to 1.3.61 seems to have rectified. I also ran kotlinNpmInstall before build.
@anton.bannykh @Ilya Goncharov [JB] @Eivind Nilsbakken I've just tried to add a simple network request, unfortunatly with my set up there are so many dependencies that are needed to be pulled from NPM. Also the amount of scripting work to do in order to pull bundle local libs is insane. I went in and done this manually and checked it out. Ended up with Coroutine scope issues thanks to ktor. Unless there is a clear path forward for this, I really don't think it will work in a scalable manner. Is there any advice at all that can help with this as I would really like to make it work as a true cross platform library? Another issue I spotted that event when you allow the client to handle the dependencies (not bundled with the npm lib) they are not available on the NPM channel. So
npm update
consistently fails to resolve. Fixing the NPM issue is the only way I can see this moving forward, allowing
webpack
to do all the treeshaking on the client side to reduce the size. But this means the libs need to be npm available? unless I'm missing something?
e
@Ilya Goncharov [JB] I replaced the unzipped content from the
.jar
with the contents of
kotlin-dce
. This doesn't take me all the way, but as you suspected, at least I don't need to add
keep('kotlin.defineModule')
to my dce config. I do however have to explicitly
keep
my own package (
keep("<http://tabletop-enums.com|tabletop-enums.com>.fleskesvor.tabletop")
. Otherwise, my package hierarchy is declared within the generated module, but never populated and never exported, ie. like this:
Copy code
var Enum = Kotlin.kotlin.Enum;
  var Kind_CLASS = Kotlin.Kind.CLASS;
  var throwISE = Kotlin.throwISE;
  var Kind_OBJECT = Kotlin.Kind.OBJECT;
  var Type$BOARDGAME_instance;
  var Type$CARDS_instance;
  var Type$DICE_instance;
  var Suit$CLUBS_instance;
  var Suit$DIAMONDS_instance;
  var Suit$HEARTS_instance;
  var Suit$SPADES_instance;
  var Platform_instance = null;
As before, enabling the
nebula.release
plugin has the effect of breaking the configuration of
keep
, which is an effect that is still present on my new
HEAD
of
master
. (So one must comment out that plugin,
./gradlew build
and set a valid version in
build/npm/package.json
to be able to
npm link
my test project.) Additionally,
kotlin-dce
does not contain a
package.json
out of the box, nor is
src/jsMain/resources/package.json
copied over, so I have to do that in a custom task. I also still need that copy task for
src/jsMain/resources/index.js
since I don't want my consumers to have to "unwrap" my exported module. Another interesting find is that even the generated module in
kotlin-dce
doesn't actually use the DCE-ed
kotlin.js
, so I still need Sean's hack of replacing occurences of
require('kotlin')
with
require('kotlin.js')
. This can easily be verified by testing the module with
npm link
with that replacement commented out, in which case any use of it will fail with a
MODULE_NOT_FOUND
, since no dependency on
kotlin
is added to my
package.json
. Adding that dependency will pull in the full
kotlin
dependency, which will result in a full weight of 2.0M of the full module, vs. only 115K with the DCE-ed
kotlin.js
(sizes of a bundle with
@zeit/ncc
). By the way, there seems to be an inconsistency/error in the DCE documentation on https://kotlinlang.org/docs/reference/javascript-dce.html: The described syntax
moduleName.dot.separated.package.name.declarationName
works (though
declarationName
doesn't seem to be necessary, if you want to keep everything from a package), but the example
kotlin-js-example_<http://main.org|main.org>.jetbrains.kotlin.examples.toKeep
has an underscore in place of the dot to separate module and package name, which doesn't seem to work for me, unless I'm misunderstanding something. ๐Ÿค”
i
Ohh I see, you want to use DCE in case of nodejs. It is not good integrated for nodejs. Because we think, that size is not so matter in case of nodejs. Although this case is not covered yet, you can build โ€œbrowserโ€ version of your library, which is minified also, including webpack stage (in 1.3.70 it will be library-like). But you need to explicitly set all you api in
keep
declarations But personally I do not recommend provide public JavaScript API of your library with Kotlin-specific types like Enums, and etc, because it is not JavaScript way, better to use JavaScript native types like arrays, primitives objects and so on. Because if user of your library will use
Enum
from your library, and will use other Kotlin/JS based library with Enum too, these two enums will be different enums in JavaScript virtual machine, which can lead to problem in runtime (with
instanceof
for example)
e
Yeah, that's exactly it. My reasoning is that size matters as long as it's not a dev dependency, since otherwise I'll have to rely on the tree-shaking of my consumer applications, though maybe that is widespread and mature enough to not be a problem. I prefer the Enums over native types because of my Java consumers, but I agree that it would be better for Javascript consumers with native types. In one of my POCs I use my
index.js
to recurse over the generated object to be able to export a similar object with native types instead, which is a solution I'm leaning towards. I'd prefer if I could somehow do this in Kotlin, but I haven't found a good way to do this, other than
expect
/`actual` and a bunch of duplication + transformation throughout the specific platform sources. The dce is from the
browser
version, by the way, since there's no dce in
nodejs
. EDIT: This seems almost exactly like what I'm hoping to achieve with my test use-case: https://kotlinlang.slack.com/archives/C0B8L3U69/p1533092140000170 Though it doesn't seem like
inline enum class
is supported yet, as of 1.3.70-eap-184.
s
In one of my POCs I use my
index.js
to recurse over the generated object to be able to export a similar object with native types instead, which is a solution I'm leaning towards
If you succeed in exposing the JS object from a Kotlin codebase let me know ๐Ÿ˜‚
e
Well, it's kinda working without it, but I'd prefer if I could somehow "decouple" the JS object from the enums in Kotlin: https://npm.runkit.com/tabletop-enums
Copy code
var te = require("tabletop-enums")

console.log(te.enums.type.BOARDGAME);
console.log(te.enums.card.suit.HEARTS);
I have the recursion in
index.js
stashed on a different computer, but it's pretty basic stuff.
335 Views