I just posted a lein re-frame template based question to #clojurescript if anyone has a moment to look at it.
Can someone help me with re-frisk
? I am learning re-frame
and re-frisk
helped me a lot during app development. There is this call: (re-frisk/enable)
which puts the debug window into my application. Which I do not want to add in the production version, only for the development. Probably I need to add an if
around enable
, but I am not sure what should be the condition. Just guessing here: I have a figwheel.main based leiningen project: I have dev.cljs.edn
and I can probably create a prod.cljs.edn
too, which could carry build information. But me seems these are intended for figwheel.main, and I am not sure their content is available directly in my application.
Is there any easy way to make (re-frisk/enable)
conditional without creating a separate configuration file and read it's content?
it's better to use :preloads [re-frisk.preload]
in your dev config
@thoneyvazul https://github.com/flexsurfer/test-re-frisk/blob/master/project.clj#L34
@andre Thank you! Preload worked nicely.
Check out re-frame.interop/debug-enabled?
.
Thank you for the idea! I am not entirely sure how this works, but according to the comment in the source code: the idea is that it defaults to true, but if I used advanced optimization, this will somehow turn to false automatically. Neat! I try this out.
No I misunderstood. I somehow need to set goog.DEBUG
in the leiningen project file.
The rise of asynchronous apis is a point of friction for re-frame. Possibly an inherant conflict of "state in memory" vs "state accessed via async".
Some kind of Promise friendly cofx might help. On react native the sqlite database and keystore apis are fast but promise based.
Reminds me of subs: signal + compute fns.
unfortunately, re-frame's API, docs and general guidance encourage developers to use re-frame events as the language they use to implement their app, which makes common things like accessing a piece of data asynchronously tedious and error prone
promises are wonderful abstractions for a huge amount of use cases; they are composable (events: must build your own composition), they are completable and failable (events: must build your own completion and failure mechanisms), and have an identity (events: must build your own way of identifying between different occurrences)
unfortunately they lack cancellation, which events can get you... if you build it and all of the other things 😄
Absolutely agree.
Anything jump out as examples we can learn from?
I've seem a few FSM libraries built [with support]for re-frame. Or just libraries that remove the need for some boilerplate. This one just yesterday: https://lucywang000.github.io/clj-statecharts/docs/integration/re-frame/ Others: - https://github.com/ingesolvoll/re-chain - https://github.com/Guaranteed-Rate/re-flow There was another one but I didn't save it - I remember not liking it because it heavily relied on side-effects in event handlers. Should've still saved it though. But I haven't used any of them yet.
statecharts is an area I think we're still trying to find the right approach with, with regards to what level the APIs should act on. Definitely warrants more exploring though. Some more libs with statecharts+re-frame: • https://github.com/MaximGB/re-state • https://github.com/jiangts/re-state And finally, re-frame EP about general state machines, seems @mikethompson is leaning towards behavior trees instead of statecharts though, at least from what I gathered from a podcast he was in, talking about re-frame: https://github.com/day8/re-frame/blob/master/docs/EPs/005-StateMachines.md
also, good general introduction to statecharts and how they can be beneficial: https://statecharts.github.io/
Thanks for the links. Also, not sure if it's the same lib I was talking about but MaximGB/re-state
definitely does dirty things.
But maybe it's practicality vs purity in this case, not sure.
yeah, guess it's the same trade-off that re-frame is doing with the registers (or is it registrar?) where there is just one global one for practicalities sake. There is a doc in the re-frame repo somewhere talking about this but not finding it atm
It's still possible to use things that re-frame offers in an async environment. But it will definitely have some boilerplate. But I'm not sure what you mean by "state accessed via async".
Perhaps "data sources" is a better word than "state" since that tends to imply the app-db in re-frame.
I agree it's possible... but if you're doing it in event handlers you're moving towards a more verbose version of the origial JS "callback hell". One option is to bundle things up as fx handlers. Another is the async-fx lib (sometimes).
I think cofx returning a promise and delays event execution until it resolves is an interesting idea.
I understand the concept but I struggle to come up with an actual use case for that.
(Quick aside: I love your engagement on slack. You do good work)
Heh, thanks. :)
Some examples I'm looking at right now. It's a React Natvie app.
I'm storing an api token in keystore. That means to use the token I need to pull it out via an async api.
So to avoid this in every handler which needs it I have choices 1. put it in app-db (keep in memory) 2. make all api calls reach into keystore directly (promise chain) 3. register two handlers the first to request data, the second to process
I went with option 1
Another example
I have an app with a database too large to hold in memory.
It's in sqlite which has an async api
to pull data out needed for a view I need to make one or more queries
So you need multiple handlers and perhaps an fx which to prepares data
That moves more logic into fx which makes them more complex.
that sort of thing.
Right, it makes it more clear, thanks.
Actually, I just started to remember how at the very beginning of my path with re-frame I was reading about IndexedDB and I couldn't quite reconcile the two things in my mind.
I think there's a argument that we have the necessary building blocks and that the convenience of chaining promises comes at the price of being more complicated (complected) and thus more difficult to test and reason about.
Still think it'd be nice if re-frame was "closer" to data sources.
Chaining promises is one thing. Using a plain promise as a data source is another. I would argue that the latter is acceptable.
yep. that would cover the common case.