Fork me on GitHub
#re-frame
<
2020-04-02
>
victorb11:04:20

not sure what you're familiar with since before, but shadow-cljs is basically a replacement for figwheel/fighweel-main and their alike. https://github.com/thheller/shadow-cljs

victorb11:04:52

the examples are just there to show how you can use re-frame, that particular example is using shadow-cljs as its build tool

Michaël Salihi13:04:14

Sorry, my question was not precise enough. Since few months, I'm familiar with Shadow-CLJS, Re-frame, CLJS and Clojure. However, when I browsing the Re-frame example I notice this deps.cljs file which contains this map: {:npm-dev-deps {"shadow-cljs" "2.8.83"}} What is this :npm-dev-deps keyword ? For which usage ?

victorb13:04:27

yeah, I think that one is just there to get the handy cli of shadow-cljs going (as in, the package is the npm package shadow-cljs, not the clojure library that is also called shadow-cljs). Think this is mentioned in the docs of shadow-cljs somewhere

victorb13:04:43

so the example you linked are using both the clojure library and the npm package. :npm-dev-deps is for installing the npm package, project.clj has the clojure library. Hope that answers your question!

Michaël Salihi13:04:42

OK, thank you. What surprises me is that it seems to be used only for the Re-frame project. https://www.google.com/search?q=deps.cljs%20%22%3Anpm-dev-deps%22 Nothing is the Shadow-CLJS users guide. @thheller Any clue ?

👍 4
victorb13:04:26

@UFBL6R4P3 is not what's mentioned here? https://shadow-cljs.github.io/docs/UsersGuide.html#publish-deps-cljs Think your search is missing bunch of results because of the npm-dev-deps vs npm-deps which are essentially the same but slightly different (and comes from npm https://docs.npmjs.com/files/package.json#dependencies)

Michaël Salihi13:04:10

> Think your search is missing bunch of results because of the npm-dev-deps That why I had not found the doc, thank you very much 😉

thheller13:04:25

no clue what :npm-dev-deps is. it is not something supported or used by shadow-cljs

thheller13:04:33

I guess its something related to lein-shadow?

Michaël Salihi11:04:10

@thheller OK, That's what I thought. Thank I think @superstructor will be able to enlighten us. :)

p-himik11:04:58

@UFBL6R4P3 No need to send every thread message to the main channel.

Michaël Salihi16:04:20

@p-himik Yeah got it, I didn't expect that pollute the channel like that.

👍 4
superstructor09:04:16

Correct it is something supported by lein-shadow for declaring package.json devDependencies in the deps.edn file. @UFBL6R4P3 @thheller

👏 4
Michaël Salihi09:04:42

Perfect, thank you for these details!

martinklepsch10:04:41

In my app there is a kind of effect that has to be triggered whenever certain parts of the application state change. I think of this as “app-state reactivity”. If this problem statement is understandable I’d be very curious to hear more about how people deal with this in re-frame land 🙂

p-himik10:04:58

If I understand you correctly, that's exactly why https://github.com/day8/re-frame/issues/570 was created.

victorb11:04:31

well, usually I have the event trigger more events by using reg-event-fx in that case, then make sure to trigger that event in the handler I want to trigger the other event (if I understand correctly)

p-himik11:04:35

That won't work if the data change can be external. It also doesn't scale well with code and team sizes.

victorb11:04:49

it's true that won't work when the app-db changes from outside of re-frame. But I don't think the link you put above would solve that either, as it's still within the world of re-frame. Half-way towards global interceptors is just creating a normal interceptor and using that, it's outlined here: https://github.com/day8/re-frame/blob/master/examples/todomvc/src/todomvc/events.cljs

victorb11:04:44

regarding if the data changes from outside the app-db, what I've done in the past with websocket messages is that you have one handler that dispatches other events depending on the message, then in that handler you can either add your interceptor or more dispatches. Depends on where the external data comes from I guess and how/why the app-db changes

victorb11:04:18

^ obviously won't be performant if you're having tons of messages in a short timeframe, but works well for small-size collaboration apps for example

p-himik11:04:39

I didn't mean direct DB changes, because when that happens, all bets are off WRT re-frame. I mean dispatching events that change your DB but that don't come from your app. > Half-way towards global interceptors is just creating a normal interceptor and using that Impossible to integrate with third-party code that directly uses re-frame.core/reg-event-* functions.

victorb12:04:54

yeah, thanks for adding that. Just trying to spit out different solutions, in the end it just depends so much on the context

lilactown14:04:45

I would just create a subscription and use reagent.core/track! or some other way of watching and doing the side effect on dB change

lilactown14:04:20

This is assuming that the side effect in question isn’t going to produce more db changes...

lilactown14:04:31

I dunno. The unidirectional flow of events -> fx -> subs -> ui is not always so unidirectional

p-himik14:04:07

