Fork me on GitHub
#clojurescript
<
2015-10-10
>
ul08:10:26

Any caveats of doing extend-type against js/String?

thheller09:10:10

@ul probably better to extend string, extending native javascript objects does not work properly in some browsers

thheller09:10:22

mostly IE8- though

thheller09:10:33

never had issues in proper browsers

ul09:10:38

trying to do smth like this (extend-type string IFn (-invoke [s x] (get x s)))

ul09:10:59

getting:

cljs.user=> (extend-type string IFn (-invoke [s x] (get x s))) ("z" {"z" 1})
#object[Function "function (s,x){
return cljs.core.get.call(null,x,s);
}"]
cljs.user=> ("z" {"z" 1})
#object[TypeError TypeError: "z".call is not a function]
TypeError: "z".call is not a function
    at eval (eval at figwheel$client$utils$eval_helper (), <anonymous>:1:93)
    at eval (eval at figwheel$client$utils$eval_helper (), <anonymous>:9:3)
    at eval (eval at figwheel$client$utils$eval_helper (), <anonymous>:14:4)
    at figwheel$client$utils$eval_helper ()

thheller09:10:01

hmm not sure that is supposed to work, I'd definitely recommend not to do this

thheller10:10:51

are you using :static-fns by any chance? that would prevent that from working

thheller10:10:00

@ul nope, it is a compiler issue

thheller10:10:07

just checked the generated js

thheller10:10:40

(let [s "z"] (s {"z" 1})) might work

thheller10:10:17

just do (get {"z" 1} "z") 😛

thheller10:10:26

CLJS would have to replace String.prototype.call which is not a great idea IMHO

ul10:10:35

yes, it is not great idea, I agree

ul10:10:25

but only because of implementation details

ul10:10:08

i want it to be possible and without dragons )))

thheller10:10:58

(-invoke "z" {"z" 1}) probably works

thheller10:10:32

we could probably teach that to the compiler in the spirit of being more like clojure

thheller10:10:10

but not sure if that would introduce more issues, maybe try a JIRA issue. not sure if this has been discussed before

cvermilion14:10:58

@maria, thanks for the blog pointer, but I’ve seen the documentation a few places and as far as I can tell, when I build with :optimizations :whitespace, the compiler doesn’t emit the CLOSURE_UNCOMPILED_DEFINES variable; I set up a simple repo to demo what I’m seeing: https://github.com/cvermilion/goog-define-bug

cvermilion14:10:31

would love to figure out what I’m doing wrong 😕

dnolen14:10:40

@ul it's unlikely that we’ll support extending primitive JS types to IFn

dnolen14:10:48

little benefit and a lot of hassle

dnolen14:10:29

@ul and you should never extend-type JS primitive types - extend-type js/String will definitely cause problems.

dnolen14:10:34

extend-type string instead

ul14:10:02

@dnolen: thanks, got it. I understand trade-off, but have some dreams about perfect CLJS simple_smile

dnolen14:10:26

yeah not interested in this particular enhancement

bensu14:10:58

@dnolen: I have some tooling that needs to know the compilers default :output-dir. Do you think it's wise to expose something like cljs.closure/add-implicit-opts? https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/closure.clj#L1569

bensu14:10:41

one more thing (I did search for this simple_smile

bensu14:10:32

the externs file for node has only two symbols

bensu14:10:51

do you think it should issue some warning when using node to include something like cljsjs/node_externs when using node?

bensu14:10:58

or the docs are enough?

dnolen14:10:24

if you’re doing a custom build thing we assume you know you need to handle externs

dnolen14:10:30

this is not normal usage

bensu14:10:57

I'm just using (.exit js/process 1) in a normal program, and process.exit is not covered in the built in externs

bensu14:10:29

If you know what's going on, you can figure it out fairly fast, otherwise it takes a while simple_smile

dnolen14:10:51

well a couple things

dnolen14:10:44

1) this Node.js, advanced optimizations don’t matter much, 2) we’re never going to provide the complete Node.js externs file because we don’t have the time to maintain it and because of 1)

bensu14:10:29

I agree with both points, that's why I'm asking about warnings/docs. I'll see if there is a suitable place in the wiki to point Node users to cljsjs/node-externs

bensu14:10:39

