Fork me on GitHub
#clojurescript
<
2022-08-04
>
wcohen00:08:18

Surprisingly basic interop question that’s been eluding me (and it’s quite possible that @mauricio.szabo has a good answer via spock, though its interop (https://gitlab.com/mauricioszabo/spock/-/blob/master/src/spock/swi.cljs#L177-211) appears a little fancier than what I may be going for): • I’ve got a emscripten-transpiled library, which means there’s a foolib.js and foolib.wasm file that got emitted locally, and which I’ve stuck in a resources folder (ie it doesn’t currently exist as an npm module, there’s no webpack bundle or anything else). How can I load that big emscripten-produced JS/WASM pair of files so that I can reference the Module object that emscripten makes available from a CLJS namespace? All my previous experience with js interop has been via node_modules stuff, so to date I’ve been relying on the magic behind the scenes when following the npm and webpack guides

mauricio.szabo03:08:25

Wow, you're up for a ride 😄. This library must have exported functions/procedures right? You will need to know how should you call these from C, and then translate these to Emscripten

mauricio.szabo03:08:36

It's not straighforward, honestly, but it's doable. Is more a JS interop with WASM than ClojureScript at this point

wcohen14:08:28

Makes sense. Based on this I went ahead and made the JS/WASM files into a small (local for now) npm module, and then am webpacking that in to a basic CLJS namespace per the guide at https://clojurescript.org/guides/webpack. Progress — in the cljs ns I’ve got a (:require [projwasm]) , which webpack didn’t argue with, and when I run clj -M -m cljs.main -co build.edn -v -c -r per the guide everything starts up nice. When I switch the repl to that namespace, and try to run (.default projwasm) to actually execute the emscripten JS and get the Module loaded along with its WASM, I immediately get hit with a CORS error and it fails. I imagine you hit something similar at some point. Any suggestions? Edit: Never mind — it’s a basic CLJS repl issue, unrelated to wasm!

wcohen15:08:33

Building on the above, I’ve now got a webpack-bundle-based minimal CLJS namespace with access to the required files, and I can get the repl going in a browser with clj -M -m cljs.main -co build.edn -v -c -r . The browser is able to get to the built .js, and .edn files, but it 404s when I try to access a .wasm in that same directory. Is there a permission setting I can pass to clj on the command line to enable the cljs repl browser to access wasm files too?

John David Eriksen15:08:53

Hey there, I have been trying to solve this Reagent / re-frame problem off and on for several months and haven't come across a reliable solution. I am experiencing this problem in Chrome on macOS. If I create a text input field and bind its value to an atom, the input field will re-render every time text is added. This is fine if I am appending text but if I want to use the backspace key to insert text in the middle of the string, then when the input field re-renders the cursor is forced to the end of the string. I am using the approach described here: https://stackoverflow.com/a/60761065

Michaël Salihi17:08:23

@jeriksen Could you please share a snippet of your parent component calling atom-input? You can try to replace :value with :default-value too. See for more information: https://github.com/day8/re-frame/issues/39#issuecomment-89794895

John David Eriksen18:08:24

Hi Michaël, thanks for following up! I didn't know about :default-value. While putting together a small example of the code to share with you I found a solution. We are using cljss for styling and I believe that using components created with defstyled are triggering the re-rendering issue. Here is the non-working code:

(def value (r/atom ""))

(defstyled my-input :input
  {:border "1px solid red"})

(defn input-field
  []
  (let [on-change #(reset! value (-> % .-target .-value))]
    (prn :rendered @value)
    [:div
     [my-input {:type "text"
                :key "my-input-test"
                :name "my-input-test"
                :value @value
                :on-change on-change}]]))
And here is the working code:
(def value (r/atom ""))

(defstyles my-input []
  {:border "1px solid red"})

(defn input-field
  []
  (let [on-change #(reset! value (-> % .-target .-value))]
    (prn :rendered @value)
    [:div
     [:input {:type "text"
              :class (my-input)
              :key "my-input-test"
              :name "my-input-test"
              :value @value
              :on-change on-change}]]))
Looks like defstyled made this code vulnerable to re-rendering for some reason. Using defstyles instead avoids this issue.

Michaël Salihi19:08:45

Great new that you fixed!

gratitude-thank-you 1
Michaël Salihi19:08:01

BTW interesting issue.

daniel.flexiana00:08:45

Have you tried calling the my-input instead of passing it in the vector? > (def value (r/atom "")) > > (defstyled my-input :input > {:border "1px solid red"}) > > (defn input-field > [] > (let [on-change #(reset! value (-> % .-target .-value))] > (prn :rendered @value) > [:div > (my-input {:type "text" > :key "my-input-test" > :name "my-input-test" > :value @value > :on-change on-change})]))

John David Eriksen15:08:14

Have not tried that. Will try it in the future. Thanks for the suggestion, @U037W3C7KTR.

👍 1