Fork me on GitHub
Joshua Smock16:03:40

I’m not sure if here or #shadow-cljs is the right channel, but I’ll start here and can forward there if needed. I posted before about trying out the self-hosted compiler and, after reading about shadow’s bootstrapping, I’ve gotten something kind of working. I’m able to run a namespace’s source through cljs.js/analyze-str and have it load and analyze the file and its dependencies, but if one of those deps loads some macros, I get the following error (in my case, I’m testing out using Reagent):

#error {:message "Invalid :refer, macro reagent.debug/dev? does not exist in file /var/folders/4b/47n5wqp92wxc7p888mspg7340000gp/T/jars/reagent/debug.cljs", :data {:tag :cljs/analysis-error}}
I know that I loaded the macro file beforehand, because earlier in my logs I have the following lines:
:load-fn {:name reagent.debug, :macros true, :path "reagent/debug"}
:generate-module-definition reagent.debug true ; <-- log from my function used to generate the {:lang :source :file} map passed to `cb` in `load-fn`
where the first line is what was passed into load-fn and the last was the file that was found (which is the correct file). I didn’t see any docs about special handling of macro files in the source or elsewhere. Do I need to do something special when loading a macro file in analyze-str (or compile-str)?


I can't tell you how since I don't know but yes. Macros do require special handling.

👍 1
Joshua Smock16:03:18

:thumbsup: Thanks @U05224H0W, I thought it might be the case. I know that the namespace needs to be turned into ns$macros but I assume that this happens automatically by the analyzer after returning the source in load-fn ’s cb , however I may be wrong.


yeah can't say how you get the self-host analyzer to do this but that is the gist of it

👍 1
Joshua Smock17:03:53

Ok I did some debugging and found that cljs.analyzer/check-use-macros , which uses /missing-use-macros , is what’s causing the error. missing-use-macros calls a function which calls cljs.core/find-macros-ns , which looks up the namespace in cljs.core/NS_CACHE, and reagent.debug$macros isn’t in that cache. NS_CACHE seems to be a map atom that holds ns as the key and an instance of cljs.core/Namespace as the value I wonder if there’s a way I can add the analyzed namespaces to the cache manually


Does anyone use Firebase 9? I'm having trouble updating a tutorial's instructions to it. The app works fine in dev mode but breaks in the deployed production app. I believe it has to do with my db-subscribe function.


I translated the example db listener function from;authuser=0#web-version-9_2:

import { getDatabase, ref, onValue} from "firebase/database";

const db = getDatabase();
const starCountRef = ref(db, 'posts/' + postId + '/starCount');
onValue(starCountRef, (snapshot) => {
  const data = snapshot.val();
  updateStarCount(postElement, data);



(ns giggin.fb.db
    ["firebase/database" :refer (getDatabase onValue ref)]
    [clojure.string :as s]
    [giggin.state :as state]))

(defn db-ref
  (let [db (getDatabase)]
    (ref db (s/join "/" path))))

(defn db-subscribe 
  (onValue (db-ref path) (fn [^DataSnapshot snapshot]
                            (reset! state/gigs 
                                    (js->clj (.val snapshot) :keywordize-keys true)))))


I get a weird type error in production. In dev mode, I print out the DataSnapshot and it's value and it is all correct.


In production I get:


Which is kind of impenetrable for me.


this is an externs issue. something is getting renamed. this is caused by your ^DataSnapshot annotation which is incorrect. it basically tells the compiler that this is safe to rename. use ^js instead and it should be fine


you can get a better understanding about what is getting renamed via shadow-cljs release app --pseudo-names


Ahh! Let me try that. I would have no clue. thanks so much.


which will likely cause the error to be a.$val$ is not a function instead of the other


It works! So awesome. And I had thought I was so clever adding in that type hint to solve a warning that shadow cljs was giving me. Haha


Thanks for the quick response. I didn't think anyone would be able to help on such a niche, specific error.


the idea was correct. just need the correct hint 🙂


Yep, I was just reading through that


hi there, I'm trying to impl this snippet of code but having trouble getting the onload DOM event to fire. this hiccup compiles to React. anyone have a tip?

  {:rel "preload"
   :as "style"
   :onload "this.onload=null;this.rel='stylesheet'"
   :href "/some-file.css"}]


Use React refs instead.


That makes sense given the use of this. However the issue I'm observing is that :onload doesn't get triggered whether I pass a string of js or a function. Are you suggesting that I set the "onload" attribute directly on the ref?


I'm suggesting not to use onload at all. :) In React, ref is onload. The corresponding function is called (or the ref object is set) when the object is mounted, and the argument is the DOM node.


Ah yes, of course. Thank you!!

👍 1

Can I typehint a js event so that Cursive recognizes for example .stopPropagation?


Yep, you can add the type hint in the argvec [^js e] or at the callsite


Then I have two unresolved symbols 🙂


Ah sorry, spoke too soon. I'm not familiar with the way Cursive handles this. If nobody gets back to you here, there's also a #cursive channel


Thanks, I'll try there!


I’ve been trying to deal with this for a few days, hoping to get a hint from someone who has seen this before… I’m finding I’m getting 15 of these warnings when I compile a single user.clj file. This is a minimal file, it's just importing a couple CLJS dependencies. It finishes compiling, but my Clojure process prints warnings like the one below, and I get JavaScript errors (missing WebSocket?) as soon as I load the compiled output into the browser. These warnings don't seem to be coming from Clojure, but directly from the Closure Library. And indeed, I look in my inferred_externs.js file, and see 15 references to symbols like goog.require. Lately, I’ve tried to more deeply understand how externs work, and it doesn't seem right to me that I should ever see goog.* references inside inferred_externs.js. Why would the Google Closure Library need to refer to itself as an extern?

Feb 26, 2022 4:10:09 PM println
WARNING: .compiled/cljs/inferred_externs.js:37:0: WARNING - [JSC_UNDEFINED_EXTERN_VAR_ERROR] name goog is not defined in the externs.
  37| goog.writeScriptTag_;
Feb 26, 2022 4:10:09 PM println
WARNING: .compiled/cljs/inferred_externs.js:38:0: WARNING - [JSC_UNDEFINED_EXTERN_VAR_ERROR] name goog is not defined in the externs.
  38| goog.require;