To finish with the series of exercises we've been doing lately around the Lights Out kata, I decided to use reagi library to raise the level of abstraction of the communications between the Lights and the LightsGateway components.
reagi is an FRP library for Clojure and ClojureScript which is built on top of core.async. I discovered it while reading Leonardo Borges' wonderful Clojure Reactive Programming book.
I started from the code of the version using the component library I posted recently about and introduced reagi. Let's see the code.
Let's start with the lights-gateway name space:
The main change here is that the ApiLightsGateway component keeps a lights-stream which it's initialized in its start function and disposed of in its stop function using reagi.
I also use, reagi's deliver function to feed the lights-stream with the response that is taken from the channel that cljs-http returns when we make a post request to the server.
Next,the lights name space:
Notice how the dependency on core.async disappears and the code to update the lights atom is now a subscription to the lights-stream (look inside the listen-to-lights-updates! function). This new code is much easier to read and is at a higher level of abstraction than the one using core.async in previous versions of the exercise.
Now the lights-view name space:
Here I also used reagi to create a stream of clicked-light-positions. Again the use of FRP makes the handling of clicks much simpler (in previous versions a callback was being used to do the same).
Another change to notice is that we made the view a component (LightsView component) in order to properly create and dispose of the clicked-light-positions stream.
Finally, this is the core name space where all the components are composed together:
This was a nice practice to learn more about doing FRP with reagi. I really like the separation of concerns and clarity that FRP brings with it.
You can find my code in these two GitHub repositories: the server and the client (see the master branch).
You can check the changes I made to use reagi here (see the commits made from the commit d51d2d4 (using a stream to update the lights) on).
Ok, that's all, next I'll start posting a bit about re-frame.