shadow-cljs

https://github.com/thheller/shadow-cljs | https://github.com/sponsors/thheller | https://www.patreon.com/thheller
2021-03-30T14:14:43.225300Z

In Brave, I see a warning now regarding SharedArrayBuffer and it looks like it originates from something like shadow$provide.module$node_modules$scheduler$cjs$scheduler_development.

2021-03-30T14:14:50.225500Z

Is this a known issue that an update will address? Or not yet?

2021-03-30T14:19:13.225800Z

(it's just a deprecation warning from the browser)

thheller 2021-03-30T15:17:34.226400Z

@pmooser that is a library you are using, or rather that react is using. I have no control over that and shadow-cljs is not involved in that.

thheller 2021-03-30T15:18:09.227Z

you can check the repo if there is an issue about it. there probably is.

2021-03-30T16:06:22.227900Z

Ok, sorry about that. I didn't realize!

wombawomba 2021-03-30T16:41:07.229100Z

is there a way to get custom formatters and/or a CLJS REPL in Chrome devtools when using shadow-cljs?

wombawomba 2021-03-31T09:04:35.275Z

@thheller can you confirm this?

thheller 2021-03-31T09:06:39.275700Z

no. dirac does not work. or it didn't use to work, it has been a while since I looked.

wombawomba 2021-03-31T09:09:18.275900Z

okay thanks 🙂

thheller 2021-03-30T16:49:06.229900Z

custom formatters you can just use cljs-devtools. a REPL no.

Jack Arrington 2021-03-30T20:36:36.230Z

Maybe not exactly what you want, but if you want to make your Chrome devtools more CLJS friendly you might check out Dirac: https://github.com/binaryage/dirac

Jack Arrington 2021-03-30T20:39:20.230300Z

I haven't personally used it (honestly, I've just been too lazy to set it up), but I've heard a lot of praise for it in the community

wombawomba 2021-03-30T21:00:01.230500Z

Does Dirac work with shadow-cljs?

wombawomba 2021-03-30T21:00:24.230800Z

alright, thanks

Jack Arrington 2021-03-30T21:09:27.230900Z

It should work with any Clojurescript code running in a browser. Shadow-cljs is just a build system.

dpsutton 2021-03-30T21:42:03.233600Z

i'm seeing some strange compiler output

(defn js-i18n [format-string-string & args]
  (js* "ttag/t`~{}`" format-string-string)
  (apply ttag/t (-> format-string-string chomp-format-string into-array) args))
i'm playing around with emitting a tagged format literal in js for our i18n. And strangely, this is emitting
(metabase.shared.util.i18n.js_i18n.cljs$core$IFn$_invoke$arity$variadic = (function (format_string_string,args){
ttag/t`format_string_string`;

return cljs.core.apply.cljs$core$IFn$_invoke$arity$3(shadow.js.shim.module$ttag.t,cljs.core.into_array.cljs$core$IFn$_invoke$arity$1(metabase.shared.util.i18n.chomp_format_string(format_string_string)),args);
}));
which is including the name of the var, not its contents: ttag/t'format_string_string' (had to use apostrophes instead of backticks here). however, evaluating (js* "1 + ~{}" x) at a repl where x is (def x 3) correctly yeilds 4. So it seems to resolve at runtime in a repl but under advanced compilation uses the local name

thheller 2021-03-30T21:47:21.234300Z

I don't understand. that is producing exactly the code it is supposed to?

thheller 2021-03-30T21:49:07.234800Z

this (js* "1 + ~{}" x) ends up as 1 + x in the code so of course that is valid?

thheller 2021-03-30T21:49:18.235100Z

unless I'm missing something?

dpsutton 2021-03-30T21:49:37.235500Z

oh i see. i was thinking it would end up as 1 + 3 instead of 1 + x with that being a valid local

dpsutton 2021-03-30T21:49:57.235900Z

and now i realized i had thought myself into a silly place 🙂

thheller 2021-03-30T21:50:26.236400Z

yeah the string literals are difficult to emulate

