Give me a little reminder please. If I have a `Dic...
# javascript
v
Give me a little reminder please. If I have a
Dict
subinterface that I need to give as argument, how do I properly construct it? In this case it is the
external interface OutgoingHttpHeaders : Dict<dynamic /* Number | String | Array<String> */>
from
kotlinx-nodejs
t
For latest OutgoingHttpHeaders you can use
Record
factory function
v
Ah, so
kotlin-node
is kind of successor of
koltinx-nodejs
I guess? Well keep in mind when I go to newer Node. I guess the
kotlin-node
version corresponds to the Node.js version? Because currently I'm on Node.js 12 and only have the choice between 12 and 16, as it is about a GitHub Action. For now I solved it using
Copy code
fun Map<String, Any>.asOutgoingHttpHeaders() = asDynamic().unsafeCast<OutgoingHttpHeaders>()
t
Ah, so
kotlin-node
is kind of successor of
koltinx-nodejs
I guess?
In some way
I guess the
kotlin-node
version corresponds to the Node.js version?
@types/node
version used
Because currently I’m on Node.js 12 and only have the choice between 12 and 16, as it is about a GitHub Action.
16 - current LTS πŸ™‚
For now I solved it using
Copy code
fun Map<String, Any>.asOutgoingHttpHeaders() = asDynamic().unsafeCast<OutgoingHttpHeaders>()
Map
!=
Record
(JSO)
v
16 - current LTS πŸ™‚
When I wrote the action only 12 was available. 🀷
Map
!=
Record
(JSO)
Well, it works as expected according to my tests. :-)
t
Map
- Kotlin Map?
v
Yes
t
image.png
v
Well, I derived it from the previous
Copy code
fun Map<String, Any>.asIHeaders() = asDynamic().unsafeCast<IHeaders>()
that I created with the help of you afair πŸ™‚
Ah, no, it was not you but araqnid (https://kotlinlang.slack.com/archives/C0B8L3U69/p1597445606499200). And of course I should also add the
asDynamic
πŸ˜„
Copy code
fun Map<String, Any>.asOutgoingHttpHeaders() = asDynamic().unsafeCast<OutgoingHttpHeaders>()

fun <V> Map<String, V>.asDynamic() = jsObject<dynamic> {
    for ((name, value) in this@asDynamic) {
        this[name] = value
    }
}
t
when Node.js 18 enters long-term support (LTS) later this month
https://nodejs.org/en/blog/announcements/v19-release-announce/
In
kotlin-wrappers
we provide many additional types for strict JS interop. As result - you can avoid
asDynamic()
and
unsafeCast()
usages (like in case above 😜)
πŸ‘Œ 1
v
Hm, GitHub stops supporting node 12, but does not yet support node 18, so just node 16. But kotlin-node just provides node 17 and node 18. So what should I use for node 16? Still continue using koltinx-nodejs? And btw. will kotlin-node ever leave pre-state? πŸ˜„
t
But
kotlin-node
just provides node 17 and node 18.
We support Node 16 as minimum version
So what should I use for node 16?
In case of wrappers 18 = 16+ You will see some new API, but most of them marked with
@since
tag
And btw. will kotlin-node ever leave pre-state? πŸ˜„
Yes, when we will find better versioning scheme for our use case (NPM version + wrappers build or version). Do you have ideas? πŸ™‚
v
We support Node 16 as minimum version
Oh really? But I only have seen 17 and 18 versions on Maven Central
In case of wrappers 18 = 16+
You will see some new API, but most of them marked with
@since
tag
Oh, I see, great. I thought you need the version matching your node version. Then I'll probably switch of course. For now it actually worked without any code change and just changing node version to 16 πŸ™‚
Do you have ideas?
Probably none you didn't have yet. <npm version>-<your release as increasing number> or something like that. But maybe I just cannot think, it's 4 AM. Just wanted to quickly get rid of the issue ticket. πŸ˜„
t
@Vampire FYI - we have
suspend
adapters for converted promise API in
kotlin-node
. For example for
fs
module API
v
Mind elaborating what you mean?
t
v
So like
mkdirSync
in
kotlinx-nodejs
, isn't it?
t
In
mkdirSync
- synchronous API Inside
mkdir
we use asynchronous API (
mkdirAsync
)
v
Well, then like
mkdir
, isn't it? Or what do I miss? πŸ™‚
Ah, now I see it. That returns a
Promise
and you abstract that away πŸ‘Œ
😜 1
What are the
...-compat
versions?
t
AFAIK It’s the same build, but with
Copy code
kotlin.mpp.enableCompatibilityMetadataVariant=true
option.
v
I see, just wondered because not every version has that variant, thx
Back, kind of, to the original topic. I'm currently finally trying to migrate from
kotlin-extensions
and
kotlinx-nodejs
to
kotlin-js
and
kotlin-node
, so I might come back with some more question if you don't mind. πŸ™‚
The
OutgoingHttpHeaders
I was now able to do using
Copy code
additionalHeaders = Record<String, String> {
    set("Content-Type", "application/x-www-form-urlencoded")
}
That's the intended way and what you meant, correct?
πŸ‘Œ 1
t
Factory, which we discuss right now:
Copy code
additionalHeaders = recordOf(
    "Content-Type" to "application/x-www-form-urlencoded",
)
v
Argh, I should read properly. Seen it, liked it, changed my code, wondered I don't find it, then seen that you said this is an idea for the future. πŸ˜„
Ok, next is, I call
exec(...)
from
@actions/exec
. That needs an
ExecOptions
so I now do
options = jso { ... }
instead of
options = jsObject { ... }
, right?
πŸ‘Œ 1
Now the
ExecOptions
need (or I need to set it)
env
of type
tsstdlib.T$2
which comes from
lib.es5.kt
and is defined as
Copy code
external interface `T$2` {
    @nativeGetter
    operator fun get(key: String): String?
    @nativeSetter
    operator fun set(key: String, value: String)
}
What is the correct way here? In approximation of my old code mentioned above, I'd guess
Copy code
env = Record<String, String> {
    set("DEBIAN_FRONTEND", "noninteractive")
    set("WSLENV", "DEBIAN_FRONTEND/u")
}.unsafeCast<`T$2`>()
?
t
T$2
is effectively
Record
- could you replace it?
v
It's probably coming from Dukat, but I have a "fix the result up" procedure, so I guess I could.
t
ReadonlyRecord
looks like better replacement πŸ˜‰
recordOf
will return it
v
So I would in the
ExecOptions
replace
Copy code
var env: `T$2`?
    get() = definedExternally
    set(value) = definedExternally
by
Copy code
var env: js.core.ReadonlyRecord<String, String>?
right?
t
Yes
Analog from JVM world
Map
->
ReadonlyRecord
MutableMap
->
Record
v
Great, now I can even do
env = Record {
without type arguments πŸ™‚
t
recordOf
is ready
Will be available in
pre.488
❀️ 1
Great, now I can even do
env = Record {
without type arguments πŸ™‚
recordOf
v
Sure, when 488 is available πŸ™‚
Hm, where is
node.fs.readdir
?
And is there some way to make Dukat use the new wrappers classes? Now various of the generated classes use
http.IncomingMessage
,
http.OutgoingHttpHeaders
,
url.URL
, and so on which are all in other packages now. Or do I need to add the import-fixing to my post-processing step?
t
Which NPM libraries do you need?
v
Copy code
implementation(npm("@actions/cache"))
    implementation(npm("@actions/core"))
    implementation(npm("@actions/exec"))
    implementation(npm("@actions/http-client"))
    implementation(npm("@actions/io"))
    implementation(npm("@actions/tool-cache"))
    implementation(npm("@types/semver"))
    implementation(npm("semver", generateExternals = false))
    implementation(npm("null-writable")) 

    implementation(npm("@vercel/ncc", generateExternals = false))
t
Hm, where is
node.fs.readdir
?
As quick fix - PR in
kotlin-node
(with manual declarations) + issue
v
So it is missing? 😞
t
I did’t see it right now
v
I would even take
readdirSync
or
readdirAsync
, but it seems all are missing.
exists
is also missing, but at least
existsSync
is available.
t
Issue will be helpful
v
Of course, just thought I might miss something and had you at hand πŸ™‚ Thanks for your great help always. πŸ™‚
πŸ˜€ 1
And is there some way to make Dukat use the new wrappers classes?
Now various of the generated classes use
http.IncomingMessage
,
http.OutgoingHttpHeaders
,
url.URL
, and so on which are all in other packages now.
Or do I need to add the import-fixing to my post-processing step?
Which NPM libraries do you need?
``` implementation(npm("@actions/cache"))
implementation(npm("@actions/core"))
implementation(npm("@actions/exec"))
implementation(npm("@actions/http-client"))
implementation(npm("@actions/io"))
implementation(npm("@actions/tool-cache"))
implementation(npm("@types/semver"))
implementation(npm("semver", generateExternals = false))
implementation(npm("null-writable"))
implementation(npm("@vercel/ncc", generateExternals = false))```
So, ...? πŸ™‚
t
And is there some way to make Dukat use the new wrappers classes?
AFAIK Dukat is freezed right now 😞
@actions/...
libraries look like good candidates for
kotlin-wrappers
Issue will be fine start point, especially if you are ready to test results πŸ™‚
https://github.com/JetBrains/kotlin-wrappers/issues/1889
Could you list all missed methods, which you found?
v
AFAIK Dukat is freezed right now
So no No problem, I'll simply do it in my post-processing. Actually, it should unfreeze now. At least it was always said that it is freezed until IR is stable which it is now with 1.8.
@actions/...
libraries look like good candidates for
kotlin-wrappers
Issue will be fine start point, especially if you are ready to test results πŸ™‚
Nice. :-) Here you have it: https://github.com/JetBrains/kotlin-wrappers/issues/1891 Of course I'm willing to test, as I use almost all of them anyway already and have extensive tests for my action.
> https://github.com/JetBrains/kotlin-wrappers/issues/1889
Could you list all missed methods, which you found?
I did.
readdirSync
was the only one I used for which I did not find a replacement.
Ah, actually found another hole.
writeFile
previously allowed to set the mode for the file, but now only the encoding can be set 😞 https://github.com/JetBrains/kotlin-wrappers/issues/1893
t
pre.488
released!
recordOf
is available πŸ˜‰
❀️ 1
v
Not yet on MavenCentral?
t
15+ minutes usually required for sync
If MavenCentral is fine :)
πŸ‘Œ 1
v
Hm, at least where it takes an
OutgoingHttpHeaders
I cannot use the
recordOf
factory as it complains because
OutgoingHttpHeaders
is an alias for
Dict<Any /* OutgoingHttpHeader */>
which is an alias for
Record<String, Any /* OutgoingHttpHeader */>
so it does not accept the
ReadonlyRecord
πŸ€” 1
t
Fix is ready!
❀️ 1
Requested fixes for Node also expected in
pre.489
πŸ‘Œ 1
Released :)
v
Nice, thanks. Though I question the naming of the new interface. πŸ™‚ properties are
mode
of type
Mode
and
flag
of type
OpenMode
, but the interface containing them is called
FlagAndOpenMode
which both just refer to the second property. πŸ™‚
t
Good news - we have single source for all plaforms! πŸ˜‰
v
Ah, damn, maybe one more. I still have one
...Sync
method,
existsSync
which is the only one you have in the wrapper. Should there be an
existsAsync
and therefor a
suspend exists
?
Good news - we have single source for all plaforms! πŸ˜‰
https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/64140
πŸ‘ 1
t
Ah, damn, maybe one more.
Don’t stop! πŸ˜‰
Fallbacks for
exists
described in header
v
So if I got it right, β€’ async
exists
returning a promise does not exist as it is not in
promises.d.ts
β€’
existsSync
does exist and is also supported β€’
exists
in an async way only exists with callbacks and these are deprecated and should be replaced by
stat
or
access
Correct?
So from what I understood from those docs, I should use
fs.access
instead. But
node.fs.access
in the wrapper returns
Unit
πŸ˜•
t
Success = exists πŸ™‚
stat
looks like best async variant
v
But the docs of
stat
tell to use
access
for pure file-exists check πŸ˜„
So I guess I need a
Copy code
suspend fun exists(path: PathLike) = runCatching {
    access(path)
    true
}.getOrDefault(false)
t
Copy code
suspend fun exists(path: PathLike): Boolean =
    accessAsync(path)
        .then { true }
        .catch { false } 
        .await()
v
Is that better than my version and if so, why, or is it just an alternative? :-)
Ah, well, yours does not need exception handling, so better
No exception handling for flow-control if avoidable πŸ™‚
Ok, thanks again for you help, all usages updated. Now let's see whether the tests still run successfully. πŸ™‚
Oh, damn, it does not even run anymore. :'''-(
Copy code
Error: No such built-in module: node:test
    at new NodeError (node:internal/errors:372:5)
    at Function.Module._load (node:internal/modules/cjs/loader:785:13)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.2008 (D:\a\setup-wsl\setup-wsl\build\webpack:\setup-wsl-ncc-packer\external node-commonjs "node:test":1:1)
    at __nccwpck_require__ (D:\a\setup-wsl\setup-wsl\build\webpack:\setup-wsl-ncc-packer\webpack\bootstrap:21:1)
    at Object.6166 (D:\a\setup-wsl\setup-wsl\build\node_modules\kotlin-node\kotlin-node.js:2070:1)
    at __nccwpck_require__ (D:\a\setup-wsl\setup-wsl\build\webpack:\setup-wsl-ncc-packer\webpack\bootstrap:21:1)
    at Object.4624 (D:\a\setup-wsl\setup-wsl\build\webpack:\setup-wsl\kotlin\setup-wsl.js:3364:1)
    at __nccwpck_require__ (D:\a\setup-wsl\setup-wsl\build\webpack:\setup-wsl-ncc-packer\webpack\bootstrap:21:1)
Any idea where that might come from?
t
Do you use Legacy compiler?
AFAIK
node:test
is from Node 18
v
Yes, that project is still on Kotlin 1.4.
How would node:test come in then? I use Node 16 to build and also to run
And the Node version also did not change
It's also not the
ncc
version, if I update that separately first, the project still runs as expected.
But I then replace `kotlin-extensions`/`kotlinx-nodejs` by `kotlin-js`/`kotlin-node` it fails with that error
t
It’s also not the
ncc
version
What does it mean?
Yes, that project is still on Kotlin 1.4.
Magic πŸ™‚
v
I wanted to switch to `kotlin-js`/`kotlin-node` only as a first step. But with those changes
ncc
failed to run. So I updated
ncc
along to see whether it helps and then the
ncc
run worked. But now the execution of the result fails. I now reverted all changes and only updated
ncc
first to see whether it fails or not, but with that it still works as expected.
t
What is
ncc
?
v
Input is the result of Kotlin/JS, output is a self-contained runnable JS, that then runs as GitHub action
t
Do you use Webpack?
v
iirc ncc uses webpack internally
t
I see 2 options: 1. Use IR with Kotlin 1.8 to avoid redundant imports (
node:test
in your case) // recommended 2. Configure webpack fallback for
node:test
if it’s possible
Webpack fallback
3*. Remove/replace
node:test
import in Gradle task πŸ˜‰
v
With 3. you mean a post-processing of the ncc result? I wonder how it actually lands in the result just by switching from `kotlin-extensions`/`kotlinx-nodejs` to `kotlin-js`/`kotlin-node`
t
With 3. you mean a post-processing of the ncc result?
I mean post-processing of Kotlin compilation result It’s what you can find in
build/js/packages/%your-package%
v
find build/js/packages/setup-wsl -type f -exec grep node:test {} +
does not find any result though
Ok, maybe I should take the recommended approach and first stash all my changes and update Kotlin to 1.8. But I guess I will go on bugging you with questions then πŸ˜„
Is there docs what the tasks do? e. g. now with 1.8 and IR, there is
compileProductionExecutableKotlinJs
and
compileDevelopmentExecutableKotlinJs
. But I don't find info about them in the docs. Or
productionExecutableCompileSync
and
devleopmentExecutableCompileSync
.
Or previously
run
did run
nodeRun
and the docs still say it does. But now
run
runs
nodeRun
,
nodeProductionRun
, and
nodeDevelopmentRun
.
Ah, I think I got it.
compileKotlinJs
-
*.kt
=> IR
compileDevelopmentExecutableKotlinJs
- IR => JS without DCE
compileProductionExecutableKotlinJs
- IR => JS with DCE
developmentExecutableCompileSync
- JS without DCE + resources => to other folder
productionExecutableCompileSync
- JS with DCE + resources => to other folder
nodeRun
- Runs the result of
developmentExecutableCompileSync
nodeDevelopmentRun
- Also runs the result of
developmentExecutableCompileSync
nodeProductionRun
- Runs the result of
productionExecutableCompileSync
While I think it is very suboptimally solved that the
...CompileSync
tasks are
Copy
tasks, not
Sync
tasks, and that they also have the same output directory. Will create an issue about that.
πŸ‘ 1
Yay, not many questions necessary actually. I successfully moved to Kotlin 1.8 and due to incompatibility Gradle 7.6 and thereby the long overdue switch to included builds instead of
buildSrc
I long postponed due to other stuff and thereby cleaning up some really ugly stuff did in the past in that build, rewriting half of the build. πŸ˜„ And as a side-effect fixed invalid tests that were successful do the wrong reason. :-D Now the end result is immediately just 6.3 MiB instead of 14 MiB. :-)
πŸ˜‰ 1
t
FYI - If you use IR - mangling will be applied by default
v
Can you elaborate?
v
Yeah, I've read that before. I'm just not sure whether you wanted to imply something. :-)
Perfect, now my stashed changes also work flawlessly πŸ™‚
Hm, not exactly flawlessly. 😞 In production mode it works fine. But if I do
nodeRun
or
nodeDevelopmentRun
, it fails with
Copy code
D:\Sourcecode\other\setup-wsl\build\js\packages\setup-wsl\kotlin\setup-wsl.js:25473
}(module.exports, require('semver'), require('node:fs/promises'), require('null-writable'), require('node:path'), require('node:os'), require('node:process')));
 ^
ReferenceError: AbstractCoroutineContextElement is not defined
    at D:\Sourcecode\other\setup-wsl\build\js\packages\setup-wsl\kotlin\setup-wsl.js:454:73
    at Object.<anonymous> (D:\Sourcecode\other\setup-wsl\build\js\packages\setup-wsl\kotlin\setup-wsl.js:25473:2)
    at Module._compile (node:internal/modules/cjs/loader:1152:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1209:10)
    at Module.load (node:internal/modules/cjs/loader:1033:32)
    at Function.Module._load (node:internal/modules/cjs/loader:868:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:22:47
πŸ™ˆ Any idea where this might come from and / or how to fix it?
t
Outdated
coroutines
version?
v
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4
And in production mode it works fine
t
Which Kotlin version do you use?
v
1.8.10
Same with 1.8.0, just updated to 1.8.10 as it came out
t
Do you use
whole-program
granularity? 🧐
v
As you advised, yes. But iirc I also tried without and it didn't change
t
It means, that you can simply check result file.
AbstractCoroutineContextElement
really missed in development build?
v
Ah, yeah, I did check that too:
Copy code
$ grep AbstractCoroutineContextElement build/compileSync/js/main/developmentExecutable/kotlin/setup-wsl.js
  setMetadataFor(CoroutineDispatcher, 'CoroutineDispatcher', classMeta, AbstractCoroutineContextElement, [AbstractCoroutineContextElement, ContinuationInterceptor], undefined, undefined, []);
  setMetadataFor(YieldContext, 'YieldContext', classMeta, AbstractCoroutineContextElement, undefined, undefined, undefined, []);
    AbstractCoroutineContextElement.call(this, Key_getInstance());
    AbstractCoroutineContextElement.call(this, Key_getInstance_3());
Feel free to also have a look if you like, I pushed the current state to branch
foo
of https://github.com/Vampire/setup-wsl
In production mode it is
Copy code
$ grep AbstractCoroutineContextElement build/compileSync/js/main/productionExecutable/kotlin/setup-wsl.js
  setMetadataFor(AbstractCoroutineContextElement, 'AbstractCoroutineContextElement', classMeta, undefined, [Element], undefined, undefined, []);
  setMetadataFor(CoroutineDispatcher, 'CoroutineDispatcher', classMeta, AbstractCoroutineContextElement, [AbstractCoroutineContextElement, ContinuationInterceptor], undefined, undefined, []);
  function AbstractCoroutineContextElement(key) {
  AbstractCoroutineContextElement.prototype.w = function () {
    AbstractCoroutineContextElement.call(this, Key_getInstance());
  AbstractCoroutineContextElement.prototype.m2 = get;
  AbstractCoroutineContextElement.prototype.s2 = fold;
  AbstractCoroutineContextElement.prototype.r2 = minusKey;
  AbstractCoroutineContextElement.prototype.t2 = plus;
t
Call in
main
:
Copy code
(AbstractCoroutineContextElement::class.js)
as workaround works for you?
I see, that you use different versions for Kotlin (
1.8.10
) and Kotlinx Serialization plugin (
1.7.10
) . Why?
v
The serialization plugin is used in the build, so I chose the one matching the Kotlin version embedded in Gradle
In the production code no serialization is used
I just use it to read the
action.yml
file and to write a file in the sub-builds that I read in the root build
The suggested work-around does help in so far, that it then complains about the next class
Copy code
D:\Sourcecode\other\setup-wsl\build\js\packages\setup-wsl\kotlin\setup-wsl.js:31451
}(module.exports, require('node:fs/promises'), require('@actions/http-client'), require('@actions/core'), require('@actions/exec'), require('semver/classes/semver'), require('null-writable'), require('node:path'), require('node:os'), require('@actions/tool-cache'), require('@actions/cache'), require('node:process'), require('@actions/io')));
 ^
ReferenceError: CancellationException is not defined
    at D:\Sourcecode\other\setup-wsl\build\js\packages\setup-wsl\kotlin\setup-wsl.js:627:91
    at Object.<anonymous> (D:\Sourcecode\other\setup-wsl\build\js\packages\setup-wsl\kotlin\setup-wsl.js:31451:2)
    at Module._compile (node:internal/modules/cjs/loader:1155:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1209:10)
    at Module.load (node:internal/modules/cjs/loader:1033:32)
    at Function.Module._load (node:internal/modules/cjs/loader:868:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:22:47
And if I also add
(CancellationException::class.js)
, then it at least starts to run but then fails with
Copy code
> Task :nodeDevelopmentRun FAILED
::group::Verify Windows Environment
::endgroup::
::debug::ReferenceError: intercepted is not defined%0A    at await_0 (D:\opt\teamcity-agent\work\44ec6e850d5c63f0\kotlinx-coroutines-core\common\src\CancellableContinuation.kt:315:27)%0A    at $verifyWindowsEnvironmentCOROUTINE$4.doResume_5yljmg_k$ (D:\Sourcecode\other\setup-wsl\src\main\kotlin\net\kautler\github\action\setup_wsl\SetupWsl.kt:345:26)%0A    at verifyWindowsEnvironment (D:\Sourcecode\other\setup-wsl\src\main\kotlin\net\kautler\github\action\setup_wsl\SetupWsl.kt:341:9)%0A    at verifyWindowsEnvironment$ref.invoke_pbb09x_k$ (D:\Sourcecode\other\setup-wsl\src\main\kotlin\net\kautler\github\action\setup_wsl\SetupWsl.kt:271:45)%0A    at $groupCOROUTINE$3.l [as fn_1] (D:\Sourcecode\other\setup-wsl\build\js\packages\setup-wsl\kotlin\setup-wsl.js:30474:16)%0A    at $groupCOROUTINE$3.doResume_5yljmg_k$ (D:\Sourcecode\other\setup-wsl\src\main\kotlin\net\kautler\github\action\setup_wsl\SetupWsl.kt:335:16)%0A    at group (D:\Sourcecode\other\setup-wsl\src\main\kotlin\net\kautler\github\action\setup_wsl\SetupWsl.kt:332:9)%0A    at $mainCOROUTINE$0.doResume_5yljmg_k$ (D:\Sourcecode\other\setup-wsl\src\main\kotlin\net\kautler\github\action\setup_wsl\SetupWsl.kt:271:9)%0A    at main (D:\Sourcecode\other\setup-wsl\src\main\kotlin\net\kautler\github\action\setup_wsl\SetupWsl.kt:266:9)%0A    at D:\Sourcecode\other\setup-wsl\build\js\packages\setup-wsl\kotlin\setup-wsl.js:31495:3%0A
::error::intercepted is not defined
Actually, as the production run works, it is not super-blocking for me. I'd just like to understand what the problem is and what it is caused by. Whether I did something wrong I should fix, or whether I hit a bug I should report and where to.
t
Dukat generate types in root package. My expectation is that such type(s) can produce such behaviour. Known β€œduplication” -
Symbol
, we have it in browser API and we have it in
coroutines
.
We expect
kotlin-actions-toolkit
release tomorrow. Probably it will simplify future checks.
With
per-module
granularity it also doesn’t work, right? πŸ€”
v
Not at my computer right now, but I think I tried and it behave exactly the same
t
kotlin-actions-toolkit
released πŸš€
v
Nice, thanks
Hm, I almost expected the same pattern like for the Node.js stuff. That the
Promise
returning methods are suffixed with
Async
and that there is a
suspend
one that awaits that promise.
t
Step by step :) For first step it will be fine to use functions with same (β€œold”) contracts. Especially when you have problems with
coroutines
in dev mode.
v
I see, I switched to that wrapper, and besides that, it works fine, thanks, basically drop-in replacement, just needed to change the imports. All tests are green. But the dev-mode problem is unchanged.
t
Hm, I almost expected the same pattern like for the Node.js stuff.
Are you talking about top level functions only?
v
Not 100% what you mean
t
In Node we create
suspend
wrappers only for top level functions (
mkdir
,
readFile
)
In case of
@actions/*
looks like you want more
For example wrappers for
HttpClient
methods
v
Well, I take anything I can get πŸ˜„ Those two http client methods (
post
and
readBody
) are indeed the only non-top-level I use. What is the reasoning to only do it for the top-level methods in node?
t
1. I had use cases only for top level functions 2. Without
inline
sugar you won’t see it in default suggestion from IDEA
v
I see. Well, whatever you think makes sense. If you think it is best to keep it like it is, fine. If you think it is best to have the suspend sugar for the top-level methods, also fine. Anything else, you guessed it, of course fine. πŸ˜„
Any more ideas how I could investigate the dev-run problem? πŸ™‚
t
Kotlin
1.8.20-beta
?
v
Hard to quickly try, they disabled Dukat
Ah well, thanks to your wrapper work for the actions toolkit I just needed to define three classes, and the dev run worked
Now let's see whehter the same works with 1.8.10 already πŸ˜„
No, indeed with the same setup but 1.8.10 it fails with the
AbstractCoroutineContextElement
error. So it seems to indeed be a Kotlin/JS bug that will be fixed with 1.8.20. Thanks for the help in figuring out.
Hm, what did I wrong with
Copy code
import node.stream.Writable

@JsModule("null-writable")
@JsNonModule
external class NullWritable : Writable
?
Copy code
::debug::TypeError: NullWritable is not a constructor%0A    at wslHelp$slambda.gc (D:\Sourcecode\other\setup-wsl\src\main\kotlin\net\kautler\github\action\setup_wsl\SetupWsl.kt:77:25)%0A    at wslHelp$slambda.n11 (D:\Sourcecode\other\setup-wsl\src\main\kotlin\net\kautler\github\action\setup_wsl\SetupWsl.kt:67:47)%0A    at l (D:\Sourcecode\other\setup-wsl\build\js\packages\setup-wsl\kotlin\setup-wsl.js:13007:16)%0A    at _no_name_provided__qut3iv_2.gc (D:\Sourcecode\other\setup-wsl\build\compileSync\js\main\productionExecutable\kotlin\src\kotlin\coroutines_13\IntrinsicsJs.kt:163:40)%0A    at _no_name_provided__qut3iv_2.CoroutineImpl.r7 (D:\Sourcecode\other\setup-wsl\build\compileSync\js\main\productionExecutable\kotlin\commonMainSources\libraries\stdlib\src\kotlin\util\Standard.kt:55:40)%0A    at _no_name_provided__qut3iv_2.CoroutineImpl.j2 (D:\Sourcecode\other\setup-wsl\build\js\packages\setup-wsl\kotlin\setup-wsl.js:7214:17)%0A    at <http://DispatchedContinuation.DispatchedTask.gh|DispatchedContinuation.DispatchedTask.gh> (D:\Sourcecode\other\setup-wsl\build\compileSync\js\main\productionExecutable\kotlin\commonMainSources\libraries\stdlib\src\kotlin\coroutines\Continuation.kt:45:5)%0A    at <http://ScheduledMessageQueue.MessageQueue.no|ScheduledMessageQueue.MessageQueue.no> (D:\opt\teamcity-agent\work\44ec6e850d5c63f0\kotlinx-coroutines-core\js\src\JSDispatcher.kt:153:25)%0A    at D:\opt\teamcity-agent\work\44ec6e850d5c63f0\kotlinx-coroutines-core\js\src\JSDispatcher.kt:19:48%0A    at processTicksAndRejections (node:internal/process/task_queues:78:11)%0A
::error::NullWritable is not a constructor
πŸ˜•
t
File annotations must be used instead
v
Oh, ok, it seems for semver it worked properly with
Copy code
@JsModule("semver/classes/semver")
external class SemVer(version: String, options: RangeOptions)
external interface RangeOptions
though, or do I need to use file annotation there too?
No, with semver it is exactly the other way around. If I do it as file annotation, I get "TypeError: SemVer is not a constructor", but with the class annotation it works fine
One day I should learn to understand that πŸ˜„
Thanks again for your help
Yay
9 files changed, 45 insertions(+), 575 deletions(-)
Now Dukat is eliminated from my build, many boilerplate removed (and most additions are copyright), no time-waste for running Dukat or compiling the Kotlin classes and it works with 1.8.20-Beta. πŸ™‚ So yeah, if I in the current state just change 1.8.10 to 1.8.20-Beta, the dev-run suddenly works. πŸ™‚
πŸŽ‰ 1
t
Looks like you are ready for more
suspend
wrappers πŸ™‚
One day I should learn to understand that πŸ˜„
There 2 main variants:
Copy code
// #1 Named import
// JS
import { Vampire } from "vampire"

// Kotlin
@file:JsModule("vampire")

external val Vampire

------------------------------

// #2 Default import
// JS
import Vampire from "vampire"

// Kotlin
@file:JsModule("vampire")

@JsName("default")
external val Vampire
FYI -
@JsNonModule
is redundant for Node, because you need modular format in any case
More transparent
JsImport
already requested - feel free to vote πŸ™‚
v
Looks like you are ready for more suspend wrappers πŸ™‚
Always :-)
There 2 main variants:
Thanks
FYI - @JsNonModule is redundant for Node, because you need modular format in any case
Ah, ok, will remove it, thanks. Basically looked at what Dukat had produced. :-)
feel free to vote πŸ™‚
Done :-)
Looks like you are ready for more suspend wrappers
Should I find them already and am just blind? I updated to the new version and see that now there is
execAsync
and alike, but I don't find the suspend versions. Or is that yet again another step? πŸ™‚
The
...Async
methods work fine too, anyway πŸ™‚
The suspend methods now are the remaining piece for my current update streak. :-)
t
The
...Async
methods work fine too, anyway πŸ™‚
Fine On next step I will generate
suspend
adapters
I will ping you here or in issue (if you will create it), when it will be ready
πŸ‘Œ 1
❀️ 1
v
```suspend fun exists(path: PathLike): Boolean =
accessAsync(path)
.then { true }
.catch { false }
.await()```
Actually I'm just blind, there is
actions.io.exists
ready to use πŸ™ˆ
t
Yes
And release is ready
v
Yep, seen it, thanks. πŸ™‚ It is already integrated and tests running.
Argh, why do I now get "TypeError: exists is not a function" πŸ˜•
Might that indeed be a problem in the wrapper?
Copy code
TypeError: exists is not a function%0A    at exists_0 (D:\Users\leonid.khachaturov\code\kotlin-wrappers-new\kotlin-actions-toolkit\src\jsMain\generated\actions\io\exists.kt:10:5)%0A
  at $mainCOROUTINE$<http://11.ec|11.ec> (D:\Sourcecode\other\setup-wsl\src\main\kotlin\net\kautler\github\action\setup_wsl\SetupWsl.kt:287:17)%0A    at $verifyWindowsEnvironmentCOROUTINE$15.CoroutineImpl.r7 (D:\Sourcecode\other\setup-wsl\build\compileSync\js\main\productionExecutable\kotlin\commonMainSources\libraries\stdlib\src\kotlin\util\Standard.kt:55:40)%0A    at $verifyWindowsEnvironmentCOROUTINE$15.CoroutineImpl.j2 (D:\Sourcecode\other\setup-wsl\build\js\packages\setup-wsl\kotlin\setup-wsl.js:6918:17)%0A    at resume (D:\opt\teamcity-agent\work\44ec6e850d5c63f0\kotlinx-coroutines-core\common\src\internal\DispatchedTask.kt:178:26)%0A    at dispatch (D:\opt\teamcity-agent\work\44ec6e850d5c63f0\kotlinx-coroutines-core\common\src\internal\DispatchedTask.kt:166:9)%0A
 at dispatchResume (D:\opt\teamcity-agent\work\44ec6e850d5c63f0\kotlinx-coroutines-core\common\src\CancellableContinuationImpl.kt:397:9)%0A    at resumeImpl (D:\opt\teamcity-agent\work\44ec6e850d5c63f0\kotlinx-coroutines-core\common\src\CancellableContinuationImpl.kt:431:21)%0A    at resumeImpl$default (D:\opt\teamcity-agent\work\44ec6e850d5c63f0\kotlinx-coroutines-core\common\src\CancellableContinuationImpl.kt:420:13)%0A    at CancellableContinuationImpl.j2 (D:\opt\teamcity-agent\work\44ec6e850d5c63f0\kotlinx-coroutines-core\common\src\CancellableContinuationImpl.kt:328:9)%0A
exists is not a function
Yeah, according to the readme it does not exist: https://github.com/actions/toolkit/tree/main/packages/io
It is in
io-utils.ts
, not in
io.ts
like the others
That also explains why I didn't use it when not having the wrappers version πŸ˜„
t
It can be fixed. Could you please report an issue?
v
Sure, will the fix be that it will be not available, or that it will work? I guess the former as it is not an officially supported function?
t
Sure, will the fix be that it will be not available, or that it will work?
Looks like it will be better to delete it
πŸ‘Œ 1
For now we have only
generated
sources for Node
If you will create PR with
existsAsync
and suspend
exists
I will merge it
v
I guess those could easily confused with the deprecated
exists
from Node itself?
Especially the existing
existsSync
representing that deprecated
exists
t
Deprecated
exists
- with callback. Your version will be without callback - no problem detected.
v
I'm talking about
Copy code
package node.fs
external fun existsSync(
    path: PathLike,
): Boolean
For the deprecated
exists
with callback you don't even provide a wrapper, do you?
Or actually I don't know what I'm saying, I mixed those up. πŸ˜„
t
Yes, we don’t convert functions with callback
t
Return type missed 😞
v
whoops, bad copy & paste, sorry
fixed
t
pre.498
is waiting for checks πŸ˜‰
v
Yep, running πŸ™‚
Yay, everything green. I think I'm finally finished for now. :-) Thanks for all your help again.
πŸš€ 1
πŸ˜ƒ 1