clojurescript

true.neutral 2024-11-08T12:40:04.552019Z

Is there an easy way to list all callables from an imported JS package? It's a continuation of my previous question: the package is imported straight from the runtime; K6 authors changed something between v0.52 and v0.53 so whenever I run against a newer version, it errors out the function I'm calling is not there anymore. Changelog doesn't help, sources don't help - it should be there, and the source with the function definition hasn't been changed for quite some time. So I wanna look around what's actually available, and I can't quite understand how to do it. All I have working now is (:require ["k6/http" :as http]), and the call that broke is http/get.

thheller 2024-11-08T12:43:41.373009Z

kinda hard to say without knowing what the actual runtime is capable of

thheller 2024-11-08T12:43:51.540649Z

maybe (js/Object.keys http)?

thheller 2024-11-08T12:44:48.046929Z

also a quick check in the docs has this example JS bit import http from 'k6/http';

thheller 2024-11-08T12:44:54.178659Z

this does not translate to what you have above

thheller 2024-11-08T12:45:20.568679Z

see the examples in this section https://shadow-cljs.github.io/docs/UsersGuide.html#_using_npm_packages

thheller 2024-11-08T12:46:50.536179Z

basically should be (:require ["k6/http$default" :as http])

true.neutral 2024-11-08T12:49:13.316669Z

Ohhhh. Let me check quickly with both versions! The runtime is Grafana's own fork of goja engine, if that helps. Says to be fully compatible with ES5.

true.neutral 2024-11-08T12:54:05.876009Z

With v0.52, it gives everything as it should with an old require:

["TLS_1_0","TLS_1_1","TLS_1_2","TLS_1_3","OCSP_STATUS_GOOD","OCSP_STATUS_REVOKED","OCSP_STATUS_SERVER_FAILED","OCSP_STATUS_UNKNOWN","OCSP_REASON_UNSPECIFIED","OCSP_REASON_KEY_COMPROMISE","OCSP_REASON_CA_COMPROMISE","OCSP_REASON_AFFILIATION_CHANGED","OCSP_REASON_SUPERSEDED","OCSP_REASON_CESSATION_OF_OPERATION","OCSP_REASON_CERTIFICATE_HOLD","OCSP_REASON_REMOVE_FROM_CRL","OCSP_REASON_PRIVILEGE_WITHDRAWN","OCSP_REASON_AA_COMPROMISE","url","CookieJar","cookieJar","file","get","head","post","put","patch","del","options","request","asyncRequest","batch","setResponseCallback","expectedStatuses","default"]
v0.54 output is empty. With $default require, v0.52 still works, while (js/Object.keys http) throws
TypeError: Cannot convert undefined or null to object
        at keys (native)

thheller 2024-11-08T12:54:48.203909Z

guess they moved stuff to the default export then .. JS devs are always fun like that 😛

thheller 2024-11-08T12:56:32.756339Z

at least they documented it I guess https://grafana.com/docs/k6/latest/release-notes/v0.53.0/#breaking-changes

true.neutral 2024-11-08T13:00:06.206539Z

Could you explain please? %) I'm so new to the JavaScript game, I don't understand the intricacies and implications; I'm more used to the world where a symbol is either explicitly exported or not, and can be linked against or not :D

true.neutral 2024-11-08T13:00:52.238979Z

> they moved stuff to the default export then But then (:reuqire ["k6/http$default" :as http]) should have worked as far as I understand, no?

thheller 2024-11-08T13:01:48.556019Z

not a clue. can't tell which version their docs reference 😛

thheller 2024-11-08T13:02:44.775439Z

(:require ["k6/http" :as http]) and listing all the properties should at least have a default property

thheller 2024-11-08T13:02:55.284499Z

..."expectedStatuses","default"] like that one

true.neutral 2024-11-08T13:03:19.255139Z

Sadly, no, this is literally the log line:

INFO[0000] []                                            source=console

true.neutral 2024-11-08T13:03:28.586329Z

Empty array.

thheller 2024-11-08T13:03:51.733279Z

hmm and just trying (js/Object.keys http/default)?

thheller 2024-11-08T13:04:35.968619Z

what does (type http) say? is it undefined or an actual object?

true.neutral 2024-11-08T13:04:51.476619Z

Throws just like with "k6/http$default" require:

ERRO[0000] TypeError: Cannot convert undefined or null to object
        at keys (native)

true.neutral 2024-11-08T13:05:06.811989Z

I guess it would be undefined, let me check for sure.

true.neutral 2024-11-08T13:05:38.423169Z

Yep, undefined.

INFO[0000] undefined                                     source=console

true.neutral 2024-11-08T13:06:16.966789Z

If I try (type http) with $default require, it gives null .

thheller 2024-11-08T13:06:17.345589Z

hmm. don't know enough about the runtime to comment I guess. maybe just try a regular JS file and see what happens?

