Hey, all. I have just added `js {}` compilation to...
# javascript
s
Hey, all. I have just added
js {}
compilation to my app. However, I have a class that asks for kotlin.time.Clock in its constructor. Obviously, when compiling, the compiler says:
Exported declaration uses non-exportable parameter type 'Clock'
What workarounds are there to solve this? I thought about adding
@JsExport.Ignore
to the constructor, create another constructor with
@JsExport
and asks for a
Double
maybe and then assign it to my clock. I am not sure if that's the best how to I have another <https://github.com/theodorosidmar/pubgkt/blob/chore/js/common/src/commonMain/kotlin/dev/pubgkt/RetryConfiguration.kt#L55|constructor asking for List<KClassout Throwable>> with the same problem. Not sure what to do here
b
Hi!
Obviously, when compiling, the compiler says:
Exported declaration uses non-exportable parameter type 'Clock'
Actually, this is not obvious at all 🙂 Which Kotlin version are you using? I don't see any
@JsExport
annotations, so the question is why does the compiler treat your class as exported?
s
Sorry. I have just pushed the changes. Now you can see it up to date I am using Kotlin 2.3.21
b
I thought about adding
@JsExport.Ignore
to the constructor, create another constructor with
@JsExport
and asks for a
Double
maybe and then assign it to my clock.
This looks like the correct workaround, I would go with it too. As for the
Retry
class, do you absolutely need to export the full constructor, including the
retryOnExceptions
parameter, to JS? If no, you can add a secondary constructor that doesn't include this parameter:
Copy code
@JsExport
public data class Retry @JsExport.Ignore constructor(
    val maxRetries: Int,
    val backoff: BackoffStrategy,
    val retryOnExceptions: List<KClass<out Throwable>>,
) : RetryPolicy {
    constructor(
        maxRetries: Int = 5,
        backoff: BackoffStrategy = NoBackoff,
    ) : this(maxRetries, backoff, emptyList())

    override val enabled: Boolean = true
}
s
Yes, nice catch. That's helpful. Thank you, my friend
It worked just fine for DelayRateLimiter. However, for Retry, compiler is still complaining about:
pubgkt/common/src/commonMain/kotlin/dev/pubgkt/RetryConfiguration.kt:60:5 Exported declaration uses non-exportable return type 'List<KClass<out Throwable>>'.
It seems
@JsExport.Ignore
does not work properly with `data class`es `constructor`s. I am going to need to come up with another solution
b
Oh, that's because the property
retryOnExceptions
should be marked separately:
Copy code
@JsExport
public data class Retry @JsExport.Ignore constructor(
    val maxRetries: Int = 5,
    val backoff: BackoffStrategy = NoBackoff,
    @JsExport.Ignore val retryOnExceptions: List<KClass<out Throwable>> = emptyList(),
) : RetryPolicy {
    ...
}
s
Oh '-'
Because that's a public property in an exported data class. That makes a lot of sense
👌 1
Actually nothing changed 😫
It's funny because the compiler actually outputs two errors: 1.
Exported declaration uses non-exportable return type 'List<KClass<out Throwable>>'
2.
Exported declaration uses non-exportable parameter type 'List<KClass<out Throwable>>'
b
This is strange indeed. Could you please create an issue? kotl.in/issue
s
Of course. Doing it now
b
I got it. This warning is about the synthetic
copy
and
componentN
functions that are generated by the compiler for data classes and that still use the non-exported type. The warning message could definitely be improved.
s
Hmmm makes sense. Those are actually warnings that become errors due to my configuration
kotlin { compilerOptions { allWarningsAsErrors = true } }
(reference)
Do you still want/need me to raise the ticket/issue?
b
What I would suggest you doing here is making the
Retry
class a regular class instead of a data class. As far as I can tell,
Retry
is part of the public API of your library, and we don't recommend using data classes in public API: https://kotlinlang.org/docs/api-guidelines-backward-compatibility.html#avoid-using-data-classes-in-your-api When you make
Retry
a regular class, you will have to explicitly define the
equals
,
hashCode
,
toString
,
copy
and
componentN
methods to preserve the behavior and source (and binary) compatibility.
Do you still want/need me to raise the ticket/issue?
Yes, please
s
Thank you for sharing about the usage of `data class`es in libraries/public apis. I appreciate.
Yes, please
Sure. But how would you like me to write it? As an issue "`@JsExport.Ignore` does not work properly with `data class`es members" or "the compiler warning message could be better" or something else?
b
The first one
✅ 1
s
• For Gradle problems, include a Gradle scan (
gradle build --scan
) in a comment with`jetbrains-team`visibility.
How can I do this?
I mean, I have the build scan here. I am asking about "jetbrains-team visibility"
b
It's good, thanks! No need for a Gradle scan, since this issue is easily reproducible even in the Kotlin playground.
s
Well, this is my first KMP library so I am kinda abusing/using/discovering everything I can lol
b
It's okay, no worries! 🙂 Thank you for taking your time, I appreciate it a lot.
s
Thank you, Sergej