Fork me on GitHub
#clojurescript
<
2020-09-08
>
ozzloy06:09:43

i'm following this: https://www.learn-clojurescript.com/section-2/lesson-14-performing-io/ . under "Handling Events", when i try point 2, (gevents/listen input gevents/EventType.KEYUP update-target), i get WARNING: Use of undeclared Var goog.events/EventType at line 2 <cljs repl>

rpkarlsson09:09:50

Testing in a repl led me to:

goog.events/EventType.KEYUP
;; => nil

goog.events.EventType.KEYUP
;; => "keyup"

(.-KEYUP goog.events.EventType)
;; => "keyup"
It looks to me like bad interop syntax in the course example but I'm unsure as I dont do that much JS interop. I would expect anything after / to be a function not an attribute lookup.

rpkarlsson09:09:32

Scratch that. Actually running it gives me the same results as the course.

(require '[goog.events :as gevents])
 gevents/EventType.KEYUP
;; => "keyup"

ozzloy06:09:27

and this https://google.github.io/closure-library/api/goog.events.EventType.html seems to be saying that goog.events.EventType.KEYUP exists

ozzloy06:09:39

however, if i replace gevents/EventType.KEYUP with "keyup", things work as expected. what's wrong with gevents/EventType.KEYUP?

thheller09:09:42

it mostly allows the code to be minified more. ie. when closure minifies goog.events.EventType.KEYUP it turns into aB or so which is much shorter than "keyup" in the final release build. doesn't really matter much but thats the reason I believe.

Andreas S.09:09:00

Hello everyone! I'm just trying to follow the steps here: https://clojurescript.org/guides/quick-start , but i'm on windows and I get an error if I try a PRODUCTION build, normal build works OK, but on Production build I get this:

Andreas S.09:09:03

Exception in thread "main" java.nio.file.InvalidPathException: Illegal char <:> at index 2: /C:/Users/ascheinert/Downloads/cljs_hw/out/cljs/core.js
        at java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
        at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
        at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
        at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92)
        at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:229)
        at com.google.javascript.jscomp.SourceMapResolver.getRelativePath(SourceMapResolver.java:102)
        at com.google.javascript.jscomp.SourceMapResolver.extractSourceMap(SourceMapResolver.java:63)
        at com.google.javascript.jscomp.JsAst.parse(JsAst.java:168)
        at com.google.javascript.jscomp.JsAst.getAstRoot(JsAst.java:55)
        at com.google.javascript.jscomp.CompilerInput.getAstRoot(CompilerInput.java:133)
        at com.google.javascript.jscomp.Compiler.parseInputs(Compiler.java:1720)
        at com.google.javascript.jscomp.Compiler.parseForCompilationInternal(Compiler.java:939)
        at com.google.javascript.jscomp.Compiler.lambda$parseForCompilation$4(Compiler.java:922)
        at com.google.javascript.jscomp.CompilerExecutor$2.call(CompilerExecutor.java:102)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:835)

takis_11:09:33

Hello : ) I want to convert 1 clojure function to 1 "standalone" javascript function. I want to use this function inside mongoDB,that only allows 1 function without extra dependencies. Is it possible to do it with Clojurescript? If its not possible any alternative way?

borkdude11:09:41

@takis_ You can export the function and compile it with CLJS. A very hacky way is this (from planck):

cljs.user=> (defn foo [x] (inc 1))
#'cljs.user/foo
cljs.user=> (str foo)
"function cljs$user$foo(x){\nreturn ((1) + (1));\n}"

takis_11:09:26

all the code needed will be inside that function?

borkdude11:09:47

no, probably not. thus you will need to compile it with CLJS properly

borkdude11:09:14

Use ^:export to make it available in the compiled output

takis_11:09:35

i am new with clojurescript,the times that i compliled it,it produces many large javascript files

borkdude11:09:54

@takis_ You'll have to use advanced compilation, so it cuts away everything that's not used

borkdude11:09:12

and then you can paste that JS into mongo (hopefully)

takis_11:09:26

ok but still it will be possible,to convert all in 1 standalone function?

borkdude11:09:22

JS is very flexible so I'm pretty sure you could make it into just one function.

borkdude11:09:27

using closures

takis_11:09:47

ok thank you , i am new , i will try it : )

takis_11:09:21

If someone experienced in clojurescript can convert this function to 1 "standalone" javascript function, it will be helpful, of how he did it