thheller 2024-11-08T13:06:45.667249Z

like import http from "k6/http"; console.log(http); and run that?

thheller 2024-11-08T13:07:07.259379Z

no clue how that all works, but if that gives you the actual object we can dig deeper on the CLJS side 😛

true.neutral 2024-11-08T13:07:29.910059Z

I have a TypeScript test that works (or at least USED TO work with old K6 version), let me try and run that against the new version.

thheller 2024-11-08T13:08:48.550089Z

I assume you added k6/http to the :keep-as-import set?

true.neutral 2024-11-08T13:09:23.068309Z

Correct, else it wouldn't build. 🙂

thheller 2024-11-08T13:11:02.327009Z

just checking 😉

true.neutral 2024-11-08T13:12:10.510409Z

Ah, okay, so from TypeScript:

here be dragons
{"TLS_1_0":"tls1.0","TLS_1_1":"tls1.1","TLS_1_2":"tls1.2","TLS_1_3":"tls1.3","OCSP_STATUS_GOOD":"good","OCSP_STATUS_REVOKED":"revoked","OCSP_STATUS_SERVER_FAILED":"server_failed","OCSP_STATUS_UNKNOWN":"unknown","OCSP_REASON_UNSPECIFIED":"unspecified","OCSP_REASON_KEY_COMPROMISE":"key_compromise","OCSP_REASON_CA_COMPROMISE":"ca_compromise","OCSP_REASON_AFFILIATION_CHANGED":"affiliation_changed","OCSP_REASON_SUPERSEDED":"superseded","OCSP_REASON_CESSATION_OF_OPERATION":"cessation_of_operation","OCSP_REASON_CERTIFICATE_HOLD":"certificate_hold","OCSP_REASON_REMOVE_FROM_CRL":"remove_from_crl","OCSP_REASON_PRIVILEGE_WITHDRAWN":"privilege_withdrawn","OCSP_REASON_AA_COMPROMISE":"aa_compromise"}
this is produced with
import http from "k6/http";

console.log("here be dragons");
console.log(http);
with latest k6:
$ k6 version
k6 v0.54.0 (commit/baba871c8a, go1.23.1, linux/amd64)

thheller 2024-11-08T13:13:39.721299Z

and import * as http from "k6/http";?

true.neutral 2024-11-08T13:14:31.601519Z

Seems like the same exact output:

{"TLS_1_0":"tls1.0","TLS_1_1":"tls1.1","TLS_1_2":"tls1.2","TLS_1_3":"tls1.3","OCSP_STATUS_GOOD":"good","OCSP_STATUS_REVOKED":"revoked","OCSP_STATUS_SERVER_FAILED":"server_failed","OCSP_STATUS_UNKNOWN":"unknown","OCSP_REASON_UNSPECIFIED":"unspecified","OCSP_REASON_KEY_COMPROMISE":"key_compromise","OCSP_REASON_CA_COMPROMISE":"ca_compromise","OCSP_REASON_AFFILIATION_CHANGED":"affiliation_changed","OCSP_REASON_SUPERSEDED":"superseded","OCSP_REASON_CESSATION_OF_OPERATION":"cessation_of_operation","OCSP_REASON_CERTIFICATE_HOLD":"certificate_hold","OCSP_REASON_REMOVE_FROM_CRL":"remove_from_crl","OCSP_REASON_PRIVILEGE_WITHDRAWN":"privilege_withdrawn","OCSP_REASON_AA_COMPROMISE":"aa_compromise"}

thheller 2024-11-08T13:15:04.857279Z

hmm then I don't see why the CLJS version wouldn't work. there is no difference in the type of imports used

thheller 2024-11-08T13:15:24.748869Z

you can check the generated sources? maybe there is another mistake happening somewhere

true.neutral 2024-11-08T13:15:55.611139Z

The generated, you mean the CLJS compiled to JS ones?

thheller 2024-11-08T13:15:58.323149Z

I mean the printed object is still weird because its missing get and stuff, but that could just be the printer

thheller 2024-11-08T13:16:06.461469Z

yeah the :output-dir files

true.neutral 2024-11-08T13:17:15.661299Z

If I do Object.keys(), btw, I see the methods - get, head, post and all that; with both import * as http from and import http from

thheller 2024-11-08T13:20:09.723669Z

just grep for k6/http in the :output-dir. that should find the import

true.neutral 2024-11-08T13:21:34.643359Z

import*as esm_import$k6$http from"k6/http";

thheller 2024-11-08T13:21:53.486029Z

yeah ok. then that should be ok

true.neutral 2024-11-08T13:21:59.100579Z

That corresponds to

(:require ["k6/http$default" :as http]))

thheller 2024-11-08T13:22:19.666689Z

nah that will just end up using esm_import$k6$http.default basically, so the same as (:require ["k6/http" :as http]) + http/default would

