Fork me on GitHub
#clojurescript
<
2019-12-03
>
lilactown00:12:07

has anyone built an STM-like lib for CLJS?

andy.fingerhut01:12:35

I do not know, but without threads in JavaScript, what would such a lib do?

lilactown01:12:36

mainly batching operations and scheduling

lilactown01:12:44

e.g. I want the ability to do something like:

(def foo (ref 0))

(add-watch foo :log prn)

(dosync
  (alter foo inc)
  (alter foo inc)
  (alter foo inc))

;; .. logs 3 and no intermediate values

Roman Liutikov01:12:46

Not sure about correctness, but I've built this one for node https://github.com/roman01la/node-stm

lilactown01:12:39

thanks @U0FR82FU1! this helps

jjttjj04:12:26

Javelin also implements dosync on its atom-like cells https://github.com/hoplon/javelin

cfleming00:12:51

Hi all, if I’d like to create a Node module with CLJS (i.e. with an exports section exporting some CLJS fns), how do I do that?

cfleming00:12:05

Looks like shadow can do this, can I do it with vanilla CLJS?

Roman Liutikov01:12:42

I think you'd need to assign exports for node manually in the code. export meta will just create a global var. Also set :target :nodejs in compiler options

cfleming04:12:32

I think you’d need to assign exports for node manually in the code.How would I do this? If I do something like (def exports {whatever whatever}) that will create a global var too. How can I coerce CLJS to just create an exports block in the output JS file?

Roman Liutikov07:12:36

