When using Karakum, this: ```declare namespace inc...
# javascript
v
When using Karakum, this:
Copy code
declare namespace inc {
    type IdentifierBase = "0" | "1";
}
results in
Copy code
external object inc {
sealed external interface IdentifierBase {
companion object {
@seskar.js.JsValue("0")
val `0`: IdentifierBase
@seskar.js.JsValue("1")
val `1`: IdentifierBase
}
}
}
which does not compile due to "Non-top-level 'external' declaration.". What is the best way to solve this?
s
In Karakum I have 3 strategies to handle namespaces: 1.
package
- sub directory with name
inc
will be created and all code inside namespace will be put to separate Kotlin package 2.
object
- it is what you see now, unfortunately it is buggy 😞 I need to remove
external
modifier for such cases 3.
ignore
- namespase wrapper will be removed, and generator will just convert body of namespace
Do you want to continue with
object
strategy? or you need something else?
v
I'm not sure. :-D I use
semver
in my project, so tried to add it to
kotlin-wrappers
now. In my project I only defined the externals I used. Now I of course want to provide everything and currently try to make it compile at first and this is the next-to-last compile error I'm having. The ignore strategy I know how to use, for that there is a nice example in the readme. So I'm asking more in the context of kotlin-wrappers which best fits in / what is best-practice. :-)
t
IdebtiferBase must be on top level
v
"must be" because?
Or more like "should be in kotlin-wrappers"? :-)
s
Is limitation of
@seskar.js.JsValue
?
I published fix for Karakum that should fix compilation for provided example.
t
In most cases package - best solution
Because package - nearest analog of namespace
Single exclusion - namespace with simple function names, which clash with existed functions
s
BTW, we have similar problems with
node:test
package and
test.ignore(() => ...)
API, Now is is converted as package, but is is not so useful to be honest 🙂. I guess I need to fix it at some moment.
namespace with simple function names
could you provide example?
@Vampire I agree that for your use case
package
strategy is better for now. But I won't so sure, if you need to implement something like this
inc(...)
and
inc.unsafe(...)
. I am considering this, because I guess TS declaration for such case also will include namespaces:
Copy code
function inc(...): string | null

namespace inc {
  function unsafe(...): string | null
}
t
Common strategy If namespace doesn't contains functions with popular names like "it", "do", "sin", "cos" -
package
is your strategy. It's strategy for most wrappers
And it's your case ;)
v
If
package
is the proper choice in most cases, why is it not the default? 😄 Ok, so can you point me at an example - e. g. in kotlin-wrappers - how to follow the
package
strategy? Also, I didn't get what Sergei said about
inc.unsafe
t
package strategy examples:
Copy code
js.intl
js.atomics
In declarations both are namespaces
Use case, which describes Sergei - import
👌 1
gratitude thank you 1
Such cases exist, but it's not your case
s
Sorry for misleading 🙂 If you are looking for Karakum config, you can pay attention for
kotlin-node/karakum.config.json
, there is
namespaceStrategy
section, I guess in you case it should work:
Copy code
"namespaceStrategy": {
  "inc": "package"
}
v
Yeah, thanks package strategy fixed the compile error. Now to the other one. A mixture of compile error and unlucky character-substitutions.
Copy code
operator: "" | "=" | "<" | ">" | "<=" | ">=";
leads to
Copy code
/* export = Comparator; */
sealed external interface ComparatorOperator {
companion object {
@seskar.js.JsValue("")
val `_`: ComparatorOperator
@seskar.js.JsValue("=")
val : ComparatorOperator
/*
Duplicated names were generated:
 for "<"
 for ">"
 for "<="
 for ">="
*/
}
Which has two major problems. 5 values result in the same property name which is the empty name, and the empty string leads to an underscore as property name. Is there some similar case already where I can lend some fixup strategy?
s
Yea, it is known problem, unfortunately Kotlin/JS had problems with exotic names in external declarations, now maybe situation is better, we need more inverstigations. For now I do this for similar cases in Node js: 1. I declare type aliases for such unions: see
kotlin-node/src/jsMain/kotlin/node/path/PlatformPathSep.kt
and
kotlin-node/src/jsMain/kotlin/node/path/PlatformPathDelimiter.kt
2. I exclude this files from output, see
kotlin-node/karakum.config.json
Copy code
"ignoreOutput": [      
...  
    "**/path/PlatformPathDelimiter.kt", 
...  
]
so sourceset for external declarations in wrappers it is
generated
folder for generation output +
kotlin
folder for additional APIs and manual customization.
v
Ah, I see, excluding the files and providing a manual substitution. That might be a work-around. But now i'm short before making another PR where you can define a mapping in the config file for string union options in case you like it :-)
s
I think it is good improvements, I though about reusing of existing extension, like name resolver, but it seems it is separate task, so maybe additional extension point is better.
also it can be useful if you want to rename some class/interface member or even function, it can be solved using
@JsName
v
Hm, can I somehow get hold of
configuration
in a plugin?
Actually, in the
StringUnionTypePlugin
which is not really a plugin
Ah, found it I think
s
Yea, you need to use service locator
context
+
configuration
service
v
Yeah, that's what I found somwhere else, thx 🙂