(defn mygroupby [v k]
  (reduce (fn [grouped-array doc]
            (let [cur-key (str (get doc k))]
              (if (contains? grouped-array cur-key)
                (update grouped-array cur-key conj doc)
                (assoc grouped-array cur-key [doc])))) 
          {}
          v))

borkdude11:09:27

@takis_ put your file in a src folder, add ^:export to it, like:

(ns my.cljs)

(defn ^:export mygroupby [v k]
  (reduce (fn [grouped-array doc]
            (let [cur-key (str (get doc k))]
              (if (contains? grouped-array cur-key)
                (update grouped-array cur-key conj doc)
                (assoc grouped-array cur-key [doc]))))
          {}
          v))
Then compile with:
$ clojure -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.10.597"}}}' -m cljs.main -O advanced -c my.cljs
Find the compiled asset in out/main.js

borkdude11:09:09

Looking at the output size this will probably make you write this function in JS instead, but that's up to you :)

takis_11:09:48

thank you 🙂 we will see

Milan Munzar11:09:38

Hey, 🙂 It seems to me that there is some problem with name resolution in defrecord when defining method named delete . In the following code it fails with a type error saying that delete is not a function. However when I rename it to del or something else it works as expected. Also I am able to call it like ((:delete foo)). Does anyone knows what is going on? Thx 🙂

(defn make
  [ddb-client]
  (map->DBClient {:get    #(-> ddb-client .get .promise)
                  :put    #(-> ddb-client .put .promise)
                  :query  #(-> ddb-client .query .promise)
                  :delete #(-> ddb-client .delete .promise)}))

(def foo (make client))
(.delete foo)

thheller12:09:18

most likely https://clojure.atlassian.net/browse/CLJS-871 since delete is also a reserved word

👍 3
borkdude11:09:55

@takis_ :

> require('./out/main')
{ my: { cljs: { mygroupby: [Function: Ee] } } }
This is in node

takis_11:09:32

ok thank you i am trying it now

borkdude11:09:21

Maybe -t node also helps in some regard, not sure if it's relevant here

takis_12:09:48

@borkdude i still try to run it,but i cant

takis_12:09:04

1)created a folder jsgen 2)created a folder jsgen/src 3)put my.cljs inside jsgen/src 4)cd jsgen 5)clojure -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.10.741"}}}' -m cljs.main -O advanced -c my.cljs Execution error (FileNotFoundException) at http://java.io.FileInputStream/open0 (FileInputStream.java:-2).-Sdeps (No such file or directory) Full report at: /tmp/clojure-11667070442944232008.edn

borkdude12:09:22

@takis_ it should be my/cljs.cljs

borkdude12:09:51

so the dir structure is jsgen > src > my

takis_12:09:07

1)created a folder jsgen 2)created a folder jsgen/src/my 3)put my.cljs inside jsgen/src/my 4)cd jsgen 5)clojure -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.10.741"}}}' -m cljs.main -O advanced -c my.cljs Execution error (FileNotFoundException) at http://java.io.FileInputStream/open0 (FileInputStream.java:-2). -Sdeps (No such file or directory) Full report at: /tmp/clojure-6401545215020083189.edn

takis_12:09:26

i dont know why i cant run it, i should install anything else first?

takis_12:09:48

the my.cljs is the file you sended me above

noisesmith12:09:34

"-Sdeps (no such file or directory)" - I bet your "clojure" isn't the one that uses deps.edn

noisesmith12:09:39

check out which clojure

noisesmith12:09:17

it's saying that it wants to open -Sdeps as a file, which probably means someone's old useless bundling of clojure

takis_12:09:49

clojure Clojure 1.10.1 user=> exit

takis_12:09:08

it says 1.10.1

takis_12:09:59

how to install a clojure that can use deps.edn

noisesmith12:09:54

deps.edn isn't a version of clojure, what I'm saying is there are CLI tools called "clojure" that don't use deps.edn, the which tool will help you figure out what actually runs if you run clojure at the command line

noisesmith12:09:23

eg. debian has a "clojure" that just runs java and loads the clojure library and runs clojure.main

noisesmith12:09:47

which isn't what most people would want these days

noisesmith12:09:44

here's me verifying that my "clojure" knows what Sdeps means

$ grep Sdeps $(which clojure)
    -Sdeps)
	 -Sdeps EDN     Deps data to use as the last deps file to be merged

takis_13:09:46

i done it thank you, i installed clojure using brew

takis_13:09:58

but now i get different error

takis_13:09:00

