Fork me on GitHub
#fulcro
<
2020-06-08
>
lsenjov14:06:15

Is there a way to apply a mutation on the frontend, but specifically not sending to the remote for this request? I'm playing with websockets and synchronizing state front and back. I'm sending a mutation from one client, and sending that mutation to each other client on the frontend. I'm just not sure how to do this nicely without declaring mutations twice

Björn Ebbinghaus15:06:54

I am not sure if I understand you correctly. You want a switch, to toggle if a mutation goes remote or not?

Björn Ebbinghaus15:06:31

The mutation is only going remote if the body of remote (or any other remote with a different name) returns a truthy value. So you could write:

clojure
(defmutation my-mutation [:keys {remote?}]
  (action [env] …your client stuff…)
   (remote [env] remote?))

Björn Ebbinghaus15:06:47

Forgot, that Slack still can’t to highlighting

lsenjov22:06:01

Ah neat, thanks!

lsenjov15:06:12

Ended up writing a macro to do it for me

dvingo17:06:20

anyone tried setting up fulcro 3 with devcards? I've got some basic version rendering, mostly copying the workspaces code for fulcro3 cards

tony.kay17:06:55

@danvingo I’ve moved to workspaces. There is a workspaces I’ve ported forward to 3…https://github.com/awkay/workspaces

tony.kay17:06:22

the regular one also works, but it is still written in F2, so you end up with both on classpath

dvingo17:06:17

workspaces is working for me, I wanted to try out devcards also, and just generally if other people want to use it, it's good to have options

tony.kay17:06:34

sure…yep, that’s basically what’s needed.

dvingo17:06:40

cool, thanks

zilti17:06:16

I just recently used the workspaces cards, and made a custom one to add toolbar buttons to individual Fulcro 3 cards: https://dev.to/zilti/adding-custom-toolbar-buttons-to-fulcro-3-workspaces-cards-4306

mruzekw21:06:07

So I've been following Tony's latest videos, and I noticed the one use fulcro inside of a re-frame app. And that made me wonder, what is the argument for using fulcro vs. re-frame on the rendering side? Are there any other advantages assuming reframe with a fulcro db/network pipeline?

currentoor22:06:26

the best person to ask would probably be @U5P29DSUS, i believe he has a lot of re-frame experience

currentoor22:06:55

@U066U8JQJ is a fulcro expert and i think he's using re-frame at his new day job now?

JAtkins22:06:32

I wouldn't consider myself an expert in either. However, I did choose fulcro over re-frame for my current application. I'm actually debating your question myself. I have parts of my application that are well suited to the subscription model, so I ended up building a mini implementation of re-frame within fulcro. I still like the general model of fulcro much better - being able to see the data straight in the db without having to use tooling to see the values of the subscriptions is a huge help. If Tony has a chance, he probably has a more thorough answer since we have discussed this a bit in the last week.

JAtkins22:06:45

