Use your Cerebral

Damian Płaza
4 min readDec 20, 2018

--

Photo by Sabine Schulte on Unsplash

What is Cerebral apart from biological meaning of this word? Basically it’s opinionated tool for building web applications using various view libraries such as React, Vue, Angular and others. How does it differ from other existing approaches like Redux or Mobx? What benefits does it give? I’ll try to share my perspective based on production experience with Cerebral. In this first post I’m going to present my understanding of Cerebral with almost no code.

I just want to warn you — JavaScript/TypeScript world isn’t that safe as it seems to be. In order to keep yourself calm, happy and productive you need to be really disciplined. I mean — REALLY DISCIPLINED. This boils down to not deliberately introducing side-effects into your functions, keep them pure if possible with single responsiblity so that your peers (including future yourself reading code written by you now) will understand and reason about the code easily with joy and smile on the face. But everyone knows that, right? ;-)

Finally — what’s Cerebral? It is a bunch of useful concepts/abstractions/terms that make reasoning about and building web applications easy. Of course, these ones are covered with code so they become tangible and useful. In the rest of the article I will use bold text as a reference to Cerebral’s concepts (except for section subtitles).

Imperative shell. Functional core.

Cerebral promotes well-known principle expressed in the title. This means your business logic is (should be) side-effect free and every effectful operation is delegated to parts having power to do so. Functional core is built with actions — low-level unit that enable creating powerful transformation pipelines for application state. In fact, action is simply a function. Functions can be composed. Composition is the heart of Cerebral — actions can be grouped in sequences and reused across the application. Still, action shouldn’t interact with outside world directly, because it violates principle of purity. Fortunately, we have providers — right place to keep your impure, imperative and 3rd party code. They work as a layer that safely enables communication with external world like storage (e.g. IndexedDB), REST endpoints, canvas, web sockets, etc.

Purity and functional dependency injection

Each action has the same context passed as an argument. Context is an plain object that contains useful dependencies enabling interacting with state, props and providers. This means actions are testable by default, because with great ease you can mock every dependency — you have complete control over injected parts!

DSL — domain specific language

Using actions, sequences and operators, Cerebral allows building powerful specific language that is human readable so it can be presented to the domain expert and can be easily verified if it describes domain well. Declarative nature only helps reasoning about pieces of code, so you’re rooted deeply in problem solving not fighting with the “framework” how to achieve desired effect.

Expressive operators

You can leverage your code to be more expressive and readable by using operators. In reality they are just functions accepting some arguments and returning actions or sequences. So basically you can parametrize your logic so it becomes more reusable. Cerebral contains built-in, general purpose operators, but simplcity of creating your own is just intimidating. This contributes well for building ubiquitous language and documenting intention, not the details of implementation.

References to application state

Cerebral comes with really interesting term — tags. Tag is a representation of state. It is not exactly your state, but rather a “pointer” to it. You can reference state using it, simply by chaining respective paths in state tree. But true miraculous power lies in composability of tags — you can use tags to build other tags!

Consider following tag:

No real usage — just showing how you can point to specific path in state. We’re referencing users path.

It points to state tree under users path. Suppose it is an object with id of an user as a property key. Suppose in state we have selected user id. In order to access specific user we can create the following tag

Compose all the things!

Now when resolved, we will have a user with given id. Such tag can be passed around application to operate on the same state path. What’s more, you can use it both in business logic (for insance, in some sequence) and in your components (e.g. React).

Real-time debugging

Cerebral is shipped with GREAT Cerebral Debugger. It is a devtool that helps visualizing executed/executing sequences, inspecting mutations, performing time-travelling, checking number of rerendered components and a lot more! It brings debugging of an application to the higher, better level. Next to Cerebral’s declarative way of expressing business logic, it’s a great introduction tool for other devs coming into the project. They simply can see how data flows through application — literally!

UI as a function of state

DRY — don’t repeat yourself they said. As stated, if you think about UI of your web app as a transformed state — you gain interesting benefits. For instance, changing one piece of state by transforming another one, brings UI change almost efortlessly. This means that sometimes you can avoid repetitiveness by computing state from other state. Computeds enable deriving state. They can be used across entire application — in your view (connected components), operators, actions, sequences and, other computeds! This means Cerebral shines again in terms of composability.

Summary

This was only a short introduction/review of Cerebral’s concepts that I found interesting enough to talk about. Still I am aware that I scratched the surface and I am leaving you, dear reader, with a lot of questions (hopefully) and uncertainty. If you don’t know Cerebral, I really encourage you to visit their page at https://cerebraljs.com/ . You can find getting started section — it will explain in greater details stuff I mentioned briefly in this post.

--

--