Fork me on GitHub
#clojurescript
<
2021-07-15
>
Oliver George00:07:04

e.g. "WARNING: Use of undeclared" means my build is broken. I want it to throw it's toys out of the pram... not stoically push on regardless.

💯 4
Oliver George00:07:26

Here's my current workaround using a Makefile...

prod-build:
	clj-kondo --lint src/cljs --fail-level warning
	clojure -M -m cljs.main -co prod.cljs.edn -O advanced -c

Oliver George00:07:32

There really should be a bot which links to shadow-cljs for each known CLJS compiler niggle.

😆 4
zendevil.eth11:07:43

I have an re-frame fx set-logged-in that is triggered on page load:

(rf/reg-fx
  :set-logged-in
  (fn [magic]
    (go
     (rf/dispatch
      [:set-logged-in'
       (<p! (.. ^js magic -user (isLoggedIn)))]))))

(reg-event-db
   :set-logged-in'
   (fn [db [_ logged-in?]]
    (assoc db :logged-in? logged-in?)))
And the problem is that (<p! (.. ^js magic -user (isLoggedIn))) is true after a few seconds (takes a while for the magic api to set isLoggedIn to true in the backend) and not immediately on pageload, so that means even though I want the value of :logged-in? to be true, it shows up as false because :logged-in? is set before the value of the promise is changed from false to true. How can I tweak the code so that I can wait for a few seconds on isLoggedIn so that I know for sure that isLoggedIn will or won’t return true and then set the :logged-in? value? Basically I want to change :logged-in? whenever (<p! (.. ^js magic -user (isLoggedIn))) changes, but currently I can only set it once on pageload. Also I don’t understand how in the documentation they manage to do this using useEffect:
useEffect(() => {
  setUser({ loading: true });
  magic.user.isLoggedIn().then(isLoggedIn => {
    return isLoggedIn ? magic.user.getMetadata().then(userData => setUser(userData)) : setUser({ user: null });
  });
}, []);
https://magic.link/posts/magic-react-express Does useEffect somehow know that await magic.user.isLoggedIn() has changed? (I believe the .getMetadata() part can be ignored for now) I implemented this is react too:
(let [[logged-in? set-logged-in] (useState false)
        _ (useEffect (fn []
                       (.then 
                        (.. magic -user (isLoggedIn))
                        (fn [logged-in?]
                          (set-logged-in logged-in?)
                          #_(e/set-logged-in' logged-in?)))
                      []))] ...)
But the same problem arises. I’m not logged in the redirect after the magic link but have to refresh the page to be logged in

leif18:07:00

Is there any documentation on how to actually require macros defined in bootstrapped cljs?

leif18:07:23

(Like, I can define them just fine, but I can't seem to expand them.)

leif18:07:41

(Or even get bootstrapped clojurescript to require the correct file without explicitly using :require-macros

leif18:07:39

(oh, by bootstrapped I mean the self-hosted compiler)

dnolen18:07:03

it can be done but it requires cleverness

dnolen18:07:20

bootstrapped ClojureScript does not change the basic model

dnolen18:07:46

but you can subvert it - basically there is a hidden namespace which is the same name as the original but + $macros

leif18:07:18

Right, I see that in the compiled javascript.

leif18:07:37

Am I expected to actually explicitly put $macro at the end of my identifiers?

dnolen18:07:05

you're not supposed to do this at all is what I'm saying 🙂

dnolen18:07:25

we're not going to make it any easier

leif18:07:55

Oh, I see. So self-hosted clojurescript is just not supposed to have macros then, correct?

dnolen18:07:33

everything works in self-hosted same as regular ClojureScript

dnolen18:07:40

A) ClojureScript: macroexpand at runtime is impossible

dnolen18:07:51

B) Self host: macroexpand at runtime is necessary but a compiler detail

p-himik18:07:20

Damn, I thought you were going for "III)" next. ;)

dnolen18:07:22

give A) & B) - I still don't know what you are trying to do

leif18:07:48

I'm trying to make a clojurescript IDE in the browser.

dnolen18:07:03

now we're talking - we have a goal 🙂

leif18:07:05

Using the self-hosted variant.

leif18:07:27

(And I would ideally like to try making macros with that ide.)

dnolen18:07:29

so here is the problem

dnolen18:07:45

Clojure has one global namespace

dnolen18:07:00

ClojureScript has two global namespaces - one for runtime one for macros

dnolen18:07:20

because in ClojureScript you can have naming collisions between macros and fns

dnolen18:07:35

but it's not a problem

dnolen18:07:58

in self-hosted it becomes a problem right away - because you can't have these things live in the same place

leif19:07:00

Okay. (Hence the adding of $macro on the end, at least that's what it sounds like.)

leif19:07:24

So I guess, the question then becomes, how do I use these macros. What I've tried so far is:

;; example/core.clj
(ns example.core)
(defmacro add-three [x]
  `(+ ~x 3))
;; example/core.cljs
(ns example.core
  :refer-macros [example.core :refer [add-three]])

(println (add-three 4))
But it seems to be trying to call add-three as a function.

dnolen19:07:24

I think it's :require-macros ?

leif19:07:42

oops, yes, I meant :require-macros.

dnolen19:07:31

I never use :refer-macros sugar - even so the pasted code also has missing parens

leif19:07:47

The compiled output for core.clj is:

goog.provide("example.core$macros");
var ret__38016__auto___49 = bob.core$macros.add_three = (function example$core$macros$add_three(_AMPERSAND_form,_AMPERSAND_env,x){
return cljs.core.sequence.call(null,cljs.core.concat.call(null,(new cljs.core.List(null,new cljs.core.Symbol("cljs.core","+","cljs.core/+",(-342754435),null),null,(1),null)),(new cljs.core.List(null,x,null,(1),null)),(new cljs.core.List(null,(3),null,(1),null))));
});
(example.core$macros.add_three.cljs$lang$macro = true);
Which looks right.

leif19:07:42

But then I get

#error {:message Could not parse ns form example.core in file /example/core.clj, :data {:tag :cljs/analysis-error}, :cause #error {:message Invalid :refer, macro example.core/add-three does not exist in file /example/core.clj, :data {:tag :cljs/analysis-error}}}

dnolen19:07:50

maybe we should move this convo to #cljs-dev as it's a bit esoteric for most

leif19:07:05

Fair point.

✅ 2