thheller 2024-11-08T13:23:22.569699Z

if they actually implement ESM correctly then that should be valid

true.neutral 2024-11-08T13:23:23.750549Z

Ah I see.

thheller 2024-11-08T13:23:29.922379Z

maybe try in the JS variant if that works there

thheller 2024-11-08T13:23:49.340839Z

import * as http from "k6/http"; and console.log(http.default)

thheller 2024-11-08T13:24:10.214709Z

I gotta go. be back in about 2 hours

true.neutral 2024-11-08T13:25:03.127369Z

I appreciate your help @thheller, I'll play around with it some more. I'm gonna be back myself in ~3.5 if you're still here, that'd be great.

true.neutral 2024-11-08T13:26:36.631809Z

import * as http from "k6/http";
console.log(http.default);
still works:
{"TLS_1_0":"tls1.0","TLS_1_1":"tls1.1","TLS_1_2":"tls1.2","TLS_1_3":"tls1.3","OCSP_STATUS_GOOD":"good","OCSP_STATUS_REVOKED":"revoked","OCSP_STATUS_SERVER_FAILED":"server_failed","OCSP_STATUS_UNKNOWN":"unknown","OCSP_REASON_UNSPECIFIED":"unspecified","OCSP_REASON_KEY_COMPROMISE":"key_compromise","OCSP_REASON_CA_COMPROMISE":"ca_compromise","OCSP_REASON_AFFILIATION_CHANGED":"affiliation_changed","OCSP_REASON_SUPERSEDED":"superseded","OCSP_REASON_CESSATION_OF_OPERATION":"cessation_of_operation","OCSP_REASON_CERTIFICATE_HOLD":"certificate_hold","OCSP_REASON_REMOVE_FROM_CRL":"remove_from_crl","OCSP_REASON_PRIVILEGE_WITHDRAWN":"privilege_withdrawn","OCSP_REASON_AA_COMPROMISE":"aa_compromise"}

true.neutral 2024-11-08T13:40:56.547579Z

Another thing: with the old k6 version, with this import:

["k6/http" :as http]
both
(js/console.log (js/Object.keys http/default))
and
(js/console.log (js/Object.keys http))
print out correct keys:
["TLS_1_0","TLS_1_1","TLS_1_2","TLS_1_3","OCSP_STATUS_GOOD","OCSP_STATUS_REVOKED","OCSP_STATUS_SERVER_FAILED","OCSP_STATUS_UNKNOWN","OCSP_REASON_UNSPECIFIED","OCSP_REASON_KEY_COMPROMISE","OCSP_REASON_CA_COMPROMISE","OCSP_REASON_AFFILIATION_CHANGED","OCSP_REASON_SUPERSEDED","OCSP_REASON_CESSATION_OF_OPERATION","OCSP_REASON_CERTIFICATE_HOLD","OCSP_REASON_REMOVE_FROM_CRL","OCSP_REASON_PRIVILEGE_WITHDRAWN","OCSP_REASON_AA_COMPROMISE","url","CookieJar","cookieJar","file","get","head","post","put","patch","del","options","request","asyncRequest","batch","setResponseCallback","expectedStatuses"]
(as expected), BUT
(js/console.log (type http))
gives null , as well as (type http/default) ; same story with "k6/http$default" require. Which is kind of mind-boggling, so http is null to CLJS but if it's passed to JS runtime the properties can be accessed?..

p-himik 2024-11-08T15:00:55.184029Z

There's no such thing as "passing to JS runtime" - it's all there already. (type http) might return nil even when the object is not nil itself.

true.neutral 2024-11-08T16:20:55.099029Z

Ah, I see. Just seems strange that a call to Clojure's type's giving nil, but js/Object.keys shows it's definitely not nil.

p-himik 2024-11-08T16:53:13.926459Z

Types in JS are weird.

true.neutral 2024-11-14T11:05:32.109629Z

I filed a bug for k6 and it's getting a fix it seems: https://github.com/grafana/k6/pull/4058

2024-11-08T21:08:04.077959Z

in clojure I can extend a protocol to Object to get a kind of default implementation, is there something like that in clojurescript?

2024-11-08T21:10:39.472809Z

perfect, thank you

2024-11-08T21:15:44.709739Z

are there any provisos, like it only works with extend-protocol and not extend-type? (getting errors still, might not be related, working on getting a big chunk of clojure code working in clojurescript)

thheller 2024-11-08T21:17:24.589149Z

dunno about extend-type. seems like default is not a type to me 😛

thheller 2024-11-08T21:17:30.920139Z

there is object but its kinda weird

2024-11-08T21:19:19.169999Z

yeah, I think maybe default is working, but I translated some interop incorrectly

2024-11-08T21:20:08.764929Z

actually I think what it is is the closure compiler not knowing about Promise.withResolvers and mangling it

2024-11-08T21:27:14.469949Z

(it was that)