clojurescript

ClojureScript, a dialect of Clojure that compiles to JavaScript http://clojurescript.org | Currently at 1.10.879
ozzloy 2020-10-09T01:05:57.335500Z

i'm creating a bingo game and it currently serves an isolated game to each visitor. i would like to sync the games. i'm looking at sente, but not getting it working. anyone have a good sente tutorial link, or suggestion of some other lib for the job?

2020-10-09T01:09:52.339600Z

Hi, I have a weird issue with recording a video... I'm following https://developers.google.com/web/fundamentals/media/recording-video , so I conj into a vector chunks all (.-data %) of ondataavailable events, then in the end do (-> chunks (js/Blob.) (.createObjectURL js/URL) . I set that as the URL of a video element, but it behaves strangely: When I first play the video, I get a video which stops visually at the end of the first clip, and also just displays the total length of it, but continues to play the audio. When I hit play afterwards, it plays the last chunk with matching audio. When I download it, it just contains the first clip. When the camera recording stream is still open, I get a live video feed instead of the recorded video. I have absolutely no idea how that can possibly happen.

2020-10-09T01:10:10.340300Z

Does anyone have an insight to help me?

Shantanu Kumar 2020-10-09T01:11:09.341Z

Can anybody tell why this expression throws NullPointerException when macroexpanding in CLJS 1.10.758 (but works fine in CLJ)?

(case ()
  ()   1
  (()) 2)

2020-10-09T01:13:08.341100Z

https://github.com/weavejester/haslett looks simple enough, but I also found using the websocket API directly quite straightforward.

ozzloy 2020-10-09T01:19:46.341500Z

thanks! i'll take a look

2020-10-09T01:48:38.342Z

I got it, I tried to concatenate chunks from different recordings, but that doesn't work. You can only concatenate pieces from the same recording (which where created by requestData calls or the recording ending) Replacing the recording with the video stream seems like a different issue, maybe the blob isn't ready or something like that.

2020-10-09T02:01:17.344500Z

Ok, new question, I have a video element with src set to the result of the above. When the page renders, that element doesn't display correctly, either showing the live video feed or nothing if the feed is closed, but if I add say an extra empty line to my code and let shadow-cljs reload it, it does. What could cause that?

victorb 2020-10-09T12:00:48.345200Z

My hunch would be something around state updates not propagating properly somewhere, are you using reagent together with reagent/atom?

2020-10-09T12:54:45.347700Z

Thanks for the answer @victorbjelkholm429, I suspect the same... I'm using re-frame. Upon inspection with dev tools the URL is set correctly though, so I'm not sure what else might influence it

victorb 2020-10-09T14:23:04.359300Z

You have some sample code? Try reproduce it in a smaller version and post it here, easier to guess what could have gone wrong then

2020-10-12T02:46:43.397400Z

I got it to work, providing an explicit key depending on the src url fixed it, still not sure why it didn't work without one

victorb 2020-10-12T08:36:07.400600Z

Seems like maybe you're changing the src after it already been rendered (hitting this: https://html.spec.whatwg.org/multipage/embedded-content.html#the-source-element "Dynamically modifying a `source` element and its attribute when the element is already inserted in a `video` or `audio` element will have no effect."), while if you add the :key to it, it rerenders the entire element and reinserts it with the new src set, rendering properly.

2020-10-12T16:15:30.409400Z

I thought so, but another SO issue claimed that setting the src element directly, without an embedded <source> element should fix it. I am however replacing another video element with a srcObject and no src, maybe it doesn't rerender that correctly otherwise? :thinking_face:

victorb 2020-10-12T16:18:16.409600Z

Hm, yeah, setting src on video should update correctly indeed. Strange huh

Nico 2020-10-09T12:39:08.347600Z

hello! I'd like to learn cljs as somebody who knows clojure but knows almost nothing about web development (I know HTML and have made a few toys with jquery years ago, but basically know nothing), where should I start? All the resources I can find are for people who already know web dev and don't know clojure rather than the other way around.I don't really want to learn a framework.

2020-10-09T13:17:43.350300Z

You might want to start with figwheel so you can get a CLJS REPL up and running and then hack at a few things to get familiar

2020-10-09T13:27:17.350900Z

If you take that route there’s a #figwheel-main channel you can ping for help, etc. https://figwheel.org/

Nico 2020-10-09T13:31:35.351400Z

the main thing I'm not sure about is how to actually affect the web page (which I suppose is DOM stuff?)

2020-10-09T13:39:17.352200Z

Yeah, your options there are going to be to either use something like Reagent or re-frame, or else do the low-level JS stuff by hand.