(when using advanced)

martinklepsch14:10:14

@cvermilion: closure defines do not currently work with white space I think.

martinklepsch14:10:44

Whitespace skips the closure compiler and just concatenates files/removes whitespace. Please someone correct me if that's not correct.

martinklepsch14:10:32

And with whitespace there is no insertion of the defines as you already discovered.

dnolen15:10:56

@martinklepsch: yep, :whitespace is one of the weird modes, unless you’re writing something like a browser plugin best to avoid entirely.

arohner17:10:06

I have

(if (and (exists? js/KM) (exists? js/KM.i))
    (.i js/KM)
, but I’m still getting ReferenceError: 'KM' is undefined. What am I doing wrong?

thheller17:10:31

@arohner: :advanced or :none?

arohner17:10:48

I think my externs are correct

thheller17:10:50

do you have externs for KM?

arohner17:10:59

var KM = {};
KM.i = function () {};

thheller17:10:43

verified that the compiler is picking them up?

arohner18:10:30

kind of. I was getting name munging errors before I added the extern

arohner18:10:44

it was KM.o is not defined, and .o doesn’t exist

thheller18:10:32

km.js or wherever KM is coming from is included before the cljs.js?

arohner18:10:48

maybe. it’s 3rd party JS that may or may not be loaded

arohner18:10:59

I’m trying to do stuff iff km.js is loaded

thheller18:10:39

"(((typeof KM !== 'undefined') && (typeof KM.i !== 'undefined'))?KM.i();\n:)" is the generated code

thheller18:10:16

try (when (exists? js/KM) (when (exists? js/KM.i)) (js/KM.i))

thheller18:10:43

the && should prevent the second typeof from executing but who knows in js 😉

thheller18:10:02

oops misplaced a )

arohner18:10:26

huh. I’ll try that in a minute

dnolen18:10:15

@arohner: exists? is just JS typeof idiom, it does not work the way you believe it to work above

dnolen18:10:26

only the first one is valid

arohner18:10:40

first one?

dnolen18:10:48

the first exists?

thheller18:10:02

really can't check properties? didn't know that

dnolen18:10:13

it can but it will blow up if the first part is undefined

dnolen18:10:48

typeof is complected in the sense that it works implicitly against the global object

thheller18:10:23

yeah but the first typeof checks whether KM exists

thheller18:10:50

confusing .. but not surprised given we are working with JS

dnolen18:10:01

hrm, that’s true I would test this by writing some JS to observe the semantics

dnolen18:10:19

side thought, I’m not sure about the implications for “use strict”;

arohner18:10:29

hrm. something else is going on. This code behaves as I expected at the repl

thheller18:10:16

have you checked the optimized output?

thheller18:10:36

I would not be surprised if closure tries to optimize something in that statement

thheller18:10:37

:none seems to work just fine

arohner18:10:21

"undefined"!==typeof KM&&"undefined"!==typeof KM.i?KM.i()

dnolen18:10:45

operator precedence issue likely

dnolen18:10:17

(note missing parens)

arohner18:10:51

"undefined"!==typeof KM&&"undefined"!==typeof KM.i?KM.i():null
works in my Chrome console

dnolen18:10:54

I would try in a source file, not console to eliminate console variable

dnolen18:10:04

also I would check Safari & Firefox

thheller18:10:09

look at the optimized output first

thheller18:10:21

see if that is actually still the code

arohner18:10:38

arg. looks like a caching issue. the client loaded the previous, broken code, which was (exists? js/KM.i), with no (and (exists? js/KM)), and then I looked at the current .cljs source

arohner18:10:48

thanks for your help

dnolen18:10:12

@arohner: did you have breakpoints set?

dnolen18:10:51

huh, yeah there’s a feature in Chrome to disable caching when the console is open

dnolen18:10:09

however I’ve seen weird stuff if I have any breakpoints lying around (I always clear them out)

dnolen18:10:25

by clear out I mean “delete all breakpoints"

arohner18:10:25

the error was in production, and I got the stacktrace from our JS error reporter, and then looked at current .cljs

arohner18:10:32

so it was more a time skew thing

stopa18:10:42

