Fork me on GitHub
#clojurescript
<
2020-10-09
>
ozzloy01:10:57

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?

mrchance01:10:08

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

ozzloy01:10:46

thanks! i'll take a look

mrchance01:10:52

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.

mrchance01:10:38

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.

mrchance01:10:10

Does anyone have an insight to help me?

Shantanu Kumar01:10:09

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

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

Shantanu Kumar19:10:33

Bumping-up: Can anybody comment on this?

mrchance02:10:17

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?

victorb12:10:48

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

mrchance12:10:45

Thanks for the answer @UEJ5FMR6K, 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

victorb14:10:04

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

mrchance02:10:43

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

victorb08:10:07

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.

mrchance16:10:30

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:

victorb16:10:16

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

Nico12:10:08

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.

manutter5113:10:43

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

manutter5113:10:17

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

Nico13:10:35

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

Michael Rispoli13:10:01

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 Rispoli13:10:57

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

manutter5113:10:17

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.

manutter5113:10:38

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

manutter5113:10:31

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

Nico13:10:47

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 Rispoli13:10:41

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?

manutter5113:10:44

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

manutter5113:10:45

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

Michael Rispoli13:10:16

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

Nico13:10:38

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)

athomasoriginal12:10:13

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

athomasoriginal12:10:51

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 Bobby14:10:02

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

victorb14:10:43

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

👍 9
Michael Rispoli14:10:55

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

Michael Rispoli14:10:09

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

victorb14:10:56

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)

victorb14:10:49

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

Michael Rispoli14:10:19

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

Michael Rispoli15:10:20

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

Michael Rispoli15:10:43

Definitely not static sites though

victorb15:10:50

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 Rispoli15:10:51

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

victorb15:10:33

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 Rispoli15:10:44

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 Rispoli15:10:57

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

Michael Rispoli15:10:20

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 Rispoli15:10:41

I guess you just have to support separate output directories

Michael Rispoli15:10:53

maybe with this :modules section it can do the same

victorb15:10:32

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 Rispoli15:10:31

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

Michael Rispoli15:10:55

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 Rispoli15:10:54

and then maybe express + figwheel to serve it all

victorb15:10:02

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 Rispoli15:10:28

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

Michael Rispoli15:10:56

definitely a bit simpler to see the tying together of everything

victorb15:10:10

yeah, great docs too :thumbsup:

Michael Rispoli15:10:45

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

Day Bobby14:10:20

thats good to know, thank you very much!

zilti15:10:42

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

Michael Rispoli16:10:50

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 Rispoli16:10:36

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.

zilti19:10:38

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

Michael Rispoli20:10:40

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.

zilti21:10:52

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 🙂

Michael Rispoli01:10:31

Oh the htmx is very cool. I think in my ideal world I was thinking something like this is a cool alternative. Reminds me of maybe like Phoenix live view or the old ruby unobtrusive js style.

leif19:10:05

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?

leif19:10:59

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.

leif19:10:30

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

mruzekw20:10:33

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?

p-himik21:10:34

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.

victorb08:10:51

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 McCormick08:10:03

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.

victorb09:10:48

"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