dpsutton 2021-03-30T21:50:58.237100Z

i'm fighting against an i18n library that has a plugin to enumerate all strings for translation that looks for tagged template literals. and i'm working on how i can get some cljs code to play nice with that

thheller 2021-03-30T21:51:21.237500Z

macro is the only way I'm afraid

dpsutton 2021-03-30T21:54:11.238100Z

that would use the js* special form? or does that strike you as the wrong approach?

thheller 2021-03-30T21:54:47.238700Z

it would need to use that since the compiler otherwise isn't currently able to emit those

dpsutton 2021-03-30T21:55:29.239600Z

awesome. thanks for your help and sorry for the wall of text for a really dumb question 🙂

thheller 2021-03-30T21:55:34.239800Z

I mean support could be added via magic but that is a rather advanced task 😛

dpsutton 2021-03-30T21:58:57.240600Z

yeah. and since they are callable as functions its not a big hindrance. just a bummer that their plugin to find them looks over the ast for tagged literals in particular

thheller 2021-03-30T22:25:17.241300Z

need to finish up some more testing with new CLJS version and then that'll be in the next release

dpsutton 2021-03-30T22:25:51.241600Z

that's close but if its possible to put a tag on front that would be nice

thheller 2021-03-30T22:26:55.242400Z

(js/ttag.t (js-template "foo"))?

dpsutton 2021-03-30T22:28:30.244400Z

i don't think so. that would call

t(`foo`)
//distinct from
t`foo
`

thheller 2021-03-30T22:28:42.244600Z

it is?

thheller 2021-03-30T22:28:47.244800Z

don't think so?

thheller 2021-03-30T22:29:17.245200Z

I've never actually used them anywhere so I might be totally wrong 😛

dpsutton 2021-03-30T22:30:18.246Z

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates

myTag`That ${ person } is a ${ age }.`;
is equivalent to
myTag(["That ", " is a "], person, age)

thheller 2021-03-30T22:30:23.246300Z

oh right doh

dpsutton 2021-03-30T22:32:17.246800Z

yeah its confusing at first but then just totally makes sense mechanically. it's just chopped up

thheller 2021-03-30T22:33:31.247600Z

hmm wonder if that should be (js-template foo "bar") or (js-tagged-template foo "bar")

thheller 2021-03-30T22:34:03.248200Z

as in a separate form or just handled by being smart and checking the first argument 😛

thheller 2021-03-30T22:46:08.249500Z

dunno if this is actually useful but it has been bugging me that this wasn't supported for a while 😛

thheller 2021-03-30T22:49:56.250Z

probably full of bugs still, pretty sure the escape logic is too naive but who knows 😉

dpsutton 2021-03-30T22:51:03.250700Z

yeah that looks closer. feels weird to emit without munging. i think you could define your own functions in cljs so it should probably be munged

thheller 2021-03-30T22:52:07.251Z

what do you mean? it is munging?

thheller 2021-03-30T22:52:56.252Z

(js-template (function-that-is-called-with-template-arg) "foo") is

function_that_is_called_with_template_arg()`foo
`

thheller 2021-03-30T22:53:12.252500Z

which is valid as far as I know?

thheller 2021-03-30T22:53:40.252800Z

tried it in the console and seemed to work 😉

thheller 2021-03-30T22:54:06.253300Z

it isn't taking the literal symbol and just dumps it there. it is actually analyzing that symbol

thheller 2021-03-30T22:54:33.253900Z

so (js-template js/ttag.t "foo") would be

ttag.t`foo
`

thheller 2021-03-30T22:55:22.254800Z

I mean for your stuff you likely still need a macro either way if you just want to emit that as a side effect so the parser can find it?

thheller 2021-03-30T22:56:00.255400Z

(js-template alias/foo "foo") would be

whatever.alias.was.foo`foo
`

dpsutton 2021-03-30T23:02:23.256100Z

actually that does all it needs to. if it emits the correct thing its golden

dpsutton 2021-03-30T23:02:49.256700Z