Michael Rispoli 2020-10-09T13:40:01.352600Z

Been going through the same thing myself, I just started with figwheel and did some basic DOM querying stuff, which was ok but I'm sorta finding that your really want to leverage reagent because the "older" way of setting even listeners on elements, etc is annoying in javascript and I found really clunky via cljs, I think cljs really shines with the reagent ecosystem

Michael Rispoli 2020-10-09T13:40:57.352900Z

I was more going through the dom query stuff for my own knowledge and understanding but its a bit difficult for sure because there are some tricks to the interop

2020-10-09T13:41:38.353600Z

I prefer re-frame to Reagent, but Reagent is easier to start with.

2020-10-09T13:42:31.354300Z

Also if you just look at something like hiccup to render static HTML, that’s an even simpler foundation to build on

Nico 2020-10-09T13:43:47.354900Z

I feel liike reagent is too big for what i want to do (which is mostly just small experiments) but I'm not sure how big it actually is

Michael Rispoli 2020-10-09T13:44:41.356100Z

Do you have any recommendations for server side rendered reframe apps, I'm sorta looking for a next.js replacement in cljs. I'm seeing some templates for figwheel that kindof get there but wasn't sure if there was something similar out there?

2020-10-09T13:44:44.356200Z

Well, the range that Reagent covers is pretty broad, but there’s simple stuff you can do.

2020-10-09T13:45:32.356600Z

@nihilazo ^

2020-10-09T13:45:45.356900Z

I haven’t done much server-side rendering myself.

Michael Rispoli 2020-10-09T13:47:16.358600Z

Yea the SSR thing is likely the requirement for most of the things I work on so was wondering how people do that and also have some light api routes in the same codebase without splitting things into a frontend and a backend service... more best practices because I see there's a few ways people are doing it

Nico 2020-10-09T13:47:38.358800Z

I think I'll check out reagent, it seems to be the way most people go. And just mess around in figwheel and figure stuff out (the best way to learn)

athomasoriginal 2020-10-14T12:27:13.450700Z

@nihilazo If you want some examples of DOM only projects in CLJS there is this repo: https://github.com/athomasoriginal/clojurescript-30

athomasoriginal 2020-10-14T12:28:51.451100Z

There is also this playlist https://www.youtube.com/watch?v=P60dMljS-OM&amp;list=PLaGDS2KB3-ArG0WqAytE9GsZgrM-USsZA if your looking for info on setting up a CLJS project from scratch. Maybe not as useful given your Clojure background.

Day Bobby 2020-10-09T14:25:02.359900Z

please forgive my ignorance, is reagent SPA only or SSR support is on roadmap?

victorb 2020-10-09T14:26:43.360500Z

Should be possible to do server-side rendering with Reagent, it's part of the API. One thread about it: https://clojureverse.org/t/cljs-server-side-rendering-with-reagent/3995, unfortunately it seems like reagent.dom.server is cljs only, not cljc, so no calling with clojure

👍 3
Day Bobby 2020-10-09T14:28:20.361Z

thats good to know, thank you very much!

Michael Rispoli 2020-10-09T14:48:55.361300Z

Looks like fetching too much data server side could impact performance as well this way

Michael Rispoli 2020-10-09T14:51:09.361500Z

This may be a little naive since I'm a bit new but I wonder if anyone has tried an approach similar to ReasonML where you just compile the js files alongside the cljs files in a framework like next.js and just leverage that ecosystem for the actual web framework parts

victorb 2020-10-09T14:57:56.361700Z

Yeah, fetching too much data will impact performance anywhere 🙂 If you're just looking for generating HTML ala static websites, go for hiccup and save the results to disk. And if you want to use next.js, you just go ahead and use it, as cljs ultimately become JS and you can interop with anything that can run JS (for most parts)

victorb 2020-10-09T14:58:49.361900Z

Mostly, I'm trying to understand what you're looking for here

Michael Rispoli 2020-10-09T14:59:19.362100Z

Yea what I'm looking for is the framework of next.js but instead of typescript having the clojurescript environment

Michael Rispoli 2020-10-09T15:00:20.362300Z

getting the advantages cljs but also having the advantages next.js put into its build system and way of structuring the application

Michael Rispoli 2020-10-09T15:00:43.362500Z

Definitely not static sites though

victorb 2020-10-09T15:00:50.362700Z

maybe check this out? https://github.com/thheller/next-cljs Haven't tried it myself, might not work as it's 2 years old and some things in shadow-cljs might have changed (ask in #shadow-cljs if you can't figure out what's going on/wrong)

