Fork me on GitHub
#shadow-cljs
<
2021-03-30
>
pmooser14:03:43

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.

pmooser14:03:50

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

pmooser14:03:13

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

thheller15:03:34

@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.

thheller15:03:09

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

pmooser16:03:22

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

wombawomba16:03:07

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

Jack Arrington20:03:36

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 Arrington20:03:20

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

wombawomba21:03:01

Does Dirac work with shadow-cljs?

Jack Arrington21:03:27

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

wombawomba09:03:35

@U05224H0W can you confirm this?

thheller09:03:39

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

wombawomba09:03:18

okay thanks 🙂

thheller16:03:06

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

wombawomba21:03:24

alright, thanks

dpsutton21:03:03

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

thheller21:03:21

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

thheller21:03:07

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

thheller21:03:18

unless I'm missing something?

dpsutton21:03:37

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

dpsutton21:03:57

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

thheller21:03:26

yeah the string literals are difficult to emulate

dpsutton21:03:58

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

thheller21:03:21

macro is the only way I'm afraid

dpsutton21:03:11

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

thheller21:03:47

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

dpsutton21:03:29

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

thheller21:03:34

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

dpsutton21:03:57

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

thheller22:03:17

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

dpsutton22:03:51

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

thheller22:03:55

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

dpsutton22:03:30

i don't think so. that would call

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

thheller22:03:47

don't think so?

thheller22:03:17

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

dpsutton22:03:18

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)

thheller22:03:23

oh right doh

dpsutton22:03:17

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

thheller22:03:31

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

thheller22:03:03

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

thheller22:03:08

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

thheller22:03:56

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

dpsutton22:03:03

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

thheller22:03:07

what do you mean? it is munging?

thheller22:03:56

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

function_that_is_called_with_template_arg()`foo
`

thheller22:03:12

which is valid as far as I know?

thheller22:03:40

tried it in the console and seemed to work 😉

thheller22:03:06

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

thheller22:03:33

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

ttag.t`foo
`

thheller22:03:22

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?

thheller22:03:00

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

whatever.alias.was.foo`foo
`

dpsutton23:03:23

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

dpsutton23:03:49

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

thheller23:03:10

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

dpsutton23:03:12

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

thheller23:03:19

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
`

thheller23:03:48

dunno how smart your parser is at detecing that 😉

thheller23:03:23

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

thheller23:03:35

it won't be that after advanced

thheller23:03:54

hmm what language level is this even?

dpsutton23:03:00

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

dpsutton23:03:15

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

dpsutton23:03:24

and under advanced compilation it was still super readable so dunno

dpsutton23:03:31

what language level? es6, etc?

thheller23:03:22

yeah which spec level

thheller23:03:22

ah yeah :es6 seems to be ok

thheller23:03:30

closure was rewriting it with :es5

dpsutton23:03:00

oh annoying

thheller23:03:45

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

thheller23:03:03

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

dpsutton23:03:46

well thanks for being the sounding board

thheller16:03:44

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

dpsutton15:04:53

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

thheller15:04:24

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

dpsutton15:04:27

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

thheller15:04:35

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

dpsutton15:04:03

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

dpsutton15:04:11

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

thheller16:04:55

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 🙂

thheller16:04:07

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

dpsutton16:04:56

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

thheller16:04:28

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

thheller16:04:29

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

`hello ${x}` 

dpsutton16:04:59

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

thheller17:04:06

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

thheller17:04:08

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

dpsutton17:04:36

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

dpsutton17:04:17

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

dpsutton17:04:33

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

thheller17:04:40

did you check what the code actually emits?

dpsutton17:04:06

no i haven't. let me go check

thheller17:04:31

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

thheller17:04:14

I mean that should emit

`your ${x} works perfectly` 

thheller17:04:53

but might be

`your ${(x)} works perfectly` 

thheller17:04:14

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

dpsutton17:04:16

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

dpsutton17:04:32

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"));

thheller17:04:02

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

dpsutton17:04:26

ah, i removed the import. apologies

dpsutton17:04:56

and got confused because my repl still had it 🙂

dpsutton17:04:16

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

dpsutton17:04:21

well i'll be damned

dpsutton17:04:34

well excellent job in your late night haze

thheller17:04:16

thats more like it 😉

dpsutton17:04:13

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

dpsutton17:04:42

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

thheller17:04:55

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

thheller17:04:24

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

thheller17:04:41

this just felt cleaner

dpsutton23:03:02

and its amazing how responsive you are. truly

3
💯 3