it needs to parse the compiled output to compile a list of strings needing translations

thheller 2021-03-30T23:04:10.257200Z

yeah but depends on what it is looking for I guess. dunno if it understands the aliasing shadow-cljs does for modules and stuff

dpsutton 2021-03-30T23:05:12.258Z

yeah i was looking at that. i think that would be another problem to solve but it felt more approachable. was wondering what your shim was and how wrapped over the underlying lib it was

thheller 2021-03-30T23:06:19.259200Z

you appear to be using :npm-module so if you have (:require ["ttag" :refer (t)]) and (js-template t "foo") what would give you

shadow.js.shim.module$ttag = require("ttag");
shadow.js.shim.module$ttag.t`foo
`

thheller 2021-03-30T23:06:48.259600Z

dunno how smart your parser is at detecing that 😉

thheller 2021-03-30T23:08:23.260200Z

the shim is just a placeholder variable basically for the require result

thheller 2021-03-30T23:08:35.260600Z

it won't be that after advanced

thheller 2021-03-30T23:15:54.261300Z

hmm what language level is this even?

dpsutton 2021-03-30T23:16:00.261500Z

yeah i don't think it picked that up. i had to (js* "ttag/t~{}) to get it to work

dpsutton 2021-03-30T23:16:15.261800Z

yeah i was hoping i could throw an export on it and have it stable

dpsutton 2021-03-30T23:16:24.262100Z

and under advanced compilation it was still super readable so dunno

dpsutton 2021-03-30T23:16:31.262300Z

what language level? es6, etc?

thheller 2021-03-30T23:17:22.262800Z

yeah which spec level

thheller 2021-03-30T23:18:22.263100Z

ah yeah :es6 seems to be ok

thheller 2021-03-30T23:18:30.263400Z

closure was rewriting it with :es5

dpsutton 2021-03-30T23:21:00.263900Z

oh annoying

thheller 2021-03-30T23:23:45.264700Z

thinking about it a macro may actually be enough with a bit of js*, doesn't need to do all I'm doing now

thheller 2021-03-30T23:24:03.265100Z

I'll see about it tomorrow when I can actually think, way too late now 🙂

dpsutton 2021-03-30T23:30:46.265300Z

well thanks for being the sounding board

thheller 2021-03-31T16:36:44.287500Z

I pushed 2.12.0 (minor bump because of new cljs version) which also has the (js-template ...) if you want to try that

dpsutton 2021-04-02T15:45:53.318300Z

i'm on 2.12.0: shadow-cljs - server version: 2.12.0 running at <http://localhost:9630>, and (js-template ttag/t "hello") is giving me an error about an undeclared var js-template

thheller 2021-04-02T15:47:24.318500Z

oh you need to require it. I made it available as a library

dpsutton 2021-04-02T15:47:27.318700Z

(special-symbol? js-template) is returning false which surprises me

dpsutton 2021-04-02T15:47:28.318900Z

ahh

thheller 2021-04-02T15:47:35.319100Z

(:require [shadow.cljs.modern :refer (js-template)])

dpsutton 2021-04-02T15:52:03.319600Z

getting an error with (js-template ttag/t "hello") and similarly with just a base test: (js-template "hello"): cannot read property call of undefined

dpsutton 2021-04-02T15:53:11.319800Z

nevermind, must have been some funky repl state. re-evaled the ns with the require and it is now working

thheller 2021-04-02T16:52:55.320Z

I expect there to be bugs with this. I didn't test is very much and the implementation is definitely kinda rushed in a late night sleepy state 🙂

thheller 2021-04-02T16:53:07.320200Z

once this has been tested a little more we can maybe make a patch for CLJS out of it

dpsutton 2021-04-02T16:56:56.320400Z

one thing to think about, is that tagged template literals, and template literals in general, make the most sense when they can have the interpolated values. i tried a simple (js-template "hello ${\"there\"}") and it emitted t'hello \$"there"' which was almost workable. not sure how to handle this. off the cuff might be (js-template "hello " x) might emit t'hello ${x}'but i doubt that might be worth the trouble and sounds like a super uphill battle going into cljs