Michael Rispoli 2020-10-09T15:01:51.363Z

Ah interesting I'll take a look, definitely a little dated but maybe can re-purpose the methods they use

victorb 2020-10-09T15:03:33.363200Z

in general it shouldn't be overly difficult interfacing with anything you're familiar with from JS, might requiring some tweaking and will also depend on the tooling you're using

Michael Rispoli 2020-10-09T15:07:44.363400Z

Yea the ReasonML integration wth next is just a standard next codebase and but with .re files that compile to js output right in the same directories... next then just ignores the file types it doesn't understand

Michael Rispoli 2020-10-09T15:07:57.363600Z

the downside to this being that it uses reason and not clojurescript lol

Michael Rispoli 2020-10-09T15:08:20.363800Z

but the concept would be the same I just have to dig into how that would work with the repl and tooling I have since I'm still new to cljs

Michael Rispoli 2020-10-09T15:09:41.364Z

I guess you just have to support separate output directories

Michael Rispoli 2020-10-09T15:10:53.364200Z

maybe with this :modules section it can do the same

victorb 2020-10-09T15:11:32.364400Z

yeah, I guess no one has worked seriously on something cljs+next.js because there doesn't seem to be a ton of benefits if compared to just using hiccup+reagent directly in cljs, or rendering hiccup with clj

Michael Rispoli 2020-10-09T15:12:31.364600Z

Oh, I probably have to dig into hiccup I haven't seen that part of the ecosystem yet

Michael Rispoli 2020-10-09T15:13:55.364800Z

Just getting familiar with some of the tooling probably will help me get to where I need to be but really I think I want to use re-frame + server side rendering + api routes if needed to interact with a remote database and perform some basic server side stuff

Michael Rispoli 2020-10-09T15:15:54.365Z

and then maybe express + figwheel to serve it all

victorb 2020-10-09T15:17:02.365200Z

if you're just getting into cljs, start with just shadow-cljs + reagent for starters, before jumping into lots of other things. I think you'll find that you generally need less stuff when building stuff with Clojure

Michael Rispoli 2020-10-09T15:18:28.365400Z

ahh shadow-cljs does seem to be more what I'm looking for

Michael Rispoli 2020-10-09T15:18:56.365600Z

definitely a bit simpler to see the tying together of everything

victorb 2020-10-09T15:19:10.365800Z

yeah, great docs too :thumbsup:

Michael Rispoli 2020-10-09T15:19:45.366Z

yea i was getting really confused by the figwheel docs though I enjoyed the actual dev environment

zilti 2020-10-09T15:41:42.366700Z

What's the usecase of using an SPA library to render a static page server-side?

Michael Rispoli 2020-10-09T16:07:50.368400Z

If you had a bunch of pages that required data from say a headless CMS of some kind or user data from the database. Basically all public facing websites need to be server side rendered to index with search engines. In the case of things that are password protected we've found server side rendering will give users a much faster time to first paint rather than pulling down an empty html doc, then fetching data, then rendering it as with a classic client side rendered spa. So really its for rendering dynamic pages, I rarely use static site builders because in general users tend to want to be able to preview their data and for really large sites always building static files is a drag. The other side of this is why next.js? The parts of next.js that I like are you can have SSR, static generation, or client side generation all living in the same codebase based upon need. The other is some of their frontend optimizations like link components pre-fetching views for you as users scroll give a very snappy performance client side. In general, next has a really great ecosystem when it comes to the output it generates for the end user. They also have the optional /api directory should you need a few backend routes for your app. Ultimately I don't really care if the end solution is next.js but was looking for something that provided those options on the CLJS side of things since that ultimately is what the hang up would be for using it on a production project for me.

Michael Rispoli 2020-10-09T16:11:36.368600Z

If I could combine the framework and the language it would really give me some large productivity gains I think. It's likely that shadow-cljs and reagent can get me somewhere close, but I think I'm still too green to be able to put something out in production so I was hoping to shortcut that process but piping it into a framework I already knew well. For instance ReasonML has a nextjs interop example that makes sense and I was thinking of trying to replicate it for that purpose with cljs.

2020-10-09T19:22:05.371600Z

