Fork me on GitHub
#clojurescript
<
2023-02-24
>
hifumi12307:02:39

Is there a library for a "recursive" #js literal? So that one doesn't need to type #js {:nested #js {:objects #js ["like this"]}} edit: preferably something that runs at compile time, like a macro

hifumi12308:02:15

I want to convert the object at compile time, sorry for not clarifying that

p-himik08:02:08

Haven't checked but should work:

(require '[cljs.tagged-literals :as cljs-tl]
         '[clojure.walk :as walk])

(defmacro recursive-js [form]
  (walk/postwalk (fn [value]
                   (cond-> value
                     (or (and (vector? value)
                              (not (map-entry? value)))
                         (map? value))
                     (cljs-tl/read-js)))
                 form))

hifumi12308:02:41

This looks promising. I'll experiment with it soon

hifumi12311:02:38

Works pretty well so far… Just need to adapt it for closures and it’s perfect for my use case 🙂

👍 2
hifumi12313:02:08

welp, looks like functions will be tricky to get right, since once would need the ability to modify the code in-place and invoke the CLJS compiler to emit a javascript function — otherwise the postwalk will visit the arglist and convert that to JS objects… However. one workaround is to simply create bindings for functions and use that inside the data 😄

p-himik13:02:56

You can avoid going into functions by replacing the walk function with something that doesn't go inside lists. And also sets, I presume.

p-himik13:02:57

Also didn't check but also should work, this time without descending into any collections other than maps and vectors:

(require '[cljs.tagged-literals :as cljs-tl])

(defn -recursive-js [form]
  (cond
    (map? form) (cljs-tl/read-js (update-vals form -recursive-js))
    (vector? form) (cljs-tl/read-js (mapv -recursive-js form))
    :else form))

(defmacro recursive-js [form]
  (-recursive-js form))

👍 2
Kari Marttila10:02:02

I'm using Tailwind in my Clojurescript frontend. How about the Tailwind CSS classes that have / character in the classname (not a valid character in Clojure keywords)? E.g. how to provide this JSX snippet in Clojurescript/Hiccup? ( w-1/2 ):

<div className="flex grow w-1/2">

p-himik10:02:10

As strings?

Kari Marttila10:02:27

Ah, of course. 🙂

Kari Marttila11:02:11

It has been some time since I previously wrote Clojurescript / Hiccup. 🙂

p-himik11:02:01

Although it's very strange that they decided to use / in the first place. AFAICT, it's not a valid symbol for a class name, even though browsers seem to support it. Some people do experience problems with it, e.g. https://github.com/tailwindlabs/tailwindcss/issues/1973 Seems like there's a way to replace it with something else on a per-project basis though.

p-himik11:02:38

Ah, I'm actually wrong - in CSS3 selectors, there are limits and you have to escape a lot. But in HTML5 you can use slashes just fine, it seems.

fabrao15:02:11

Hello, I'm trying to use (.open js/window "some url") to open a new window. When I run it from development, it works, but after deploying it, not working. Is there any issue in production env for that?

thheller15:02:37

what happens when you call it? at the very least you should get some kind of error?

thheller15:02:58

browsers usually aren't eager about letting you open new windows, so generally the open is only allowed as part of a click or so

thheller15:02:15

otherwise you may just end up getting popup-blocked

fabrao15:02:21

no error, only not open

thheller15:02:31

likely the popup blocker then

thheller15:02:45

they often have special rules about localhost and such

fabrao15:02:01

but the browser does not tell about it

p-himik15:02:12

There might be a tiny icon in the address bar that, if you hover over it, will say that the website tried to open other windows. Also, I'm pretty sure you can use (js/open "some url"), without js/window. But it's the same function.

fabrao15:02:28

you right, the Edge does not show the blocking, but chrome yes

Gerome15:02:38

Hello! Is there some article, paper, video on how the clojurescript compilation process works?

jpmonettas17:02:17

@UPJP9G4G1 one thing that is maybe helpful if you are trying to understand how the clojurescript compiler works it is to run it under FlowStorm(https://github.com/jpmonettas/flow-storm-debugger) This big "one liner"

clj -Sdeps '{:deps {com.github.jpmonettas/flow-storm-dbg {:mvn/version "3.3.320"} org.clojure/clojurescript {:mvn/version "1.11.60"}}}' -X flow-storm.api/cli-run :instrument-ns '#{"cljs."}' :profile ':light' :flow-id 0 :require-before '#{"cljs.repl.node"}' :excluding-ns '#{"cljs.core"}' :fn-symb 'cljs.main/-main' :fn-args '["-t" "nodejs" "/home/user/cljs-test/src/org/foo/myscript.cljs"]';
will open the debugger, instrument the clojurescript compiler and then compile a example cljs file you give it /home/user/cljs-test/src/org/foo/myscript.cljs in this case, assuming you are interested in understanding how that file gets compiled. Here is a video showing a little bit on FlowStorm exploring the ClojureScript compiler: https://youtu.be/A3AzlqNwUXc?t=1945 In the video case the myscript.cljs is something like this
(ns org.foo.myscript)

(defn factorial [n]
  (if (zero? n)
    1
    (* n (factorial (dec n)))))

(js/console.log "Factorial of 5 is :" (factorial 5))

🙏 2
Kerron19:02:40

I found this video by Maria very insightful. She did some work on the clojurescript compiler. https://www.youtube.com/watch?v=Elg17s_nwDg

🙏 2
Gerome22:02:15

Haha, pretty cool thumbnail

chandrasekar05:03:01

I haven't watched this video but I had bookmarked this three hour video of a session with mike fikes on the clojurescript compiler https://www.youtube.com/watch?v=kBKIGj1_WAo

👍 2