thheller 2021-04-02T16:58:28.320600Z

well the whole point was making this act like str but emit a template string

thheller 2021-04-02T16:59:29.320800Z

(js-template "hello " x) will emit exactly

`hello ${x}` 

dpsutton 2021-04-02T16:59:59.321100Z

ah sorry i thought i tried that and it didn't do what i wanted

thheller 2021-04-02T17:00:06.321300Z

(js-template "hello ${\"there\"}") is therefore pointless and will be escaped 😛

dpsutton 2021-04-02T17:00:10.321500Z

totally

thheller 2021-04-02T17:01:08.321700Z

(js-template "hello " (any-cljs "expr")) is totally valid, if it was using ${} then you'd run into all sorts of annoying quoting issues

dpsutton 2021-04-02T17:01:36.322Z

a difficult part for this particular implementation is that the translation library expects "your {x} works perfectly" and will expect the translated phrase to be "your {placeholder} works perfectly" and i can't recreate that in this guise

dpsutton 2021-04-02T17:02:17.322200Z

(js-template "your " x " works pefectly") would emit the "works pefectly" as part of the substitution rather than the base phrase

dpsutton 2021-04-02T17:02:33.322400Z

again, certainly a quirk in this implementation but kinda the point of the templates i think

thheller 2021-04-02T17:02:40.322600Z

did you check what the code actually emits?

dpsutton 2021-04-02T17:03:06.322800Z

no i haven't. let me go check

thheller 2021-04-02T17:03:31.323Z

it may just be the CLJS compiler emitting the usual extra () which I can't do anything about unfortunately

thheller 2021-04-02T17:04:14.323200Z

I mean that should emit

`your ${x} works perfectly` 

thheller 2021-04-02T17:04:53.323500Z

but might be

`your ${(x)} works perfectly` 

thheller 2021-04-02T17:05:14.323700Z

or whatever x resolves to in this case. could also by some.other.ns.x

dpsutton 2021-04-02T17:05:16.323900Z

(let [x "soundcard"]
  (js-template "your " x " works pefectly"))

dpsutton 2021-04-02T17:05:32.324100Z

var x_46339 = "soundcard";
(metabase.shared.util.i18n.js_template.cljs$core$IFn$_invoke$arity$3 ? metabase.shared.util.i18n.js_template.cljs$core$IFn$_invoke$arity$3("your ",x_46339," works pefectly") : metabase.shared.util.i18n.js_template.call(null,"your ",x_46339," works pefectly"));

thheller 2021-04-02T17:06:02.324300Z

that is definitely not the correct output. this is not using the special form at all

dpsutton 2021-04-02T17:06:26.324500Z

ah, i removed the import. apologies

dpsutton 2021-04-02T17:06:56.324700Z

and got confused because my repl still had it 🙂

dpsutton 2021-04-02T17:07:16.324900Z

var x_48110 = "soundcard";
`your ${x_48110} works pefectly`;

dpsutton 2021-04-02T17:07:21.325100Z

well i'll be damned

dpsutton 2021-04-02T17:07:34.325300Z

well excellent job in your late night haze

thheller 2021-04-02T17:08:16.325500Z

thats more like it 😉

dpsutton 2021-04-02T17:09:13.325700Z

and the plan would be to move that into cljs proper as a special form with those methods for analyzing and emitting?

dpsutton 2021-04-02T17:09:42.325900Z

re-added my sponsorship now that i'm finally using shadow at a work project

thheller 2021-04-02T17:13:55.326100Z

well it definitely needs more discussion and testing before this can be submitted to CLJS proper

thheller 2021-04-02T17:14:24.326300Z

still not sure if the special form is actually needed for this. a macro might do the trick just fine with js*

thheller 2021-04-02T17:14:41.326500Z

this just felt cleaner

dpsutton 2021-03-30T23:31:02.265700Z

and its amazing how responsive you are. truly

💯 1
1