Fork me on GitHub
#clojurescript
<
2017-01-02
>
emccue00:01:17

And to @qqq, general advice I would give is that If you can find a tutorials for it that you can understand/know how to do it on one and you dont plan to have a backend that is complex enough to give too much thought to the finer points of your server, puts names in a hat.

deas09:01:55

Are there any guidelines on how to compile things aiming at http/2?

thheller10:01:21

@deas same as http/1

deas10:01:14

@thheller Really? I mean resource aggregation makes sense with http/1. Much less with http/2.

thheller10:01:39

it is not about aggregation, it is about not downloading code you don't use

thheller10:01:44

closure takes care of that for us

deas10:01:17

In my case, emitted optimized javascript is roughly 3 MB.

thheller10:01:18

say you only use one function from a namespace, but in contains 1000

thheller10:01:26

closure will remove it as dead code

thheller10:01:33

http/2 would still download the entire file

deas10:01:45

Agree that tree shaking still makes sense.

thheller10:01:56

how many foreign libs do you have?

thheller10:01:01

and how much is it gzip'd?

deas10:01:43

The 3GB is w/o gzip, but pretty much all libs bundled.

thheller10:01:15

I mean how many non-cljs/closure js libs do you use

thheller10:01:22

aka cljsjs packages

thheller10:01:43

react and stuff

deas10:01:46

Roughly a dozen. CodeMirror is the biggest one.

thheller10:01:12

so of that 3mb, probably 50% or more aren't actually cljs/closure compatible

thheller10:01:24

it makes sense to bundle them separetely

thheller10:01:37

since they won't change as frequently as your own code will

deas10:01:47

Good point.

thheller10:01:00

and aren't dead-code processed anyways

thheller10:01:08

http2 gains a bit over http1 here if you use many separate libs

thheller10:01:48

but I would probably still recommend this for http1

thheller10:01:40

it all depends on how many foreign libs you are using

thheller10:01:54

cljs/closure is already doing pretty much the ideal

thheller10:01:53

also in my experiments the biggest gain you can get

thheller10:01:09

is by using <script async> or defer for loading the scripts

thheller11:01:04

and adding a Link: <https://example.com/other/styles.js>; rel=preload; as=script http header or html <link>

thheller11:01:21

so the browser can start downloading the js ASAP

thheller11:01:33

but not block the main thread

thheller11:01:11

although pretty much only chrome implements that

deas11:01:22

@thheller Makes all perfect sense. Thanks!

pbaille16:01:34

Hi! How can I specify an absolute asset-path to the cljs compiler?

dnolen16:01:39

@pbaille did you try it and it didn’t work?

kim016:01:08

As a newbie starting to learn cljs (focus on react / react-native) .. Should I focus on boot or lein more

pbaille16:01:19

I've just seen in the doc that you should pass a relative path to :asset-path option

pbaille16:01:53

but i'm going to try to give an absolute path

ezmiller16:01:05

Hi All, wondering what people would suggest in an odd situation I’m encountering working with a js library that works on promises (or mostly on promises). Consider this code:

(let [rv (transient [])]
  (-> (open-repo)
  (.then #(.getMasterCommit %))
  (.then #(.getTree %))
  (.then (fn [tree]
           (-> (.walk tree)
               (.on "entry" #(conj! rv (build-entry-data %)))
               (.on "end" #(js/console.log (clj->js (persistent! rv))))
               (.start))))))
This is code that uses nodegit to interact with a git repo. What it basically does is try to gather an array of file objects for all that files in the repo. The problem I’m encountering is that the piece that traverses this git object tree (the walker produced by (.walk tree) is an EventEmitter rather than a promise. So whereas the above code should return an array of promises for each file object, instead it can only return the walker. The function returns, in other words, before the “end” event fires. If I were writing JS, I’d probably fashion the block enclosing the tree walker as a Promise, return that, and manually resolve when the end event fires. But I’m unsure how to handle this in clojurescript… Can anyone suggest a good approach?

dnolen16:01:16

@kim0 it doesn’t really matter, the only time it would make a difference is if you want to use Cursive/IntelliJ (doesn’t understand boot yet)

kim016:01:05

I don’t care much for IDEs .. although I had cursive in mind

kim016:01:19

ie. vscode (or atom) are good enough for me

kim016:01:27

I’m a vimmer .. emacs not for me

pesterhazy16:01:50

Terminology question: How do people call something that behaves like an atom but may not be? (reagent/atom, reagent/cursor)

pesterhazy16:01:14

my ideas: dereffable, atomic

dnolen16:01:35

@ezmiller I don’t follow why you can’t do what you would do in JS?

dnolen16:01:07

@pesterhazy IDeref is for deref’ing, the watch capability is IAtom

pesterhazy16:01:42

[input-ui ideref] doesn't quite roll off the tongue though

pesterhazy16:01:53

(as in a reagent component)

pesterhazy16:01:11

re-frame uses model

dnolen16:01:37

if you’re deref’ing it almost always a mutable thing - state

pesterhazy16:01:28

hm state sounds good

ezmiller16:01:23

@dnolen I think my question is how one would go about doing that. Creating the promise also through interop? (like (def promise (fn [resolve reject] …))) Or is there a more vernacular way of creating a promise?

dnolen16:01:56

@ezmiller promises is JS concept, not a ClojureScript one - there is no idiomatic way of dealing with this - it’s just interop

ezmiller16:01:56

@dnolen okay duly noted. I think my confusion comes from having noticed (but so far avoided thinking about) things like promise and promise-chan in the clojure docs...

hbprince16:01:31

is om tightly coupled with react ? anyway to use libraries like preact with preact-compat in om ?

dnolen16:01:09

@renlinx it is coupled to react, making it work with other things is interesting but not a priority for me - btw there’s an #om channel

dnolen16:01:38

@ezmiller yeah those are core.async things - and the semantics are a bit different from JS promises

ezmiller16:01:30

@dnolen I’ve been surprised that I haven’t needed to get into those clojure async concepts yet. By contrast, I’ve also been wondering whether the fact that I often end up working with JS promises in cljs code means I’m doing something wrong. That is the broader context for the question I think.

dnolen16:01:01

@ezmiller if you’re using a library which relies on promises I don’t see how you can avoid it

dnolen16:01:15

if you’re not then yes I would manage asynchrony with core.async instead

ghaskins16:01:37

@ezmiller: fwiw, I use the funcool/promesa library and I often wrap interop promises inside them when necessary

ezmiller16:01:40

Okay. Thanks for the guidance.

ghaskins16:01:03

I there I wrap an ES6 interop promise into promesa

ezmiller16:01:41

@ghaskins allows you to handle promises in a more clojure-y syntax I suppose?

ghaskins16:01:50

Yeah. I originally started using promesa for de-callbackifying interop code in general, but I found it works well for even interop with things that already supported promises

ghaskins16:01:59

I'm sure there are other ways to do it and probably more elegant ways, but thought I'd share

mpenet16:01:13

a good way to do this would be to have a thin wrapper that returns a core.async/promise-chan no?

mpenet16:01:29

(that's what I usually do on the jvm side)

hbprince17:01:28

is there any way to do the alias trick like js projects in clojurescript possible?

jsus18:01:07

I got a problem with reagent

jsus18:01:56

I'm using Form-2

(defn component [props]
  (let [something "something"]
      (fn []
          [:div "test"])))

jsus18:01:08

And it doesn't render even the first time

emccue18:01:17

@jsus Form 2 components pass their parameters from the outer scope to the inner function, so in your case "component" takes one arg "props", so the inner (fn [] ..) should be of the form (fn [props] ...) Try that and see if it solves your issue.

kim018:01:18

When I do lein new figwheel whip -- --reagent .. who is handling that last —reagent

jsus18:01:02

@emccue I tried even without any args

jsus18:01:19

I'm just calling now (component)

emccue18:01:10

If you wouldn't mind, perhaps a screenshot or the full code snippet might help me spot the issue

emccue18:01:53

Also the output from your browser's console might be helpful if an error is appearing there

emccue19:01:26

Also remember that while reagent components are functions, you don't actually want to call them like functions

emccue19:01:24

So like if you have (defn root [] (component)) That will only work for type 1 components. For type 2 and 3 (and also for type 1 so that reagent can cache results), put the components in vectors like (defn root [] [component])

richiardiandrea19:01:20

@kim0 I think it is passed to lein new

kim019:01:37

@richiardiandrea Thanks .. so I guess this means that lein can add reagent to almost any template ?

richiardiandrea19:01:14

@kim0 no basically probably the figwheel template handles it

mikethompson19:01:11

@jsus the code you provide seems fine (although rightly corrected by @emccue for inner props), so there's something else going on. Perhaps take this across to the #reagent channel.

jsus20:01:04

Thnx, I have to check the proposed solutions, will report if it fixes

baptiste-from-paris22:01:54

hello guys, I am reading the om code; does anyone know what

(extend-type default,,,)
does

baptiste-from-paris22:01:46

I mean default because I know what extend-type does 🙂

dnolen22:01:47

@baptiste-from-paris it defines a default implementation in case some type is encountered which doesn’t implement it directly

baptiste-from-paris22:01:57

@dnolen thx 🙂! and where the default value comes from ?

dnolen22:01:14

@baptiste-from-paris I don’t know what you mean

baptiste-from-paris22:01:30

let me try to translate noob -> english

baptiste-from-paris22:01:22

ok I found the answer

baptiste-from-paris22:01:37

* default, meaning the definitions will apply for any value,
     unless an extend-type exists for one of the more specific
     cases below.

baptiste-from-paris22:01:39

@dnolen do you know if there is an annoted explanation of om ?

dnolen22:01:16

@baptiste-from-paris there is not, also there is an #om channel

cfleming23:01:21

@dnolen We spoke a while ago about user-defined analysis passes in the CLJS compiler. Is that currently a thing, or is it a future plan?

dnolen23:01:52

@cfleming there’s a dynamic var you can use for setting passes

cfleming23:01:14

Oh nice. I see some pass examples there too, thanks.

cfleming23:01:27

Can passes currently manipulate the AST or just collect information?

cfleming23:01:10

Ah, it looks like they accept and return an AST.

cfleming23:01:14

That’s awesome, thanks.