(set! (.-exports js/module) #js {:whatever whatever})

cfleming08:12:58

Great, thanks!

Binita Bharati07:12:16

Hi folks, I am a newbie to Clojurescript. Trying to follow the Clojurescript official guide. Am unable to make browser repl with remote IP address work. I tried running cljs as clojure --main cljs.main --compile cljs-sample-proj.core -ro :host "192.168.10.12" --repl, but the -ro seems to be ignored, and no process starts up; command prompt at the console returns back without any errors. But, when , I run the same command without the -ro option, the server process starts at localhost:9000 . The console prints : Waiting for browser to connect to . I want this process to be listening on my specified IP instead of localhost. Any pointers how to get this working ? Thanks !

p-himik07:12:57

The documentation for the -ro option says:

Options to configure the repl-env, can be an EDN 
string or system-dependent path-separated list of 
EDN files / classpath resources. Options will be 
merged left to right.
Can you try something like -ro '{:host "192.168.10.12"}'?

Binita Bharati10:12:12

I tried clojure --main cljs.main --compile cljs-sample-proj.core -ro '{:host "192.168.10.12"}' --repl . Same result as before, i.e console's command prompt came back without errors, and no process has started

p-himik10:12:47

Ah, if we check clj --main cljs.main --help, we will see that cljs.main accepts init options, main options, and arguments. And -ro is an init option. Try placing it right after --main cljs.main.

Binita Bharati11:12:37

Thank you. Its working now with clojure --main cljs.main -ro '{:host "192.168.10.12"}' --compile cljs-sample-proj.core --repl. The console prints Waiting for browser to connect to ... . But, after that , the next step that I expected was to get the repl prompt, once I point my browser to http://192.168.10.12:9000`` . Unfortunately, that is not happening. Browser is opening with the expected default cljs home page as described in tutorial. The glitch is that the console is hanging at the last printed message which was Waiting for browser to connect to ... It's as though the browser never connected to the process, although I could see temporary TCP connections to the listening IP and port.

p-himik11:12:56

Do you see any (probably failed) connections to localhost in your browser's dev tools?

Binita Bharati11:12:34

yes, I can see one request URL (for which response never came back) has used localhost in the request URL. Its . Rest of the browser sent requests have used the network IP instead, and hence got response code 200. One of the successful request URLs is :

p-himik11:12:39

I see such behavior as well. There are also these options:

browser REPL options:
   -H, --host address         Address to bind
   -p, --port number          Port to bind
However, in my case --host is ignored for some reason.

Binita Bharati11:12:59

Ok.. its a dead end I guess. I even tried curl from the same VM where the process is running. Never got the repl prompt back.

p-himik11:12:05

That's because the prompt appears only after a correct POST request has been made to the correct endpoint.

p-himik11:12:27

I'm trying to find in the CLJS sources where the host can be overriden. It's defined here: https://github.com/clojure/clojurescript/blob/master/src/main/cljs/clojure/browser/repl.cljs#L31

p-himik11:12:45

Got it working with clj --main cljs.main -ro '{:host "192.168.1.220"}' -co '{:closure-defines {"clojure.browser.repl.HOST" "192.168.1.220"}}' --compile cljs-sample-proj.core --repl

p-himik11:12:24

Which is a bit stupid IMO since it seems like clojure.browser.repl.HOST should be set to the value of :host. But maybe I'm missing something.

p-himik11:12:32

(change the IP though)

johnj16:12:53

@p-himik Ran into this issue too, looks like a bug to me

Andy Carlile13:12:16

I'm trying to use @fullcalendar/react in a figwheel application but coming up against a lot of blocks trying to use :npm-deps or foreign-libs. I found a reagent wrapper in yogthos's ajenda repo but need to extend the functionality. How would I go about importing more js packages/functionality to a project?

herald13:12:22

You should check out https://github.com/thheller/shadow-cljs It aims to make interop with npm packages easier.

Lu14:12:03

When adding more npm dependencies I relied on webpack https://clojurescript.org/guides/webpack

mitchelkuijpers14:12:26

+1 for shadow-cljs we never looked back after moving to it

4
mitchelkuijpers14:12:11

Hi I am running into a issue, I have a external api that I need to use from clojurescript which uses .bind to add a event listener. When I write this in my code the code seems to get removed with advanced compilatoin

mitchelkuijpers14:12:56

I call it like: (.bind dialog "event-name" (fn [e}))

mitchelkuijpers14:12:45

It seems pretty logical that it breaks because Closure probably thinks that it is bind from default js

thheller16:12:04

@mitchelkuijpers bind is used on funcitons? (.bind (fn [e] ....) dialog) would make dialog the this when running the resulting function?

thheller16:12:33

or is this some function dialog provides?

mitchelkuijpers17:12:51

It is provided by dialog

thheller17:12:46

closure shouldn't be treating it as function.bind unless it actually knows dialog is a function?

thheller17:12:10

did you try by "cheating"? (let [bind-fn (gobj/get dialog "bind")] (.call bind-fn dialog your other args))?

mitchelkuijpers17:12:15

I did some of my own cheating that already worked

thheller17:12:40

hmm that is odd

thheller17:12:12

it might be because of some cheat externs shadow-cljs generates. I think ... it tags everything as function 😛

mitchelkuijpers17:12:05

Ah ok, we don't care it's a small hack. We love shadow-cljs

thheller17:12:45

never would have expected this to be a problem. I think closure just might end up removing it if you don't use the return value

thheller17:12:08

so you could likely use something like (goog.reflect/sinkValue (.bind ...)) to tell the closure compiler to keep the call

mitchelkuijpers17:12:45

Ah that sounds nice, will try that out tommorow. I have no access to a laptop right now. Thank you for your help

mitchelkuijpers08:12:05

The goog.reflect hack works like a charm, thank you I like that solution the best

👍 4
awb9917:12:38

Can someone help me with using dagre-d3 in clojurescript? I tried to port some easy demos from https://dagrejs.github.io/project/dagre-d3/latest/demo/shapes and https://jsfiddle.net/f4pahbme/8/ I keep getting the error "TypeError: this._in is undefined". This is my project: https://github.com/awb99/graph Error can be reproduced by running ./demo-run.sh I spent two days on this, and don'ẗ think I made a mistake. What I think happens is that when I try to render the graph, then it is re-creating a javascript object that contains the same data And this javascript object then lacks the "this". This is what I think happens.

thheller17:12:40

@hoertlehner don't know about your problem but your use of aget is certainly not helping 😛

awb9917:12:45

@thheller When I use shadow with / notation, is it then essentially getting map entries ?

thheller17:12:38

"getting map entries"? I'm assuming those are javascript options?

awb9917:12:21

var g = new dagreD3.graphlib.Graph().setGraph({});

awb9917:12:53

var render = new dagreD3.render(); render(inner, g);

awb9917:12:08

this is what I try to port

awb9917:12:20

dagre-d3 has a dependency on graphlib

awb9917:12:28

which it brings internally

awb9917:12:31

it is in the bundle.

awb9917:12:42

that shadow-cljs creates

thheller17:12:32

the code works fine for me?

thheller17:12:39

new dagreD3.graphlib.Graph().setGraph({});

(-> (darge-d3/graphlib.Graph.)
    (.setGraph #js {}))

awb9917:12:19

I think the graph creation works fine in my code base

awb9917:12:26

the error happens when I try and render the graph.

thheller17:12:46

I just run the code and get

p-himik18:12:15

Just did the same, got the exact same result. The exact steps:

git clone 
cd graph
npm i
npm i shadow-cljs
# Using npx here since I don't have shadow-cljs globally installed.
npx shadow-cljs watch demo

thheller17:12:29

your demo repo doesn't contain a shadow-cljs version

thheller17:12:43

so don't know which version you are on. maybe its an ancient one?

awb9917:12:56

[andreas@lggram graph]$ ./demo-run.sh shadow-cljs - config: /home/andreas/Documents/gorilla/graph/shadow-cljs.edn cli version: 2.8.76 node: v10.16.3

awb9917:12:18

I removed the aget syntax

awb9917:12:25

Error remains.

awb9917:12:07

I had to manually add the lodash dependency to package.json

awb9917:12:24

Otherwise shadow-cljs would complain.

awb9917:12:30

And now the error comes from lodash.

thheller17:12:16

I don't know. I took your project. ran npm install and then npm install shadow-cljs after noticing that it wasn't installed in the project

thheller17:12:28

then started the build and opened it. no problems.

awb9917:12:08

no error?

thheller17:12:27

see screenshot I posted above

thheller17:12:39

not sure if I'm supposed to do anything besides opening the page

awb9917:12:08

It works for you

awb9917:12:39

I will see if missing shadow cljs is the solution

awb9917:12:35

still error for me

thheller17:12:47

maybe try wiping the .shadow-cljs dir. maybe you got the cache into some kind of bad state.

p-himik17:12:43

On rare occasions, it's NPM. Either the way you used it or its version. You can try wiping out node_modules as well.

awb9918:12:17

The error remains.

awb9918:12:42

I cleaned it all

awb9918:12:44

[andreas@lggram graph]$ cat clean.sh #!/bin/bash rm node_modules -r rm out/public/js -r rm .shadow-cljs -r

awb9918:12:14

@p-himik npm --version brings 6.9.0 which is the latest version I can get on fedora.

awb9918:12:17

I just reinstalled npm.

awb9918:12:20

Same problem.

awb9918:12:39

I have now removed package-lock.json also

p-himik18:12:45

I have the same version.

awb9918:12:45

This is the nly thing I have not removed

awb9918:12:07

IT IS WORKING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11

awb9918:12:42

I honestly was getting crazy on this one.

awb9918:12:01

I actually already gave up in trying to use this graph library.

awb9918:12:12

THANKS SO MUCH!!

👍 12
😍 12
✔️ 4
🙂 4
gibb18:12:55

I want to write some shell scripts to do a few mundane tasks for work, and I figure it could be a nice place to try some clojurescript. Being a pretty big noob on the language and tooling, could someone point me in the right direction? I already know I want some kind of REPL and I want to use the nodejs file system APIs among other things. Since I undoubtedly will be stumbling along with the grace of an elephant in a china shop, a fast compile/transpile time would be great.

gibb18:12:50

Should I use Lumo? The clojure cli? Shadow cljs?

thheller18:12:00

if you just want to use some scripts lumo is fine. if you actually want to build something that'd be reusable on other machines or maybe even an npm package shadow-cljs might be better

gibb18:12:35

Thanks! I like the idea of creating a few npm packages eventually

gibb18:12:50

I used shadow-cljs for some browser stuff and it worked out well

thheller18:12:14

node scripts are way easier than browser stuff

gibb18:12:18

I’m a bit more hopeful then 😃

gibb18:12:19

Yikes the user guide has grown a lot since last time !

gibb18:12:22

well done

awb9919:12:19

@gbson perhaps you want to have a look at closh shell. - bash plus clojure

gibb19:12:36

That is interesting 😃 I briefly tried https://github.com/chr15m/flk/ as well

gibb19:12:07

Which is just bash but with clojureish syntax

awb9919:12:12

I like how closh has made the integration wirh bash

awb9919:12:31

Whatever is in (brackets) is clojure

awb9919:12:39

Cannot gwt easier than that

baflo19:12:27

Hi everybody, I'm new to cljs and want to create a project with basic cljs tools for interop with nodejs. I created a project with one cljs file and a commonjs module and try to require the commonjs module. However, the module seems to be empty: TypeError: module$workspaces$cljs$cljs_commonjs$src$js$greet.greet is not a function at Object.<anonymous> (/workspaces/cljs/cljs-commonjs/tmp-closure/greet/core.js:7:51) I build it using deps.edn and cljs.edn (my compiler options) and call the compiler as follows: clj -m cljs.main -co cljs.edn -v -c This is the git repo: https://github.com/baflo/cljs-commonjs I hope somebody can help me find the correct configuration 🙂

dnolen19:12:09

@flob.ms can you be a bit more clear? You shouldn't need to do anything to interop with Node.js

dnolen19:12:12

it's pretty well supported

gibb19:12:00

@thheller Easy enough to get going, thanks for the good docs!

👍 4
baflo19:12:03

@dnolen I have commonjs module at src/js/greet.js which I declare in an edn file as foreign lib and eventually require that in a core.cljs as [js.greet :as greet] but that namespace is always empty: TypeError: module$workspaces$cljs$cljs_commonjs$src$js$greet.greet is not a function

dnolen19:12:41

@flob.ms by commonjs do you mean like a Node.js file right?

dnolen19:12:25

you don't need Foreign libs for Node.js work

dnolen19:12:30

that's only for web stuff

dnolen19:12:35

the simplest thing to do is to just called js/require w/ the relative path of your lib (don't need the ns form)

baflo19:12:38

Ah, great. I'll try that. I was working with docs from https://clojurescript.org/reference/javascript-module-support Could you give me a link for further reading on working with nodejs?

dnolen20:12:06

there's not really much of a guide because there's not that much to it - though perhaps a guide would be nice - another docs low hanging fruit

baflo20:12:53

I just got back to keyboard trying js/require, but I'm still having some path issues. I guess I'll figure that out... but there're some follow-up questions: Would you use the require statement as follows just below the namespace statement: (def greet (js/require "../../js/greet.js")) or do you use another pattern? And should I compile the cljs code at all or just run it in some cljs runtime?

dnolen20:12:50

yes requires should come after ns form

dnolen20:12:21

I believe you can avoid the relative import by specifying main in your package.json - then you can use the ns form again

dnolen20:12:27

this probably something that needs to go in a guide

dnolen20:12:48

re: compiling

dnolen20:12:00

you always have to compile to JS to run anything

baflo20:12:49

I was thinking of an environment like Lumo which compiles on the fly

dnolen20:12:43

right - that's another option - I can't offer as much guidance there as I don't really use that regularly myself

baflo20:12:15

alright, so you'd opt to compile cljs using the java compiler before running it?

dnolen20:12:38

it's the standard option, so yes

baflo20:12:54

ok, thank you very much. I'll try on then :)

Andy Carlile22:12:29

This is something of a follow-up to a previous question, but I'm trying a new angle: I want to render react components in reagent. Specifically, @fullcalendar/react . I can load the modules if I'm using a shadow-cljs method but am getting deep in a rabbit hole trying to render them in react/cljs. FullCalendar is the most robust calendar API and there aren't any cljsjs packages nor anything native to cljs. I'm trying to follow the docs at . Are there any apps that I can use as reference or helpful guides to help me translate React code into Reagent?

p-himik22:12:55

Not sure I understand. shadow-cljs is a build tool, it has nothing to do with React/Reagent. Why would you want to get rid of it?

Andy Carlile22:12:01

Perhaps I can clarify: I do not want to get rid of Shadow - cljs. My code compiles with Shadow - cljs build but my issue comes from trying to use these particular modules in reagent

Andy Carlile23:12:13

I have, but maybe I've missed something. To what would you refer in the docs?

Andy Carlile00:12:28

here's my repo, set up with lein and shadow-cljs, with each of the modules i need to use successfully imported into the namespace. From there I'm at a loss.

Andy Carlile00:12:59

reagent/adapt-react-class fullCalendar returns an error, as does [:> fullCalendar]

p-himik07:12:05

Do you have an actual link to the repo so I could take a look?

johanatan23:12:14

is the following the best way to get rationals in cljs ?

mfikes23:12:23

@johanatan I don't recall ever seeing an alternative implementation. FWIW I wrote some reader support for it: https://github.com/mfikes/precise

johanatan23:12:53

oooh, that's nice. btw, there seems to be a couple of deficiencies in that library. how do you get a floating point back out of it? i tried using core's / on the result of numerator and denominator but those two barf when you have a rational such as 1/1 apparently that is just a google integer rather than a rational

johanatan23:12:52

i.e., if i'm not mistaken, this will fail: (e/numerator #exact/ratio 1/1)

johanatan23:12:59

i.e., i would hope that: (double (/ (e/numerator #exact/ratio 1/1) (e/denominator #exact/ratio 1/1))) would return 1.0

mfikes23:12:13

You'd need to use quotes with the readers, so for example

#exact/ratio "1/3"

mfikes00:12:26

But, 1/1 ends up being just a non-ratio 1.

mfikes00:12:45

(It seems to follow Clojure in that respect.)

johanatan00:12:27

Yes, that is the problem. I can’t see any way around it. How can I get a rational whole number?

mfikes00:12:27

(numerator 1/1) fails in Clojure

johanatan00:12:41

1/1, 2/2, etc

johanatan00:12:58

Well then this would be a problem in Clojure too

mfikes00:12:20

You'd probably have to resort to using the ratio? predicate, which gets messy.

johanatan00:12:38

Yea, that’s messy but I may have to

johanatan00:12:45

Although this wouldn’t be a problem in Clojure because double can accept a rational as input and also an integer as input

johanatan00:12:03

But exact doesn’t provide an impl of double

mfikes00:12:03

Ahh, I see what you are saying. You want something that does (defn double [rational] (/ (e/numerator rational) (e/denominator rational))) but handles the types in the tower polymorphically.

johanatan00:12:02

Yes either that or an ability to create a whole number rational so that defn would work with 1/1 as input and produce 1.0

andy.fingerhut00:12:08

I may have missed something in this conversation, but would it help if you wrote your own versions of numerator and denominator that return reasonable values when given ratios or integers?

johanatan00:12:55

Yea that could work. Or the impl of double that @U04VDQDDY sketched out could branch on ratio?

johanatan00:12:39

In my opinion, exact should have provided ‘double` in that manner

johanatan01:12:45

this is the code i'm trying to make work

johanatan01:12:51

(defn- size->rational [size]
  (-> size
      {:one-third (e// (e/native->integer 1) (e/native->integer 3))
       :one-quarter (e// (e/native->integer 1) (e/native->integer 4))
       :two-thirds (e// (e/native->integer 2) (e/native->integer 3))
       :half (e// (e/native->integer 1) (e/native->integer 2))
       :three-quarters (e// (e/native->integer 3) (e/native->integer 4))
       :full (e// (e/native->integer 1) (e/native->integer 1))}))

(defn- rational->double [r]
  (if (e/ratio? r)
    (/ (e/numerator r) (e/denominator r))
    (double r)))

(defn- size->pct [size]
  (format "%.02f%s" (-> size size->rational rational->double (* 100.0)) "%"))

(defn- is-full? [sizes]
  (e/>= (reduce e/+ (map size->rational sizes)) (size->rational :full)))

johanatan01:12:59

interesting e/+ and e/>= do work with a mixture of rationals and goog.integers

johanatan01:12:15

otherwise is-full? would've been a pita to write.