(I don't know if this is what you are saying, but I also find that a normalized db is far simpler to mutate against. I use the subscription side of re-frame only)

tony.kay22:06:44

I think you mean normalized

JAtkins22:06:54

.... words. they are hard.

mruzekw22:06:32

Sure, and that's sort of where the question arose. If I'm using fulcro for a normalized db within a reframe app, what's the further argument for fulcro? I vaguely remember mentionings of rendering optimizations with the co-located queries in the days of om.next. But I didn't know if there were any more I should be aware of. I will say I like the idea of a set way for derived data, but that seems to have already been addressed lately with the subscriptions-render example

tony.kay22:06:38

At the end of the day React does the heavy render lifting for both. When Fulcro is in charge of rendering it is a pluggable algorithm that need not even be tied to React. Fulcro’s rendering is essentially triggered by tx processing, also a pluggable algorithm. Thus the video where I can use Reframe to do the rendering…Fulcro doesn’t really care and isn’t tied to it very tightly. If you’re doing web only, like Reframe’s derived value model, and want to mix them, give it a shot. I’ve not tried it in any larger program, so I have no idea how good it would actually be. Personally, I’d rather see a derived data system as a plugin to Fulcro itself.

tony.kay22:06:03

which is why I made those other videos…hoping to inspire library authors to contribute something: I’ve left all the hooks and demos of how to use them 😉

tony.kay23:06:04

There are all sorts of possiblities, and I’m open to creating more hook points if library authors see a spot I’ve not made accessible enough.

mruzekw23:06:10

Sure, and would love to contribute to that. In the videos, you suggested going the hooks/subscription route, right?

tony.kay23:06:54

Yes, @U5P29DSUS and I were talking about that, which is what inspired the videos. I wanted to show him the options, but figured others might be interested

tony.kay23:06:29

so, the React hooks route is tied to react, but when tied to render could be the cleanest end result, I think

mruzekw23:06:31

Gotcha, is your implementation based on the hooks example @U5P29DSUS?

tony.kay23:06:13

It’s also a nicer solution, in many ways, over the floating roots stuff I added recently.

tony.kay23:06:58

The main downside is that some features of other nses use the query composition (i.e. dynamic routers use it to find nested routers)….but if used only at the “leaves” of the UI graph, it could be quite nice.

JAtkins23:06:07

No, I wrote it in a weird way. I haven't used hooks before, and I didn't know that I could use the internal fulcro indicies for optimization. I'm planning on writing a hooks based system in the short term for my own needs. I'll be publishing it as a library if someone wants it.

tony.kay23:06:07

Perhaps you should both do quick-n-dirty prototypes that show the basic outline, and perhaps we can all meet up and discuss pros/cons after a bit of experimenting?

mruzekw23:06:15

Cool! Yeah, I'd be interested in that

JAtkins23:06:44

Yup. Sounds cool. Actually, I think you wrote 80% of it for the video....

tony.kay23:06:40

well, I would be interested in seeing what your thoughts are on how to actually deal with data dependencies in ways that are nicely visible during development. You know I prefer navigable code to event systems…but whatever works. a bit of R&D will help shed some light

mruzekw23:06:47

Would rendering a signal graph in devtools do it? I know it's not navigable code like functions are, but it does give visibility

mruzekw23:06:13

I'm not even sure if that's what you're actually doing @U5P29DSUS

JAtkins23:06:57

It kind of is. I have a really really shallow graph, so I kind of know where everything goes.

tony.kay23:06:59

I don’t want to limit options. I use events in UISM. I’m just encouraging you to think about scalable solutions on large projects.

tony.kay23:06:53

i.e. do we really need subs that can consume subs, or is just composing functions the calculate the result acceptable?

tony.kay23:06:57

what are the MUST have vs nice to have vs. features that sound good but actually create incidental complexity that outweighs the benefit.

mruzekw23:06:06

Sure. I was thinking about re-select which as a "lazy" graph of nodes. One node doesn't update until what it depends on does.

mruzekw23:06:12

A way to reduce computation

mruzekw23:06:44

But I think that's done all through memoized functions?

tony.kay23:06:48

right, but that’s an optimization…is it opt-in, or do I have to buy that complexity to do anything?

tony.kay23:06:00

it also introduces caching: a huge source of bugs

tony.kay23:06:19

remember that you have a superpower: normalized data. Doing a diff on that is trivial, esp when you know what idents you’re “listening to”

tony.kay23:06:51

moving that into “hidden” places like atoms with watches makes it harder to see, and requires you invent addl ways to optimize

mruzekw23:06:14

Makes sense

mruzekw23:06:35

The subscriptions hook example doesn't place anything in the db, right?

tony.kay23:06:39

consider ideas like reifiying the signal graph into the acutal db…then a dependency is as simple as a ident + optional field

mruzekw23:06:44

It just querys?

tony.kay23:06:57

don’t remember…you watched it more recently than me 😜

mruzekw23:06:14

I can play with the example to be sure

JAtkins23:06:04

I think it's possible to just use composition.

; given functions of the form

(defn step-fn [{:keys [whatever you need] :as fat-map}]
  (assoc fat-map :step-fn-result ...))

(defn step-fn2 [{:keys [whatever you need] :as fat-map}]
  (assoc fat-map :step-fn-result2 ...))


;; use meta {:changed? ...} for optimizations?
(defn memoized [function args])

;; use a composition fn that uses some memoization (backed by fulcro-db itself?)
(defn compm [& fns]
  (fn [& args]
    (let [fn-order (reverse fns)]
      (reduce ...))))
Really dirty scratch, but maybe you can get the idea.

JAtkins23:06:39

Since memoized is shared, we can take advantage of de-duplicated calls. using some form of :changed? could stop propagation. Maybe this is cheap enough that we run it for all possible registered live subscriptions on every render, since :changed? would halt it asap.

JAtkins23:06:25

Could swap out compm for just comp when testing. Works with normal functions.

JAtkins23:06:59

Maybe add a macro that keeps track of dependencies and results, and have a dependency resolution algo that simply gives you the order of functions to execute.

JAtkins23:06:04

I dunno, the more I think about it the more I like it.

tony.kay23:06:12

like I said: quick and dirty real demo with just enough complexity to prove the model would be nice

tony.kay23:06:49

avoid macros…they can always be added later. Keep it as simple and clear as possible using functions and data first.

tony.kay23:06:55

worry about sugar (much) later

mruzekw23:06:59

@U5P29DSUS So you're thinking of keeping the calculated values in the fulcro db?

JAtkins23:06:58

@U0CKQ19AQ Right, I'm just interested in the first part for now. @U1RCQD0UE yeah, but not for any really particular reason. If it's just normal functions, introspection is easy enough.