Fork me on GitHub
#clojurescript
<
2022-03-05
>
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`
"/var/folders/4b/47n5wqp92wxc7p888mspg7340000gp/T/jars/reagent/debug.clj"
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)?

thheller16:03:57

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.

thheller16:03:13

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

Chase16:03:04

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.

Chase16:03:23

I translated the example db listener function from https://firebase.google.com/docs/database/web/read-and-write?hl=en&amp;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);
});

Chase16:03:34

into

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

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

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

Chase16:03:42

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.

Chase16:03:07

In production I get:

Chase16:03:27

Which is kind of impenetrable for me.

thheller16:03:17

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

thheller16:03:42

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

Chase16:03:50

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

thheller16:03:08

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

Chase16:03:30

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

Chase17:03:04

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

thheller17:03:16

the idea was correct. just need the correct hint 🙂

Chase17:03:38

Yep, I was just reading through that

alex20:03:18

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?

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

p-himik21:03:59

Use React refs instead.

alex21:03:18

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?

p-himik22:03:51

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.

alex22:03:50

Ah yes, of course. Thank you!!

👍 1
DrLjótsson21:03:27

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

alex21:03:32

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

DrLjótsson21:03:01

Then I have two unresolved symbols 🙂

alex22:03:05

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

DrLjótsson22:03:27

Thanks, I'll try there!

neilyio21:03:05

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 com.google.javascript.jscomp.LoggerErrorManager 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 com.google.javascript.jscomp.LoggerErrorManager 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;
      ^^^^