Hello all, I'm trying to follow @dnolen's webpack tutorial (https://clojurescript.org/guides/webpack), but when I run clj -m cljs.main -co build.edn -v -c -r I get the following error:

leif@FEM ~/test/hello-bundler (main*) $ clj -m cljs.main -co build.edn -v -c -r 
Options passed to ClojureScript compiler: {:infer-externs true, :output-dir "out", :closure-warnings {:check-types :off, :check-variables :off}, :closure-defines {"cljs.core._STAR_global_STAR_" "window", "cljs.core._STAR_target_STAR_" "bundle"}, :ups-libs nil, :cache-analysis true, :closure-module-roots [], :optimizations :none, :ups-foreign-libs [], :verbose true, :aot-cache true, :preloads [process.env clojure.browser.repl.preload], :ignore-js-module-exts [".css"], :output-to "out/index.js", :nodejs-rt false, :preamble ["cljs/imul.js"], :bundle-cmd {:none ["npx" "webpack" "out/index.js" "-o" "out/main.js" "--mode=development"], :default ["npx" "webpack" "out/index.js" "-o" "out/main.js"]}, :browser-repl true, :ups-externs nil, :opts-cache "cljsc_opts.edn", :hashbang false, :source-map true, :cache-analysis-format :transit, :target :nodejs, :main hello-bundler.core, :language-in :es6, :emit-constants nil, :npm-deps true}
Copying cached /home/leif/.cljs/.aot_cache/1.10.741/130A86D/cljs/core.js to out/cljs/core.js
Reading analysis cache for jar:file:/home/leif/.m2/repository/org/clojure/clojurescript/1.10.741/clojurescript-1.10.741.jar!/cljs/core.cljs
Compiling /home/leif/test/hello-bundler/src/hello_bundler/core.cljs to out/hello_bundler/core.js
Unexpected error (ExceptionInfo) compiling at (REPL:1).
No such namespace: react, could not locate react.cljs, react.cljc, or JavaScript source providing "react" in file /home/leif/test/hello-bundler/src/hello_bundler/core.cljs

Full report at:
/tmp/clojure-10901845457455491784.edn
Which seems to indicate that its not using :bundle, but is actually running :target :nodejs . Any thoughts on why this might be?

2020-10-09T19:22:59.372500Z

Also for reference, I've put the code I have here: https://github.com/LeifAndersen/hello-bundle, but it is should be the same as the tutorial.

2020-10-09T19:37:30.373200Z

Wow, I feel silly, I had forgotten to make sure react was installed. https://twitter.com/_uosl/status/1314650404978855941 Thanks. 🙂

zilti 2020-10-09T19:39:38.373400Z

I mean, Fulcro can do SSR, but really, if I want to do SSR the last thing I'd use is a client-side library... That's like using a parachute to climb up a mountain

mruzekw 2020-10-09T20:03:33.375Z

Hi all, I absolutely love what defonce + figwheel/shadow-cljs provides, though I work in JS (React/Apollo/Redux) for my daily work at the moment. Does anyone know of a defonce equivalent for JS apps?

victorb 2020-10-10T08:34:51.386100Z

in JS community (React at least) it's called Hot Code Reload or something like that, where only components that have changed will be updated and newly renderer. You could implement defonce by leveraging state/props in your component hierarchy, so you have a data fetcher component that wraps the component needing the data, and only when you actually change the data fetcher would it reload it's data, if you change the stateless component within, it won't reload the data fetcher

Chris McCormick 2020-10-12T08:55:03.400800Z

one gotcha i've run into with reloading js code is the const keyword is not reload friendly as it will throw an error if you try to rebind something with the same name.

victorb 2020-10-12T09:55:48.407600Z

"reloading JS code" is not really the same as "reloading CLJS code", at least in the React Hot Code Reload world, as it's not all code that gets reloaded, either the component itself gets reloaded and reinserted or the entire file gets reevaluated, while in clojure land it's just updating vars with new forms, regardless

Chris McCormick 2020-10-12T11:20:47.408700Z

true

Michael Rispoli 2020-10-09T20:55:40.375700Z

Well if you have a lot of client side framework needs its very powerful. Otherwise you have to do vanilla dom OR SSR but google really makes the decision for you saying it msut be SSR. What you want is the client side frameowrk to take over after that point for a better frontend experience.

p-himik 2020-10-09T21:41:34.375900Z

I guess it depends on how JS code reload is implemented. So far, I've only seen full page reloads. But if it's in any way close to what figwheel/shadow-cljs do, then you should be able to implement defonce yourself in JS - its implementation is rather simple and in raw JS it should be even simpler, I think.

zilti 2020-10-09T21:44:52.376100Z

Yea if it is a website, so, something containing searchable and Google-indexable info, https://htmx.org/ is my go-to way of doing things. And when writing an SPA, I go with Fulcro, but then I don't use the SSR since due to it being an application there's nothing of value for Google 🙂