clojure -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.10.741"}}}' -m cljs.main -O advanced -c my.cljs Execution error (AssertionError) at cljs.closure/build (closure.clj:3098). Assert failed: No file for namespace my.cljs exists uri Full report at: /tmp/clojure-17078041070905694243.edn

noisesmith13:09:58

if the ns is my.cljs you need to have src/my/cljs.cljs

noisesmith13:09:15

cljs is a weird name for an ns btw

takis_13:09:07

it worked,but now i see so many files and directories

dpsutton13:09:15

If you read the get started article it should go over all this. If you create an advanced optimizations build you will have only a single file as output

takis_13:09:20

i just runned clojure -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.10.741"}}}' -m cljs.main -O advanced -c my.cljs

takis_13:09:03

in the past i created one simple clojurescript hello world , for node.js

takis_13:09:47

do you have a link of what to read to produce 1 single file as output?

dpsutton13:09:04

Your steps above with advanced should have produced a single output. Probably you have some remnants from past compilation hanging around. Delete the output directory and run it again and I suspect you will be fine. Alternatively give a new output location and you should see the single generated file I suspect

takis_13:09:46

i see those,i deleted the out,and re-run the clojure -Sdeps .......

takis_13:09:28

the main.js is that 1 single file?

takis_13:09:58

it is its working 🙂

takis_13:09:56

thank you for your patience , you helped me alot, dpsutton ,noisesmith , borkdude 🙂

👍 3
dpsutton13:09:12

good luck! one question, did you need a single file or a single function?

dpsutton13:09:55

it might be impossible to have everything self-contained in a single function.

borkdude13:09:48

I guess you can wrap that entire "namespace" object in a closure

borkdude13:09:11

but honestly I don't know why you would want that

takis_14:09:26

i need a single function,and able to call it with it arguments

takis_14:09:55

but still 1 file is big step

borkdude14:09:19

@takis_ you can do const { my } = require("./out/main"); which will give you my.cljs.yourfunction as the one function

borkdude14:09:35

$ node
Welcome to Node.js v14.5.0.
Type ".help" for more information.
> const { my } = require("./out/main");
undefined
> my.cljs.mygroupby
[Function: Ee]

takis_14:09:06

perfect 🙂 thats exactly what i need it , thank you alot i was thinking that no way i can clean all those code

takis_14:09:18

i have 1 fucntion now callable from js

ozzloy20:09:16

weird, i'm getting this at the cljs repl: cljs.user> gevents/EventType WARNING: Use of undeclared Var goog.events/EventType at line 1 <cljs repl> #js{:INPUT "input", :SUSPEND "suspend"

ozzloy20:09:41

it says goog.events/EventType is undeclared, but also prints out a js object

ozzloy20:09:48

i've truncated the output

ozzloy20:09:36

what is going on here? cljs.user> (goog.object/get gevents/EventType (clj->js :KEYUP)) WARNING: Use of undeclared Var goog.events/EventType at line 1 <cljs repl> "keyup"

ozzloy20:09:36

it says the var is undeclared, but also gives the expected answer

phronmophobic20:09:20

how are you requiring gevents?

ozzloy20:09:46

(require '[goog.events :as gevents])

ozzloy20:09:05

gives no error, returns nil

ozzloy20:09:36

@smith.adriane thanks for looking

phronmophobic20:09:33

i'm trying to see if I see the same issue, but I just updated my OS and nothing is working atm ¯\(ツ)

ozzloy21:09:57

figured out a fix, still not sure what's going on, but this works: (require '[goog.events.EventType :refer [KEYUP] :rename {KEYUP keyup}])

ozzloy21:09:57

the difference is between (require '[goog.events] ...), versus (require '[goog.events.EventType] ...) but i'm not sure how that would "work" and give a warning.

phronmophobic21:09:54

it probably works without optimizations, but might not work under advanced compilation

lilactown21:09:25

I wonder if EventType is one of those classes that needs to be imported

3
lilactown21:09:37

On mobile otherwise I would check

drewverlee23:09:45

I understand how an atom interacts on top of the jvm (multithreaded compare and swap) but on the browser what role does it play? I imagine conceptually it could be used with web workers

lilactown23:09:37

an atom is pretty much just an object with a state property that gets changed on swap! / reset! , and calls watchers on update

lilactown23:09:20

I don’t think the atom API could be used with web workers because it’s expected that reset! and swap! will block until the value is updated, but that’s impossible to do in a JS environment + web workers

👍 3