Well, the point of that issue is exactly to prevent the need to track! in the first place. :) Again, unless someone decides to change app-db directly, which would circumvent that mechanism. In that case, the flow still stays unidirectional, at least in the context of a single even loop iteration, or whatever it's called.

lilactown15:04:41

it seems like a sort of indirect way of doing what subs already do

lilactown15:04:57

I guess I would ask, why is updating the DOM a special effect? why can’t other effects listen to the data flowing from the app-db, similar to the way the DOM does?

lilactown15:04:12

not saying it’s wrong, but I question myself on this kind of wisdom a lot. my mental model sort of breaks down when I start to think about effects that depend on app-db, or rendering the UI which triggers events or side effects

p-himik15:04:05

Alas, I don't have an answer. Maybe @U051MTYAB does.

Michaël Salihi13:04:14

Sorry, my question was not precise enough. Since few months, I'm familiar with Shadow-CLJS, Re-frame, CLJS and Clojure. However, when I browsing the Re-frame example I notice this deps.cljs file which contains this map: {:npm-dev-deps {"shadow-cljs" "2.8.83"}} What is this :npm-dev-deps keyword ? For which usage ?

Michaël Salihi13:04:42

OK, thank you. What surprises me is that it seems to be used only for the Re-frame project. https://www.google.com/search?q=deps.cljs%20%22%3Anpm-dev-deps%22 Nothing is the Shadow-CLJS users guide. @thheller Any clue ?

👍 4
hindol14:04:17

Hi, with reg-sub, working with deeply nested values in app-db is painless since I can piggyback on other subs with :<-. Is there a similar mechanism for updating app-db with reg-event-*?

manutter5114:04:37

The trick I use is to define a field-path function at the top of each namespace, so all the reg-event-* stuff can just (update-in db (field-path :foo) value). Of course, that only works if you divide up your namespaces by component instead of putting everything in a giant events.cljs file. But I suppose you could define a foo-path and a bar-path and so on.

hindol14:04:05

So, (field-path :foo) returns [:path :to :foo]?

manutter5114:04:47

right. And as an added bonus, if I ever need to change :path :to, I only have to change it in that one place, and all my event handlers are updated instantly.

hindol14:04:50

But I will need to change the path in subs. Is there a way to share paths between subs and handlers?

p-himik14:04:28

Just share the def (or defn) then, that's it.

manutter5114:04:54

Not that I know of. I’ve never actually needed to change :path :to, tbh, so I’ve never really worried about it.

p-himik14:04:59

Just in case - there's also path interceptor built into re-frame. Doesn't really solve your problem but makes it a bit more easier for some events.

p-himik14:04:31

Oh, I misunderstood, I think. @hindol.adhya What do you mean by "change the path in subs"?

cldwalker14:04:47

Mornin. Does anyone of a drop-in library for visualizing the dependency graph of subscriptions? I've found https://gist.github.com/rgm/1b44f546c9ff7cccaeddb7b73d4a4291 but it's not drop-in and requires changing a fair amount of code

hindol14:04:30

@p-himik If I change app-db, both the subs which get data and event handlers which update data need to change.

p-himik14:04:38

You mean you need to do that because of some business logic?

p-himik14:04:01

Or do you think that re-frame requires you to do so, regardless of your business logic?

hindol14:04:09

It's nothing serious like that, just a hobby project I am doing on my own.

hindol14:04:37

So, haven't really thought through the schema initially, now I need to change parts of it.

p-himik14:04:08

So it's a development time change of the subs and events, and not a runtime change?

p-himik14:04:40

OK, then just follow what manutter51 and I said before - create a common def with the required path and use that def both in subs and event handlers.

hindol14:04:17

The def will have the complete path but the subs are organized as a tree. Anyway, it's a small thing really. Wanted to see if there is a trick I am missing.

hindol14:04:13

But the path interceptor looks really nice!

p-himik14:04:45

If you organize subs in a tree that just follows a number of paths, may just have def-s for those paths and create subs by iterating over those def-s?

hindol14:04:54

That seems too much work. On the other hand, path seems to simplify event handlers quite a bit. Thank you for that!

p-himik15:04:18

> That seems too much work That's a code that you would write once, and it's not that complicated if you stick to the same naming convention. Right now, you create each sub manually - and O(n) doesn't scale as well as O(1). ;)

hindol15:04:20

Oh, I misunderstood what you said there. You mean, generate the reg-sub itself?

p-himik15:04:49

Yep. (doseq [p path] (reg-sub (keyword "hello" p) ...)), stuff like that.

p-himik15:04:04

Would be a bit more complicated because of :<-, of course.

hindol15:04:55

Never thought about that. Do you have some example codes lying somewhere?

p-himik15:04:38

Nah, nothing readily available apart form that simple doseq. It would also depend on the way you name your subs. But I imagine the overall algorithm would stay the same.