Hey everyone, if you wanted to use the latest react-router, alongside reagent, how would you go about making the node modules play well with cljs? Would you a) use webpack to handle the node modules and expose the files via preamble to cljs b) use foreign-libs (am a bit hazy on how to do this well)

dnolen19:10:11

@stopachka: I would stick to a)

dnolen19:10:43

eventually we hope to make b) work but there a lot of little steps to be made first

stopa19:10:40

oky doke, will move onwards. Thanks : )

roberto20:10:49

has anyone used jwt with clojurescript? Did you use a pre-existing cljs library?

tyler20:10:56

@roberto are you just trying to parse a jwt or are you trying to generate one?

roberto20:10:26

the server is generating the token

tyler20:10:30

In the past I have just split by “.” and then used js/JSON.parse on the 2nd segment according to the spec here http://jwt.io/

tyler20:10:28

Which works as long as the payload is not encrypted. I don’t believe you can parse an encrypted token client side without exposing your secret key.

thheller20:10:51

is there encryption involed? isnt it just basically a signed base64 string?

tyler20:10:39

@thheller you are correct. Its just base64. I meant to say you cannot verify the token validity client side to my knowledge.

thheller20:10:02

there is a bunch of stuff in the closure library (ie. goog.crypt)

thheller20:10:28

has hmac and sha256 for example

thheller20:10:19

I believe that is all you'd need for jwt

thheller20:10:18

never tried a verify a JWT token with that but it might work

thheller20:10:21

but verifying a sercet JWT token in the browser seems questionable since you need to transmit the secret to the client

thheller20:10:30

which kinda defeats the point of a secret 😛

thheller20:10:22

but I know nothing about crypto so don't take my word for it

roberto20:10:28

Yep, it's what I was thinking. Need to do more research about jwt.

bensu20:10:12

@tyler I haven't used it but I think buddy: https://github.com/funcool/buddy/ has jwt

roberto21:10:27

I did that with friend on the server. Would still need to expose secret on the client with buddy.

mccraigmccraig21:10:27

@roberto jws/jwe seems to support asymmetric crypto for signature & encryption, but if your client is a browser then there's not much point in validating a token delivered by a server with code delivered from the same server and a public key also delivered from the same server... if you were validating a token from a different source than the code/pubkey then it may be useful

roberto21:10:11

That makes sense.

mccraigmccraig21:10:40

i use (buddy) jws for a client (browser) to store an auth token after login - the server signs the token with a symmetric key, and later validates the token given back to it by the client, unwrapping the clients user-id

mccraigmccraig21:10:01

the client doesn't really care what's inside the token in this case, it's just an opaque means of authing to the server

roberto22:10:13

Yeah, just starting to understand this.

cvermilion22:10:43

@martinklepsch and @dnolen — thanks for the helpful comments re :optimizations :whitespace and goog-define! It would be nice to document the issue, say, in the description of compiler options, since I could see this tripping someone up like it did me.

martinklepsch22:10:25

@cvermilion: do you know about the clojurescript wiki? It has a page on compiler options that everyone can modify/improve :)

cvermilion22:10:04

I did know about the wiki! I just wasn’t sure how welcome edits were. But happy to help where I can! I’ll take a look on Monday when I’m back at work. simple_smile

dnolen22:10:08

@cvermilion: edits are very welcome, the only thing that’s really off limits without asking first is the Quick Start

dnolen22:10:55

for the obvious reason that if someone edits that then it would ruin the experience for newcomers as edits these days are almost always wrong

richiardiandrea23:10:26

Hello everybody!

richiardiandrea23:10:48

I posted this question on #C03S1L9DN irc, sorry if I spam a little

richiardiandrea23:10:03

basically I would like to contribute a package on cljsjs

richiardiandrea23:10:21

it depends on jquery

richiardiandrea23:10:39

and the main constructor is

$.fn.jqconsole

richiardiandrea23:10:16

the problem is, I cannot get rid of

Uncaught ReferenceError: $ is not defined
in my minified (prod) build

richiardiandrea23:10:01

I even tried to import directly jquery in :foreign-libs, but it does not want to cooperate

richiardiandrea23:10:15

my package defines:

(deps-cljs :name     "cljsjs.jqconsole"
              :requires ["cljsjs.jquery"]) 

richiardiandrea23:10:26

I thought it would be enough