<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[fawwaz]]></title><description><![CDATA[fawwaz]]></description><link>https://blog.fawwaz.dev</link><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Apr 2026 08:37:40 GMT</lastBuildDate><atom:link href="https://blog.fawwaz.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How I Turned a Dumb Speaker Smart with a Dead Phone and Home Assistant]]></title><description><![CDATA[I've always been jealous of the makers, the tinkerers, the electronics people. There's just something about building things you can physically touch I've wanted to learn for years but every time I tri]]></description><link>https://blog.fawwaz.dev/dumb-speaker-smart-dead-phone-home-assistant</link><guid isPermaLink="true">https://blog.fawwaz.dev/dumb-speaker-smart-dead-phone-home-assistant</guid><category><![CDATA[Home Assistant]]></category><category><![CDATA[iot]]></category><category><![CDATA[smarthome]]></category><category><![CDATA[self-hosted]]></category><dc:creator><![CDATA[Fawaz Alharbi]]></dc:creator><pubDate>Tue, 07 Apr 2026 08:33:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/61c673d0f6c63f538e6f3da2/4ec962ac-2956-4bb7-8983-1007d7601f7c.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I've always been jealous of the makers, the tinkerers, the electronics people. There's just something about building things you can physically touch I've wanted to learn for years but every time I tried, there was just too much. Soldering, IoT protocols, new tools, electrical concepts. So I did what I often do shelf this to the "future" when I have "more time".</p>
<h2>The Idea That Wouldn't Go Away</h2>
<p>Then one day I looked at the speakers in my house and thought: how hard is it going to be to make these things programmable? Like, play music from 7 to 11 automatically. Café mode. And I wanted to finish it <em>today</em>.</p>
<p>I vaguely knew about something called <strong>Home Assistant.</strong> So I did what any self-respecting developer would do, I went and asked AI 🤖. After a long back-and-forth, it turned out the setup wasn't that complicated. Here's the full picture of what we figured out:</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c673d0f6c63f538e6f3da2/096519de-e9f2-4273-a14f-45dae4329d52.jpg" alt="" style="display:block;margin:0 auto" />

<p>You have a Squeezebox client that connects to a speaker through Bluetooth, and on the other end connects through Wi-Fi to a Squeezebox server running inside Home Assistant. Home Assistant Music handles the connection to your music provider (Spotify, YouTube Music, etc.)</p>
<p>The original plan involved an ESP32 a microcontroller. But as I understood what was actually needed something that receives an audio stream and pushes it to a speaker I thought why can't I just use my old phone? 🤷‍♂️.</p>
<h2>Setting Up Home Assistant</h2>
<p>First thing: <a href="https://www.home-assistant.io/">Home Assistant</a>. If you don't know it, think of it like Google Home or Apple Home except you don't have to worry about these corporations recording every conversation you have. It runs completely in your home, on your network.</p>
<p>You need some kind of computer to run it. Any old computer, a Raspberry Pi, or you can buy the <a href="https://www.home-assistant.io/green/">Home Assistant Green</a> — a ready-to-go device you plug in and it just works out of the box. I already have a home server so I set it up as a VM.</p>
<p>Once Home Assistant is up, you create an account and install the <strong>Music Assistant</strong> app. This is where two important concepts come together:</p>
<ul>
<li><p><strong>Music Providers</strong> adapters that bring your music from platforms like Spotify, YouTube Music, Apple Music, etc.</p>
</li>
<li><p><strong>Players</strong> destinations where the music plays. Your laptop, a speaker, anything that can receive audio.</p>
</li>
</ul>
<img src="https://cdn.hashnode.com/uploads/covers/61c673d0f6c63f538e6f3da2/43777e39-4488-4779-8b9f-cc7aa2965ccf.png" alt="" style="display:block;margin:0 auto" />

<img src="https://cdn.hashnode.com/uploads/covers/61c673d0f6c63f538e6f3da2/f320edb1-edf4-4baf-a132-d0ce09d619aa.png" alt="" style="display:block;margin:0 auto" />

<img src="https://cdn.hashnode.com/uploads/covers/61c673d0f6c63f538e6f3da2/59207046-f132-4b66-bcdf-39380759b306.png" alt="" style="display:block;margin:0 auto" />

<p>I connected YouTube Music (the adapter is in beta but it worked). And then something cool happened.</p>
<h2>The Moment It Clicked</h2>
<p>My laptop was already showing up as a player. Just because it's on the same network as Home Assistant. I hit play. Music came out of my laptop.</p>
<p>This was not the goal. But it made me <em>understand</em> how things connect. Music Assistant discovers players on the network. My laptop is one. Now I just need to add another one the old phone connected to my speaker.</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c673d0f6c63f538e6f3da2/7e5d85dc-c539-4831-9954-d1faa7987b80.png" alt="" style="display:block;margin:0 auto" />

<h2>Adding the Dead Phone as a Player with Squeezebox</h2>
<p><a href="https://en.wikipedia.org/wiki/Squeezebox_(network_music_player)">Squeezebox</a> is a technology that's been around for a while. What makes it interesting is that it doesn't send audio files to the device it streams audio data to any audio sync. So conceptually, if the phone is connected to the speaker through Bluetooth, any audio streamed to the phone goes straight to the speaker.</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c673d0f6c63f538e6f3da2/f14002ed-b513-44fd-a323-5e12ac7168ca.png" alt="" style="display:block;margin:0 auto" />

<p>Here's how I set it up:</p>
<ol>
<li><p><strong>Squeezebox Server</strong>: In Home Assistant Music, go to the plugins and add the Squeezebox provider. This sets up the server.</p>
</li>
<li><p><strong>Squeezebox Client on the Phone</strong>: I needed a Squeezebox client for Android. The official options are all paid on the Play Store. So I went to <a href="https://f-droid.org/">F-Droid</a> (an open-source app store) and installed <strong>SqueezeLite</strong>. Straightforward setup just point it to the server address and hit start.</p>
</li>
<li><p><strong>Connect Phone to Speaker via Bluetooth</strong>: Just the standard Bluetooth pairing. Nothing fancy.</p>
</li>
</ol>
<p>After this, I could see a new player in Home Assistant Music, "Android Speaker." I picked a song, chose that player, hit play, and the music came through the speaker.</p>
<p>That was the moment I knew the hard part was done.</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c673d0f6c63f538e6f3da2/c82bd7a4-7ac8-4c6e-a9ed-f7ad425d9d92.png" alt="" style="display:block;margin:0 auto" />

<h2>The Snowball</h2>
<p>This is the part I didn't expect.</p>
<p>Home Assistant has an automation tab and it's surprisingly straightforward. I set it up: music plays from 7 to 11, jazz playlist. Café mode.</p>
<p>But then I noticed my TV had been discovered on the network. Home Assistant just found it. So I added a rule — TV on, music stops.</p>
<p>Then I installed the Home Assistant companion app, which knows whether I'm home (and that data never leaves my server). New rule: left the house, music stops.</p>
<p>Then I wrote a small script that checks if my laptop mic is active. New rule: on a call, music ducks.</p>
<p>Each of these took minutes. And each one came from just poking around what Home Assistant had already found.</p>
<p>And then more things opened up. I discovered <strong>devices</strong> and <strong>entities</strong>. I saw <strong>NFC tags</strong> in the settings and went down a rabbit hole of how people use them. By the end of this one project, I had more ideas of what to build next than I ever got from reading books or watching courses.</p>
<p>Turns out all it took was one small question to pull me in.</p>
<hr />
<p><em>If you have questions or want to share what you built, feel free to reach out. Happy hacking 🤓</em></p>
]]></content:encoded></item><item><title><![CDATA[Convert Tailwind Components to Logical Tailwind with This Tool]]></title><description><![CDATA[I love coding but if I have to spend half just fighting with the UI to get things looking as I want, then I don't feel very productive. This why I always love to find copy-past starting points from places like TailwindUI of Flowbite, to help move fas...]]></description><link>https://blog.fawwaz.dev/convert-tailwind-components-to-logical-tailwind-with-this-tool</link><guid isPermaLink="true">https://blog.fawwaz.dev/convert-tailwind-components-to-logical-tailwind-with-this-tool</guid><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[CSS]]></category><category><![CDATA[React]]></category><category><![CDATA[Tailwind CSS Tutorial]]></category><category><![CDATA[Flowbite]]></category><dc:creator><![CDATA[Fawaz Alharbi]]></dc:creator><pubDate>Fri, 21 Jul 2023 10:06:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1689929605124/fdd685bb-bddf-40fc-aba0-d9647e108d78.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I love coding but if I have to spend half just fighting with the UI to get things looking as I want, then I don't feel very productive. This why I always love to find <em>copy-past</em> starting points from places like <a target="_blank" href="https://tailwindui.com/">TailwindUI</a> of <a target="_blank" href="https://flowbite.com/">Flowbite</a>, to help move faster. However, almost always these components are built to work with Left-to-Right (LTR) direction. So what happens when these components are integrated into websites that need to support Right-to-Left (RTL) languages like Arabic? Often, they break.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689932249103/3687fe0e-7168-4cb2-8523-88c2b50916b0.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-why-does-this-happen"><strong>Why does this happen?</strong></h2>
<p>This happens when a component use Non-logical CSS like <code>padding-left</code>, <code>margin-right</code>, <code>top-5</code> and much more. Non-logical properties include <code>width</code> and <code>height</code> which can break designs for languages that are Top-To-Bottom (TTB).</p>
<p>However, Both Flexbox and Grid are designed logically, allowing them to function correctly irrespective of the direction. This explains why some parts of the design, such as the spacing between icons and links, display correctly in both LTR and RTL.</p>
<p>New CSS properties have been introduced to address these issues, creating a more logical user interface. For instance, <code>padding-start</code> was introduced to correspond to <code>padding-left</code> in RTL, while <code>block-size</code> was developed to match <code>height</code>. Many more logical CSS properties have been developed. <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_logical_properties_and_values">A complete list of these properties can be found here</a>.</p>
<h2 id="heading-introducing-to-logical-tailwindhttpsto-logical-tailwindfawwazdev"><strong>Introducing</strong> <a target="_blank" href="https://to-logical-tailwind.fawwaz.dev/"><strong><em>to-logical -tailwind</em></strong></a></h2>
<p>Lucky for us the TaiwlindCss ecosystem for a while had a <a target="_blank" href="https://github.com/stevecochrane/tailwindcss-logical">plugin</a> that added support to logical Css in Taiwlind. Also more recently TaiwlindCss added native support to RTL with <a target="_blank" href="https://tailwindcss.com/blog/tailwindcss-v3-3">V3.3 release</a>. To-logical-tailwind, support both output formats and converts any tailwind component to a "logical-tailwind" component.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689930080066/46bcaf66-6d7c-486a-addc-944a04911cdc.jpeg" alt class="image--center mx-auto" /></p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>You can start using <a target="_blank" href="https://to-logical-tailwind.fawwaz.dev/">to-logical-tailwind</a> today, and the code for the project is open-source and you can find it <a target="_blank" href="https://github.com/Fawwaz-2009/to-logical-tailwind">here</a>. Happy hacking and feel free to open an issue if you need any help 🤓.</p>
]]></content:encoded></item><item><title><![CDATA[From Zustand to Xstate: the Zen of using the right tool]]></title><description><![CDATA[I've known and seen demos of Xstate for a while but never felt the need to use it in a project. My understanding was and still is that Xstate shines in complex flow. Recently I worked on a small personal project that I built with Zustand I thought th...]]></description><link>https://blog.fawwaz.dev/from-zustand-to-xstate-the-zen-of-using-the-right-tool</link><guid isPermaLink="true">https://blog.fawwaz.dev/from-zustand-to-xstate-the-zen-of-using-the-right-tool</guid><dc:creator><![CDATA[Fawaz Alharbi]]></dc:creator><pubDate>Sun, 16 Jul 2023 13:45:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/tYVkjjMYFBo/upload/ec27e1ae5b9548daf9981a4af6e08949.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I've known and seen demos of Xstate for a while but never felt the need to use it in a project. My understanding was and still is that Xstate shines in complex flow. Recently I worked on a small personal project that I built with Zustand I thought this a good project to dive into. This article is going to be about my experience of switching.</p>
<h2 id="heading-tldr">TLDR;</h2>
<p>The biggest advantage of Xstate is it comes to modeling complex business logic. Instead of juggling various flags or values to get things to work, as you often need to do in Zustand, Xstate allows you to align your coding approach with the actual mental model of your business logic. For example, you have a flow that is the most linear and sequential you can visualize is it in your stat chart as such. <a target="_blank" href="https://stately.ai/registry/editor/embed/a0dac34d-6a6b-4c1c-8b98-95b3a6420fd6?machineId=aabf5cc9-2f13-4625-b5df-ad1f3d94a02b">See the machine at Stately here</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689492725364/f84f2062-4102-4724-ad1a-5ba0060fa003.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-about-the-project-and-the-plan-for-migration">About the project and the plan for migration</h2>
<p>So the App we are working with allow users to create formatted tables from csv fiels . It works by using a <code>dataModel</code> to extract data and format csv files. The app is powered by a single Zustand store but broken down into two different slices. One slice is responsible for the creation of the formatted tables ("<code>AutoTables</code>"). The other slice is responsible for the creation and updating of user-defined <code>DataModels</code>. Another layer of complexity is that the store is persisted to localStorage.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689492386688/2064f50c-f2ec-4dfb-a04c-3002dd7b0d06.png" alt class="image--center mx-auto" /></p>
<p>When planning for migration to Xstate, I wanted as much as possible to do incremental migration to the Xstate. First I decided that I will start with the <code>CreateAutoTableSlice</code>. The thinking was that I can start using Xstate and not worry about persistence for now. However, I still needed somehow to be synced with any <code>DataModels</code> that are defined on the user device. Luckily the solution in Xstate was simple. In the first step of the machine, I added an invocation that fetches the data Models from local storage.</p>
<h1 id="heading-rabid-fire-mental-model-of-xstate">Rabid fire mental model of Xstate</h1>
<p>Before delving deeper into the details, let's quickly establish a fundamental mental model of Xstate. This section aims to give you an essential grounding to better appreciate the rest of the article.</p>
<ul>
<li><p><strong>Everything is defined inside a machine*</strong>: Your business logic, side effects, context, state values—everything is defined and lives inside a single machine.</p>
<ul>
<li>* There are patterns such as <code>withConfig</code> and the options parameter of the <code>useMachine</code> function, but these mostly augment the state machine rather than altering this fundamental characteristic.</li>
</ul>
</li>
<li><p><strong>Logic is modeled as several states connected by transitions</strong>: you define explicit state charts, which not only manage state but also elegantly map out the entire flow of our application logic.</p>
</li>
<li><p><strong>Machin "Context"</strong>: it's where you store data that can change over time and across states. It acts as a memory of sorts for your state machine, persisting data between state transitions.</p>
</li>
<li><p><strong>No Built-in State Sharing:</strong> Xstate doesn't have inbuilt primitives for sharing states across different applications, unlike Zustand. But fear not, as there are well-established patterns for state sharing in Xstate, which we'll be exploring later.</p>
</li>
<li><p><strong>Using Machines by "Interpreting" it</strong>: Finally, in a React application, you bring your machine to life by using <code>useMachine</code> or <code>useInterpret</code>. These hooks start a machine that runs for the lifetime of the component.</p>
</li>
</ul>
<h1 id="heading-lessons-learned">Lessons Learned</h1>
<h2 id="heading-the-code-matches-my-mental-model-of-the-business">The code matches my mental model of the business</h2>
<p>Often time when you start coding you have a fuzzy idea of how the business logic should work. This is because the natural language can't perfectly encapsulate the complexities of business operations.<br />Consequently, you end up in a cycle of coding, encountering unforeseen scenarios, refactoring, rewriting, and repeating until you achieve a working product that meets the business needs.</p>
<p>Having your code Matches the mental model of your business makes things much faster to develop. And even when you hit cases where you have to update the code to match your new understanding of the business logic is a lot easier. on top of all the the Xstate visualizer/editor, make things even easier.</p>
<h2 id="heading-there-is-a-learning-curve">There is a learning curve</h2>
<p>No Surprise there is a learning curve and a bunch of new concepts and terminologies to learn for me. Also I never really got to a point where I felt I have a solid understanding of what exactly is an <code>actor</code>, I know that a <code>service</code> is an <code>actor</code> in Xstate and I know that an actor is something that "sends messages, receives messages and do some computation" but still for my brain that wasn't enough.</p>
<p>Luckily despite this disadvantage, I managed to get my way around Xstate and manage to migrate the AutoTablesCreationSlice to Xstate. It did however take a couple of days for me to feel comfortable and stop being frustrated when typescript screams at me. As usual with foreign new complex concepts, I need to sleep on it and that for some weird reason does help.</p>
<h2 id="heading-dealing-with-computed-context"><strong>Dealing with Computed Context</strong></h2>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">In the Xstate, what's known as "computed state" in Redux or Zustand becomes "computed context". This is because in Xstae a "state" represents a specific phase in the state machine, while "context" stores data that changes over time and across states.</div>
</div>

<p>Computed context is a common need in our application and often time they do include business logic. Unfortunately Xstate doesn't have the concept of computed/derived context. However, the <code>xstate/react</code> package does come with a <code>useSelector</code>. Initially, I tried to build a custom selector hook that will encapsulate all the available computed context. However, I apondened that approach after I learned that you lose the isolation of re-renders based on what changes by using <code>useSelector</code>. Instead, I create a <code>DerivedContextSelectors</code> to encapsulate all the business logic in one place.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> autoTablesCreationMachineDerivedContextSelectors = {
  selectAvailableDataModelsNames: selectAvailableDataModelsNames,
  <span class="hljs-comment">// more selectors here</span>
} <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
</code></pre>
<h2 id="heading-hidden-bugs">Hidden Bugs</h2>
<p>I got stuck for 15m during the migration on an event that I can see from the dev-tool that is firing but the transition does not complete. I eventually found out that event firing was referencing <code>the target state</code> that was renamed. Though typescript did show an error in that file, the app didn't show anyting in the logs and didn't break. I wished that cases like this would break more loudly.</p>
<h2 id="heading-actions-can-be-fired-from-anywhere">Actions can be fired from anywhere</h2>
<p>This point was not immediately obvious to me and I was having a difficult time figuring out how to fire an error toast if the processing of uploaded files failed but still who the upload screen. I ended up doing what is called a self-transition and firing the error toast from the event.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689509027194/859eda04-1056-41eb-9fd3-2c110ce6537f.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-using-the-state-machine-across-components">Using the state Machine across components</h2>
<p>As discussed earlier, we bring our state machine to life in a component by 'interpreting' it using either <code>useMachine</code> or <code>useInterpret</code>. This initiation creates distinct, disconnected flows for each component on each call, which may not always what you want. If we want different components to share the same flow, we can achieve this by using ReactContext.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> AutoTablesCreationServiceContext = React.createContext&lt;InterpreterFrom&lt;<span class="hljs-keyword">typeof</span> autoTablesCreationMachine&gt; | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);

<span class="hljs-comment">// inside your component </span>
<span class="hljs-keyword">const</span> service = useInterpret(autoTablesCreationMachine, { devTools: <span class="hljs-literal">true</span> });
<span class="hljs-comment">// insde the return</span>
 &lt;AutoTablesCreationServiceContext.Provider value={service}&gt;
    {children}
 &lt;/AutoTablesCreationServiceContext.Provider&gt;
</code></pre>
<p>Then in any component, you can do this</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> service = useContext(autoTablesCreationMachine);
</code></pre>
<p>I wanted to use the <code>useActor</code> hook to perform <code>state.match</code> (which is how you verify the state of your machine). But since the context is sometimes <code>null</code> this was a problem so I ended up creating a custom hook that asset strong types the context and throws if it's missing.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { useContext, <span class="hljs-keyword">type</span> Context } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">useRequiredContext</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params">context: Context&lt;T | <span class="hljs-literal">null</span>&gt;</span>): <span class="hljs-title">T</span> </span>{
  <span class="hljs-keyword">const</span> value = useContext(context);
  <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">null</span>) {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Context value is missing'</span>);
  }
  <span class="hljs-keyword">return</span> value;
}
</code></pre>
<h1 id="heading-final-score">Final Score</h1>
<p>Using Xstate did require a different way of thinking about my application state. But it did ended-up for me to be a much more natural way of thinking about code and business logic. Despite the learning curve, I'm very pleased with the migration to Xstate. Going forward I'm going to explore migrating the next slice to Xstate and figure out the best approach strategy for persisting the machine's context. Stay tuned for a potential Part 2 of this article.</p>
]]></content:encoded></item><item><title><![CDATA[Solving Persistence of DDD Objects with Prisma (SQL)]]></title><description><![CDATA[Introduction
Domain-Driven Design (DDD) is a software development methodology that emphasizes the importance of modeling business domains to create software that closely aligns with the needs of the organization. However, persisting DDD objects can p...]]></description><link>https://blog.fawwaz.dev/solving-persistence-of-ddd-objects-with-prisma-sql</link><guid isPermaLink="true">https://blog.fawwaz.dev/solving-persistence-of-ddd-objects-with-prisma-sql</guid><category><![CDATA[DDD]]></category><category><![CDATA[prisma]]></category><category><![CDATA[SQL]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Fawaz Alharbi]]></dc:creator><pubDate>Wed, 26 Apr 2023 04:16:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/lRoX0shwjUQ/upload/6b778cc758267590a9eae47a87ff3d95.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-introduction">Introduction</h1>
<p>Domain-Driven Design (DDD) is a software development methodology that emphasizes the importance of modeling business domains to create software that closely aligns with the needs of the organization. However, persisting DDD objects can present challenges for developers. In this article, we'll discuss some common problems when persisting DDD objects and explore how to solve them using Prisma, a powerful and flexible ORM for Node.js and TypeScript. We will use the following example models throughout the article:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Customer {
  id: <span class="hljs-built_in">string</span>;
  name: <span class="hljs-built_in">string</span>;
  orders: Order[];
}

<span class="hljs-keyword">class</span> Order {
  id: <span class="hljs-built_in">string</span>;
  customerId: <span class="hljs-built_in">string</span>;
  total: <span class="hljs-built_in">number</span>;
  items: OrderItem[];
}

<span class="hljs-keyword">class</span> OrderItem {
  productId: <span class="hljs-built_in">string</span>;
  quantity: <span class="hljs-built_in">number</span>;
  price: <span class="hljs-built_in">number</span>;
}
</code></pre>
<h2 id="heading-problem-1-create-vs-update">Problem 1: Create VS Update</h2>
<p>In DDD, aggregate or entity IDs are usually set upon object creation if they do not exist. This presents a problem: if the ID always exists, how do we know if we should use Create or Update when persisting the object? Using the wrong operation will result in an error. Consider the code below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Customer } <span class="hljs-keyword">from</span> <span class="hljs-string">'./models/Customer'</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> cuid <span class="hljs-keyword">from</span> <span class="hljs-string">'cuid'</span>;

<span class="hljs-keyword">class</span> CustomerAggregate {
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> _customer: Customer</span>) {}

  <span class="hljs-keyword">static</span> create(customer: Partial&lt;Customer&gt;): CustomerAggregate {
    <span class="hljs-keyword">const</span> id = customer.id || cuid();
    <span class="hljs-keyword">const</span> newCustomer = <span class="hljs-keyword">new</span> Customer({ ...customer, id });
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> CustomerAggregate(newCustomer);
  }

  get customer(): Customer {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>._customer;
  }
}
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">saveCustomer</span>(<span class="hljs-params">customer: Customer</span>) </span>{
  <span class="hljs-keyword">if</span> (customer.id) {
    <span class="hljs-keyword">await</span> prisma.customer.update({ where: { id: customer.id }, data: customer });
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">await</span> prisma.customer.create({ data: customer });
  }
}
</code></pre>
<p>if the Customer Object always has an ID then the <code>else</code> path will never be reached! Of course, there is a million hacky way to solve this like adding a flag to the domain object but we are looking for a clear separation between the Domain and the DB.</p>
<h3 id="heading-solution-using-upsert-with-prisma">Solution: Using <code>upsert</code> with Prisma</h3>
<p>Prisma provides an <code>upsert</code> feature, which allows developers to replace Create and Update with Save. This simplifies the persistence logic, as shown in the code below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">saveCustomer</span>(<span class="hljs-params">customer: Customer</span>) </span>{
  <span class="hljs-keyword">await</span> prisma.customer.upsert({
    where: { id: customer.id },
    update: customer,
    create: customer,
  });
}
</code></pre>
<p>One caveat to this is that the save method can get quite large as the aggregate increase in the number of relations and complexity. See example below</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">async</span> save(propertyListing: PropertyListingAggregate): <span class="hljs-built_in">Promise</span>&lt;{ id: <span class="hljs-built_in">string</span> }&gt; {
    <span class="hljs-keyword">const</span> { pricingOptions, images, propertyListingData } = propertyListingMapper.toDb(propertyListing);

     <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.prisma.propertyListings.upsert({
      where: {
        id: propertyListingData.id,
      },
      create: {
        ...propertyListingData,
        customGeneralInfo: Prisma.JsonNull,
        customFeaturesAndAmenities: Prisma.JsonNull,
        pricingOptions: {
          createMany: {
            data: pricingOptions,
          },
        },
        images: {
          createMany: {
            data: images,
          },
        },
      },
      update: {
        ...propertyListingData,
        customGeneralInfo: Prisma.JsonNull,
        customFeaturesAndAmenities: Prisma.JsonNull,
        pricingOptions: {
          deleteMany: {},
          createMany: {
            data: pricingOptions,
          },
        },
        images: {
          deleteMany: {},
          createMany: {
            data: images,
          },
        },
      },
    });

    <span class="hljs-keyword">return</span> { id: propertyListingData.id };
  }
</code></pre>
<h2 id="heading-problem-2-value-objects-persisted-on-another-table">Problem 2: Value Objects Persisted on Another Table</h2>
<p>Sometimes, we have DDD objects that should be value objects but, due to how they are persisted in the database, we need to assign them an ID. This goes against one of the fundamental ideas of DDD: that database concerns should not leak into the domain.</p>
<h3 id="heading-solution-transactions-and-cascading-relations">Solution: Transactions and Cascading Relations</h3>
<p>To address this issue, we can use transactions in the Save method. This allows us to first delete all value objects and then create new ones through cascading relations. Consider the code example below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">saveOrder</span>(<span class="hljs-params">order: Order</span>) </span>{
  <span class="hljs-keyword">await</span> prisma.$transaction([
    prisma.orderItem.deleteMany({ where: { orderId: order.id } }),
    ...order.items.map(<span class="hljs-function">(<span class="hljs-params">item</span>) =&gt;</span>
      prisma.orderItem.create({
        data: { ...item, orderId: order.id },
      })
    ),
    prisma.order.upsert({
      where: { id: order.id },
      update: { total: order.total },
      create: { ...order, items: { create: order.items } },
    }),
  ]);
}
</code></pre>
<p>While this solution does increase the number of database operations, it prevents database concerns from leaking into the domain.</p>
<h2 id="heading-summary-and-conclusion">Summary and Conclusion</h2>
<p>Persisting DDD objects can pose challenges for developers, but Prisma provides powerful tools to overcome these issues. In this article, we explored how to use the <code>upsert</code> feature to simplify the Create and Update operations and how to use transactions and cascading relations to handle value objects that are persisted on separate tables. By employing these techniques, developers can adhere to the principles of DDD while efficiently persisting their domain objects.</p>
]]></content:encoded></item><item><title><![CDATA[Redux: The Under The Hood Tour]]></title><description><![CDATA[Photo by Hosea Georgeson on Unsplash
But wait we have React hooks now, we don't need Redux anymore, right ?

If you are not a React dev, React hooks are the latest addition to React and they are absolutely awesome ⚡, but they are not replacing Redux....]]></description><link>https://blog.fawwaz.dev/redux-the-under-the-hood-tour</link><guid isPermaLink="true">https://blog.fawwaz.dev/redux-the-under-the-hood-tour</guid><category><![CDATA[Redux]]></category><category><![CDATA[Functional Programming]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Fawaz Alharbi]]></dc:creator><pubDate>Thu, 26 May 2022 06:22:28 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1653545987121/jM0M_211X.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Photo by Hosea Georgeson on Unsplash</em></p>
<h2 id="heading-but-wait-we-have-react-hooks-now-we-dont-need-redux-anymore-right">But wait we have React hooks now, we don't need Redux anymore, right ?</h2>

<p>If you are not a React dev, React hooks are the latest addition to React and they are absolutely awesome ⚡, but they are not replacing Redux. If you are still unconvinced, I would strongly recommend Eric Elliot article, <a target="_blank" href="https://medium.com/javascript-scene/do-react-hooks-replace-redux-210bab340672">Do React Hooks Replace Redux?</a>.</p>

<p>For now if you want to continue without reading Elliot article, here is the tl;dr:</p>
<ul>
<li>Redux is not just a library, it's architecture that proved very effective in building scalble and maintainable code.</li>
<li>While you can recreate the functionalities of Redux using the createContext and React Hooks, there are no clear gains from that and you would lose access to the powerful debugging capabilities in Redux devtools.</li>
</ul>

<p>I hope that you are convinced and that you would join us in this tour. Now before we jump right in, please have a look at our brochure of functional programming concepts that you will see quite often inside Redux. <em>If however, you feel confident in these concepts you can skip to the start of the tour.</em></p>
<h2 id="heading-toc">TOC</h2>
<ul>
<li><a class="post-section-overview" href="#brochure-of-functional-programming-concepts">Brochure of functional programming concepts</a><ul>
<li><a class="post-section-overview" href="#pure-functions">Pure Functions</a></li>
<li><a class="post-section-overview" href="#closures">Closures</a></li>
<li><a class="post-section-overview" href="#high-order-functions">High order functions</a></li>
<li><a class="post-section-overview" href="#currying">Currying</a></li>
<li><a class="post-section-overview" href="#function-composition">Function Composition</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#start-of-the-tour">Start of The Tour</a><ul>
<li><a class="post-section-overview" href="#first-raw-rootreducer-endraw-the-maker-of-the-new-state">First: rootReducer, the maker of the new state</a></li>
<li><a class="post-section-overview" href="#second-raw-createstore-endraw-the-store-maker">Second: createStore, the store maker</a></li>
<li><a class="post-section-overview" href="#third-raw-middlewares-endraw-the-ones-in-the-middle">Third: middleWares, the ones in the middle</a></li>
<li><a class="post-section-overview" href="#fourth-raw-enhancers-endraw-augmenting-raw-createstore-endraw-">Fourth: enhancers, Augmenting createStore</a><ul>
<li><a class="post-section-overview" href="#the-raw-applymiddleware-endraw-">The applyMiddleWare</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="post-section-overview" href="#the-gift-shop">The Gift shop</a></li>
</ul>
<h2 id="heading-brochure-of-functional-programming-concepts">Brochure of functional programming concepts</h2>
<p>We are not going to try and give an exhaustive explanation of those concepts here as I believe it would be futile to try and jam all of those in a single article. However, I'll try to explain just enough so you can gain the most from this article.</p>
<h3 id="heading-pure-functions">Pure Functions</h3>
<ul>
<li>Functions which their return value is determained by the arguments passed to them.</li>
<li>They don't access or modify values outside of their scope.</li>
</ul>
<h3 id="heading-closures">Closures</h3>
<p>Closures are created at the <strong>creation</strong> of new functions and they allow those functions to access the outer scope.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">outer</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> savedInClosure = <span class="hljs-literal">true</span>;
  <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">if</span> (savedInClosure) {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'I always have closure'</span>);
    }
  };
}

<span class="hljs-keyword">const</span> doYouHaveClosure = outer();
doYouHaveClosure(); <span class="hljs-comment">// 'I always have closure'</span>
</code></pre>
<h3 id="heading-high-order-functions">High order functions</h3>
<p>Functions that receive functions as an argument and/or return another function. Also, Yup the code above is a high order function, well done for noticing 😉.</p>
<h3 id="heading-currying">Currying</h3>
<p>Currying is the technique of taking a function that takes multiple arguments and transforming it into a series of functions that takes one argument at a time. Now, you might scream to yourself why would I ever want to do that. Well the simple answer is "specialized Functions and separation of complexity". Let's have a look at the canonical example of currying:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Before currying</span>
<span class="hljs-keyword">const</span> add_notCurrying = <span class="hljs-function">(<span class="hljs-params">x, y</span>) =&gt;</span> x + y;

<span class="hljs-comment">// after currying</span>
<span class="hljs-keyword">const</span> add_currying = <span class="hljs-function"><span class="hljs-params">x</span> =&gt;</span> <span class="hljs-function"><span class="hljs-params">y</span> =&gt;</span> x + y;

<span class="hljs-comment">// specialize functions</span>
<span class="hljs-keyword">const</span> add2 = add_currying(<span class="hljs-number">2</span>);

add2(<span class="hljs-number">8</span>); <span class="hljs-comment">// 10</span>
</code></pre>
<p>Now say your manager comes to you and tell you, "the add functions must do a bunch of checks and API calls before committing the first argument and must do totally different checks and API calls to commit the second argument". In the uncurried version you would have to jam all that complexity into one functions, while on the curried version of <code>add</code> you can separate it.</p>
<h3 id="heading-function-composition">Function Composition</h3>
<p>Function composition is the process combining functions to build more sophisticated ones, and yes in the examples above we've already done some function composition. However, the techniques that I want to explain here is the one that might give you headache first time you see it:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> myFuncs = [func1, func2, func3, func4];

<span class="hljs-keyword">const</span> compose = <span class="hljs-function"><span class="hljs-params">arr</span> =&gt;</span> arr.reduce(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> <span class="hljs-function">(<span class="hljs-params">...args</span>) =&gt;</span> a(b(...args)));

<span class="hljs-keyword">const</span> chain = compose(myFuncs);
</code></pre>
<p><strong>WAAAAAAAAIT</strong>...., Now trust me if you don't have experience in functional programming, like I was when I first saw this, having a reaction like "🤬🤬🤬🤬" is in my opinion the healthiest response you can have. Unless you are well versed in functional programming, this will not be intuitive and it might takes time for it to click in your mind, but. For now, know that all compose does is help us get to something like this function.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> composed = <span class="hljs-function">(<span class="hljs-params">...args</span>) =&gt;</span> func1(func2(func3(func4(...args))));
</code></pre>
<p>As you can see the final function we get from compose, calls the functions in the array right-to-left and passing the return of each function as the argument to the previous one. Now with that mental framework in mind try to take a look at a refactored version from the code above.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> myFuncs = [
  <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-number">1</span>);
  },
  <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-number">2</span>);
  },
  <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-number">3</span>);
  },
  <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-number">4</span>);
  }
];

<span class="hljs-keyword">let</span> chain = myFuncs[<span class="hljs-number">0</span>];

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> index = <span class="hljs-number">1</span>; index &lt; myFuncs.length; index++) {
  <span class="hljs-keyword">const</span> currentRingInTheChain = myFuncs[index];

  <span class="hljs-comment">// This is necessary to avoid recursion. Basically we storing different instances of functionsChainSoFar in closure scopes</span>
  <span class="hljs-keyword">const</span> functionsChainSoFar = chain;

  chain = <span class="hljs-function">(<span class="hljs-params">...args</span>) =&gt;</span> functionsChainSoFar(currentRingInTheChain(...args));
}

chain(); <span class="hljs-comment">// 4 , 3, 2, 1</span>
</code></pre>
<p>I hope that clarified what <code>compose</code> does but if you are still not 100% sure, don't worry too much. Again this might take time and it does require a mental shift.</p>
<p>BONSUS ROUND: what do you think the following code will log?.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> myFuncs = [
  <span class="hljs-function"><span class="hljs-params">func</span> =&gt;</span> <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-number">1</span>);
    func();
  },
  <span class="hljs-function"><span class="hljs-params">func</span> =&gt;</span> <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-number">2</span>);
    func();
  },
  <span class="hljs-function"><span class="hljs-params">func</span> =&gt;</span> <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-number">3</span>);
    func();
  },
  <span class="hljs-function"><span class="hljs-params">func</span> =&gt;</span> <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-number">4</span>);
    func();
  }
];

<span class="hljs-keyword">const</span> hakuna = <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Mattata'</span>);

<span class="hljs-keyword">const</span> secret = compose(myFuncs)(hakuna);

secret(); <span class="hljs-comment">// what do you think this will log?</span>
</code></pre>
<p>Give it a go but if you get stuck don't worry will revisit this again in the article.</p>
<h2 id="heading-start-of-the-tour">Start of The Tour</h2>
<p>The best way to start the tour is to see how we are creating a Redux store and what are the pieces that plays a part in that. So let's have a look at this sample from the docs.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { applyMiddleware, createStore } <span class="hljs-keyword">from</span> <span class="hljs-string">'redux'</span>;
<span class="hljs-keyword">import</span> thunkMiddleware <span class="hljs-keyword">from</span> <span class="hljs-string">'redux-thunk'</span>;
<span class="hljs-keyword">import</span> { composeWithDevTools } <span class="hljs-keyword">from</span> <span class="hljs-string">'redux-devtools-extension'</span>;

<span class="hljs-keyword">import</span> monitorReducersEnhancer <span class="hljs-keyword">from</span> <span class="hljs-string">'./enhancers/monitorReducers'</span>;
<span class="hljs-keyword">import</span> loggerMiddleware <span class="hljs-keyword">from</span> <span class="hljs-string">'./middleware/logger'</span>;
<span class="hljs-keyword">import</span> rootReducer <span class="hljs-keyword">from</span> <span class="hljs-string">'./reducers'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">configureStore</span>(<span class="hljs-params">preloadedState</span>) </span>{
  <span class="hljs-keyword">const</span> middlewares = [loggerMiddleware, thunkMiddleware];
  <span class="hljs-keyword">const</span> middlewareEnhancer = applyMiddleware(...middlewares);

  <span class="hljs-keyword">const</span> enhancers = [middlewareEnhancer, monitorReducersEnhancer];
  <span class="hljs-keyword">const</span> composedEnhancers = composeWithDevTools(...enhancers);

  <span class="hljs-keyword">const</span> store = createStore(rootReducer, preloadedState, composedEnhancers);

  <span class="hljs-keyword">return</span> store;
}
</code></pre>
<p>There is a lot going on here, we are using redux-thunk, attaching the redux-devtools-extensions and a lot more. So, let's divide and conquer and separate the code above into four domains.</p>
<ol>
<li><strong>The <code>reducers</code></strong></li>
<li><strong>The <code>createStore</code> functions</strong></li>
<li><strong>The <code>enhancers</code></strong></li>
<li><strong>The <code>middlewares</code></strong></li>
</ol>
<h3 id="heading-first-rootreducer-the-maker-of-the-new-state">First: <code>rootReducer</code>, the maker of the new state</h3>
<p>The <code>rootReducer</code> function is the first of the three arguments that <code>createStore</code> takes and chances are you already know that redux <code>reducers</code> are functions that takes the current state and an action and return a new state. You might also already know that the <code>reducers</code> must be <strong>pure functions</strong>.
However, have you ever wondered <em>"why reducers have to be pure functions?"</em> 🤔. Well there is a very good reason, but unfortunately, there isn't a piece of code that I can point to and tell you <em>"if the is NOT pure function it will ALWAYS break"</em>. Yet the fact that <code>reducers</code> must be pure functions is at the heart of what Redux aim to be, and that is <strong>"a state store with predictable state mutation"</strong>. Redux, achieves that by adehering to three self-imposed principles:</p>
<ul>
<li>A Single source of truth</li>
<li>State is read-only</li>
<li>Changes to the state are made with pure functions</li>
</ul>
<p>If that didn't click immediately in your mind don't worry we will see those principles again in this article.</p>
<p>So, reducers are pure functions. They take the current state and an action as arguments and return a <strong>new state object</strong>, got it 👍. <em>But how about <code>combineReducers</code>, how does that magical function work</em>. Well <code>combineReducers</code> is an awesome utility function that help us keep our code modular, but really there is nothing magical about it. <code>combineReducers</code> is a high order function and all what it does is:</p>
<ul>
<li>Extract an array from the reducer object passed into it <em>(note that the reducer keys match the shape of the state tree)</em>.</li>
<li>Return a new <code>reducer</code> function.<ul>
<li>This function will make the next state by looping over the array of reducers keys and call the coresponding <code>reducer</code>.</li>
<li>Finally, it will return the next state.</li>
</ul>
</li>
</ul>
<p>Take a look at the trim down version of <code>combineReducers</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> reducers = {
  <span class="hljs-attr">someState</span>: reducerOfSomeState,
  <span class="hljs-attr">anotherState</span>: reducerOfAnotherState
};

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">combineReducers</span>(<span class="hljs-params">reducers</span>) </span>{
  <span class="hljs-keyword">const</span> reducerKeys = <span class="hljs-built_in">Object</span>.keys(reducers);

  <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">combinedReducer</span>(<span class="hljs-params">state = {}, action</span>) </span>{
    <span class="hljs-keyword">const</span> nextState = {};
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; reducerKeys.length; i++) {
      <span class="hljs-keyword">const</span> key = reducerKeys[i];
      <span class="hljs-keyword">const</span> reducer = reducers[key];
      <span class="hljs-keyword">const</span> previousStateForKey = state[key];
      <span class="hljs-keyword">const</span> nextStateForKey = reducer(previousStateForKey, action);

      nextState[key] = nextStateForKey;
    }
    <span class="hljs-keyword">return</span> nextState;
  };
}

<span class="hljs-keyword">const</span> rootReducer = combineReducers(reducers);
</code></pre>
<p>Finally, there is an important insight that you might already noticed by looking at <code>combineReducers</code>, which is, <strong>each time the <code>rootReducers</code> gets called all of the <code>reducers</code> in your app will be called</strong> to create the next state.</p>

<h3 id="heading-second-createstore-the-store-maker">Second: <code>createStore</code>, the store maker</h3>
<p>In it's simplest form <code>createStore</code> return a state object and few methods. However it also accepts extra arguments that <em>enhances</em> 😉 the store but more on that later. For now let's make sure we understand a simpler version of <code>createStore</code>.</p>
<p>We've already seen the <strong>three principles</strong> that redux is built on. Now, let's take another look at them and try building our own redux replica 🛠:</p>
<ul>
<li><strong>A Single source of truth</strong> ≈ we should have a single store object.</li>
<li><strong>State is read-only</strong> ≈ state object should not be mutated directly, instead changes should be described and emitted using a method. <em>(If don't understand how we got that from "state is read-only" then that's fair after all it's only four words. However, the <a target="_blank" href="https://redux.js.org/introduction/three-principles#state-is-read-only">docs</a> elaborate on the point and make the intention of the principle clear.)</em></li>
<li><strong>Changes are made with pure functions</strong> ≈ reducers have to be pure functions.</li>
</ul>
<p>Adhering to the principles above our Redux replica might look something like this:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// An action to initialize our state</span>
<span class="hljs-keyword">const</span> ActionTypes = {
  <span class="hljs-attr">INIT</span>: <span class="hljs-string">`@@redux/INIT<span class="hljs-subst">${<span class="hljs-built_in">Math</span>.random()
    .toString(<span class="hljs-number">36</span>)
    .substring(<span class="hljs-number">7</span>)}</span>`</span>
};

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createStore</span>(<span class="hljs-params">rootReducer, initialState</span>) </span>{
  <span class="hljs-keyword">let</span> currentState = initialState;

  <span class="hljs-keyword">const</span> dispatch = <span class="hljs-function"><span class="hljs-params">action</span> =&gt;</span> {
    currentState = rootReducer(action);
  };

  <span class="hljs-keyword">const</span> getState = <span class="hljs-function">() =&gt;</span> currentState;

  <span class="hljs-comment">// setting the initial state tree.</span>
  dispatch({ <span class="hljs-attr">type</span>: ActionTypes.INIT });
  <span class="hljs-keyword">return</span> {
    dispatch,
    getState
  };
}

<span class="hljs-keyword">const</span> myAwesomeStore = createStore(rootReducer, {});
</code></pre>
<p>Those few lines might not look like much, but they are equivalent to the core functionlites of Redux. Of course, Redux adds some checks to help developers avoid stupid mistakes like calling dispatch from inside a reducer or not calling <code>dispatch</code> with a plain object. Also our replica doesn't support <code>middleware</code> or <code>enhancers</code>, yet at least.</p>
<h3 id="heading-third-middlewares-the-ones-in-the-middle">Third: <code>middleWares</code>, the ones in the middle</h3>

<p>I knowwwwwwww 🤯,
Ok ok but seriously though, it's helpfully to think of them conceptually as a middleman between the <code>dispatcher</code> and the the <code>rootReducer</code>. <em>SPOILER ALERT: At the the Enhancer section we will see that it's a little bit more complected than that.</em>
Because actions go through middleware, there they can be changed, canceled or really anything else. There is a lot nuance in how to use middleware effectively, but in this article we will only focus on how they work inside Redux. So let's see that by examining what is probably the simplest middleware you will ever see.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> middledWare = <span class="hljs-function">(<span class="hljs-params">{ dispatch, getState }</span>) =&gt;</span> <span class="hljs-function"><span class="hljs-params">next</span> =&gt;</span> <span class="hljs-function"><span class="hljs-params">action</span> =&gt;</span> {
  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> action === <span class="hljs-string">'function'</span>) {
    <span class="hljs-keyword">return</span> action(dispatch, getState, extraArgument);
  }
  <span class="hljs-keyword">return</span> next(action);
};
</code></pre>
<p>If you are eyes skipped the first line and immediately went to the body of the final function you might have seen that the logic is straightforward. However, once your your eyes aim back at the first line, bells in your head should start ringing CURRYING. Also, If you feel at all confused by this, don't disheartened because you are not alone, In fact this questions is one of FAQs in the docs <a target="_blank" href="https://redux.js.org/faq/design-decisions#why-does-the-middleware-signature-use-currying">Why does the middleware signature use currying?</a>. In the <a class="post-section-overview" href="#fourth-raw-enhancers-endraw-augmenting-raw-createstore-endraw-">next section</a> we will see how this function signutre is being used by Redux inside <code>applyMiddleware</code>, for now just remember the following from the middleware signature above.</p>
<ol>
<li>the first function will get called with the an object that has two properties <code>dispatch</code> and <code>getState</code> (the middleWareApi).</li>
<li>The second function gets called with <code>next</code> (the next middleWare).</li>
<li>The final function <em>act as</em> a <code>dispatch</code> and it gets called with an action.</li>
</ol>
<p>FUN FACT 🤓: You might not have noticed it, but the code above is actully the <a target="_blank" href="https://github.com/reduxjs/redux-thunk/blob/master/src/index.js">source for redux-thunk.</a></p>
<h3 id="heading-fourth-enhancers-augmenting-createstore">Fourth: <code>enhancers</code>, Augmenting <code>createStore</code></h3>

<p>As you might have already guessed, <code>enhancers</code> are high order functions that take <code>createStore</code> and return a new <strong>enhanced</strong> version of <code>createStore</code>. Take a look a this sample implementation.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> ourAwesomeEnhancer = <span class="hljs-function"><span class="hljs-params">createStore</span> =&gt;</span> <span class="hljs-function">(<span class="hljs-params">reducer, initialState, enhancer</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> store = createStore(monitoredReducer, initialState, enhancer);
  <span class="hljs-comment">//  add enhancer logic</span>

  <span class="hljs-keyword">return</span> {
    ...store
    <span class="hljs-comment">//   you can override the some store properties or add new ones</span>
  };
};
</code></pre>
<p>While it's rare that you might need to craft your own <code>enhancers</code>, you are likely already using at least one, <code>applyMiddleware</code>. Oh Yes, this is might be shocking to some but <strong>the notion of <code>middlewares</code> is not in Redux <code>createStore</code></strong>. We add middlewares capabilities to our store by using the only <code>enhancer</code> that ships with Redux <code>applyMiddleware</code>.</p>
<p><em>To be specific the actually enhancer is the returned function from <code>applyMiddleware</code> but they are referenced interchangeably in the docs.</em></p>
<p>The <code>enhancer</code> function is first called from inside <code>createStore</code> and there isn't anything magical or overly complected. As you will soon see soon. However before we see the code, we need to address an urgent problem 🚧. Because <code>enhancers</code> take <code>createStore</code> and returned enhanced version of <code>createStore</code>, you can see how using those terms to explain the mechanics of the <code>enhancer</code> can get convoluted very quickly. As such for the purposes of this section I'm introducing what I dubbed as <strong>placeholders terms</strong>:</p>
<ul>
<li>The <strong>originalStoreMaker</strong>: the <code>createStore</code> function that you can import from Redux.</li>
<li>The <strong>storeMaker</strong>: any function that has the same signature as the <strong>original storeMaker</strong> (accepts the same arguments and return the same API).</li>
</ul>
<p>Alright then now let's see some code. Take a look at our Redux replica from above, now modified to accept <code>enhancer</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createStore</span>(<span class="hljs-params">rootReducer, initialState, enhancer</span>) </span>{
  <span class="hljs-keyword">let</span> currentState = initialState;

  <span class="hljs-comment">// Now accepts enhancers</span>
  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> enhancer !== <span class="hljs-string">'undefined'</span> &amp;&amp; <span class="hljs-keyword">typeof</span> enhancer === <span class="hljs-string">'function'</span>) {
    <span class="hljs-keyword">return</span> enhancer(createStore)(reducer, preloadedState);
  }

  <span class="hljs-keyword">const</span> dispatch = <span class="hljs-function"><span class="hljs-params">action</span> =&gt;</span> {
    currentState = rootReducer(action);
  };

  <span class="hljs-keyword">const</span> getState = <span class="hljs-function">() =&gt;</span> currentState;

  <span class="hljs-comment">// setting the initial state tree.</span>
  dispatch({ <span class="hljs-attr">type</span>: ActionTypes.INIT });
  <span class="hljs-keyword">return</span> {
    dispatch,
    getState
  };
}
</code></pre>

<p>As I said nothing magical. It's just function that takes a <strong>storeMaker</strong> and return an enhanced <strong>storeMaker</strong>. Of course that's not to say that <code>enhancer</code> can't be complex. It's to say that the complexity of an <code>enhancer</code> is encapsulated inside it and determined by what it try to achieve AND not by how it interact with a <strong>storeMaker</strong>. This subtle distinction is important as we in the rest of this section examine the implementation of the most widely used <code>enhancer</code> in Redux, <code>applyMiddleware</code>.</p>
<h4 id="heading-the-applymiddleware">The <code>applyMiddleWare</code></h4>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">applyMiddleware</span>(<span class="hljs-params">...middlewares</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-params">createStore</span> =&gt;</span> <span class="hljs-function">(<span class="hljs-params">...args</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> store = createStore(...args);
    <span class="hljs-keyword">let</span> dispatch = <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(
        <span class="hljs-string">'Dispatching while constructing your middleware is not allowed. '</span> +
          <span class="hljs-string">'Other middleware would not be applied to this dispatch.'</span>
      );
    };

    <span class="hljs-keyword">const</span> middlewareAPI = {
      <span class="hljs-attr">getState</span>: store.getState,
      <span class="hljs-attr">dispatch</span>: <span class="hljs-function">(<span class="hljs-params">...args</span>) =&gt;</span> dispatch(...args)
    };
    <span class="hljs-keyword">const</span> chain = middlewares.map(<span class="hljs-function"><span class="hljs-params">middleware</span> =&gt;</span> middleware(middlewareAPI));
    dispatch = compose(...chain)(store.dispatch);

    <span class="hljs-keyword">return</span> {
      ...store,
      dispatch
    };
  };
}
</code></pre>
<p>OK that was the whole thing now let's unpack it. Let's first quickly understand the curring part at the top. What we really need to know here is what arguments will those functions gets called with, luckily for us we already know that:</p>
<ul>
<li><code>applyMiddleware</code> takes <strong><code>middlewares</code></strong> return an <code>enhancer</code>.</li>
<li><code>enhancers</code> take a <strong>storeMaker</strong> and return an enhanced <strong>storeMaker</strong>.</li>
</ul>
<p>From that we can bring our focus back to the body of the final function and noting what it has in closure.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// In closure: [middlewares], createStore</span>

<span class="hljs-comment">// This final function is a storeMaker</span>
(...args) =&gt; {
  <span class="hljs-keyword">const</span> store = createStore(...args);
  <span class="hljs-keyword">let</span> dispatch = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(
      <span class="hljs-string">'Dispatching while constructing your middleware is not allowed. '</span> +
        <span class="hljs-string">'Other middleware would not be applied to this dispatch.'</span>
    );
  };

  <span class="hljs-keyword">const</span> middlewareAPI = {
    <span class="hljs-attr">getState</span>: store.getState,
    <span class="hljs-attr">dispatch</span>: <span class="hljs-function">(<span class="hljs-params">...args</span>) =&gt;</span> dispatch(...args)
  };
  <span class="hljs-keyword">const</span> chain = middlewares.map(<span class="hljs-function"><span class="hljs-params">middleware</span> =&gt;</span> middleware(middlewareAPI));
  dispatch = compose(...chain)(store.dispatch);

  <span class="hljs-keyword">return</span> {
    ...store,
    dispatch
  };
};
</code></pre>
<p>Much better, now Somewhere in the code this <strong>storeMaker</strong> will get called with <code>rootReducer</code> and <code>initialState</code>. Jumping inside the function, the first two lines create the store and assign a function to a variable named <code>dispatch</code>. As the error message say this is done to prevent developer from accidentally calling <code>dispach</code> inside a <strong>storeMaker</strong>.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// In closure: middlewares and the original createStore.</span>

<span class="hljs-comment">// + more code above</span>
<span class="hljs-keyword">const</span> store = createStore(...args);
<span class="hljs-keyword">let</span> dispatch = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(
    <span class="hljs-string">'Dispatching while constructing your middleware is not allowed. '</span> +
      <span class="hljs-string">'Other middleware would not be applied to this dispatch.'</span>
  );
};
<span class="hljs-comment">// + more code below</span>
</code></pre>
<p>Before looking at the second piece of code try to <strong>remember the signature of a <code>middleware</code> in Redux</strong> <a class="post-section-overview" href="#third-raw-middlewares-endraw-the-ones-in-the-middle">that we've seen before</a>. Here the first of those curried function of each <code>middleware</code> gets called. After this part of code we will get an array of functions where each has a reference in their closure to the <code>middleWareAPI</code> object.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// In closure: middlewares and the original createStore.</span>

<span class="hljs-comment">// + more code below</span>
<span class="hljs-keyword">const</span> middlewareAPI = {
  <span class="hljs-attr">getState</span>: store.getState,
  <span class="hljs-attr">dispatch</span>: <span class="hljs-function">(<span class="hljs-params">...args</span>) =&gt;</span> dispatch(...args)
};

<span class="hljs-keyword">const</span> chain = middlewares.map(<span class="hljs-function"><span class="hljs-params">middleware</span> =&gt;</span> middleware(middlewareAPI));
<span class="hljs-comment">// + more code below</span>
</code></pre>
<p>Brace yourself, the next line is probably the most intimidating part of the code. Largely because of the <code>compose</code> function. Nonetheless, give it a go 💪 and take this hint: <strong>all the functions in the <code>chain</code> variable return a function.</strong></p>
<pre><code class="lang-javascript"><span class="hljs-comment">// In closure: middlewares and the original createStore.</span>

<span class="hljs-comment">// + more code below</span>
dispatch = compose(...chain)(store.dispatch);
<span class="hljs-comment">// + more code below</span>
</code></pre>
<p>If you went through our Brochure of functional programming concepts, seeing the code above might rang few bells inside your head. Because this code look very similar to the code from the BONUS ROUND in the <a class="post-section-overview" href="#function-composition">function composition sub-section</a>. Speaking of which, what did you guess the code from there will log?....</p>
<p>well let's have another look.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> myFuncs = [
  <span class="hljs-function"><span class="hljs-params">func</span> =&gt;</span> <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-number">1</span>);
    func();
  },
  <span class="hljs-function"><span class="hljs-params">func</span> =&gt;</span> <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-number">2</span>);
    func();
  },
  <span class="hljs-function"><span class="hljs-params">func</span> =&gt;</span> <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-number">3</span>);
    func();
  },
  <span class="hljs-function"><span class="hljs-params">func</span> =&gt;</span> <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-number">4</span>);
    func();
  }
];

<span class="hljs-keyword">const</span> hakuna = <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Mattata'</span>);

<span class="hljs-keyword">const</span> secret = compose(myFuncs)(hakuna);

secret(); <span class="hljs-comment">// 1, 2, 3, 4, Matata</span>
</code></pre>
<p>Yes, if you tried to run the code in the console, you've seen that it logs <em>1, 2, 3, 4, Matata</em>. The code seems to have ran left-to-right. Except after the returned function from <code>compose</code> gets called with <code>hakuan</code>, we don't have an array anymore!. Where is the left-to-right coming from?? It's because of Closures and callbacks. Ok I'm guessing that wasn't super helpful 😅. No worries though, I'll try to explain a little better but first to avoid confusion, I'm going to need once again to introduce new <strong>placeholders terms</strong>.</p>
<ul>
<li><strong>level1Func</strong>: any function inside the <code>myFuncs</code> array.</li>
<li><strong>level2Func</strong>: any function that is returned by a <strong>level1Func</strong>.</li>
</ul>
<p>Alright, let's recap what is it that we want to achieve. We want somehow for all of <strong>level2Func</strong> to run in order from left-to-right. We can see in the array that each <strong>level1Func</strong> takes a callback as an argument and then that callback gets called inside it's <strong>level2Func</strong>. So it's seems that we can achieve our goal if somehow each <strong>level1Func</strong> got called with the <strong>next</strong> <strong>level2Func</strong>.</p>
<p>OK Ok gears are turning ⚙⚙ we are closing into something. We know by now that compose will return a function that will call functions right-to-left and passing each return to the previous function in the array. But god it's too hard running that code inside my mind 😵. Maybe if we saw how that would look like differently.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> composed = <span class="hljs-function">(<span class="hljs-params">...args</span>) =&gt;</span> func1(func2(func3(func4(...args))));
</code></pre>
<p>AHA!, As <code>composed</code> gets called and the functions gets called right-to-left, each <strong>level1func</strong> will be called by the <strong>next</strong> <strong>level2func</strong>. Well done You got it 👏. That is exactly how we end-up with a function that resemble a chain in how it runs left-to-right. The last thing to point out and hammer home is that <code>hakuna</code> function is the first argument that gets passed by composed and as such <strong>it's the last function in the chain</strong></p>
<p>Now with this new found understanding let's look back at the line code from <code>applyMiddleware</code>. I hope you can see by now how the chain is made, that each middleWare will calls the <strong>next</strong> one and that the last function in the chain is <code>store.dispatch</code> which sets the new state (but NOT create it) to the store.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// In closure: middlewares and the original createStore.</span>

<span class="hljs-comment">// + more code below</span>
dispatch = compose(...chain)(store.dispatch);
<span class="hljs-comment">// + more code below</span>
</code></pre>

<p>Finally, because this is after all a <strong>storeMaker</strong> function we return the store and of course override the <code>dispach</code> property.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">return</span> {
  ...store,
  dispatch
};
</code></pre>



<h2 id="heading-the-gift-shop">The Gift shop</h2>
<p>The above is everything about how the core of Redux works. There are few more methods that ships with Redux and while they will not alter your understanding of how Redux works, they are worth mentioning. Here is a quick list.</p>
<ul>
<li><strong>replaceReducer</strong>: Give you the ability replace the rootReducer of the store. Interestingly in some setups you can use it to add new reducers rather than just replacing the whole <code>rootReducer</code>.</li>
<li><strong>subscribe</strong>: Give you the ablity to pass a callback that will get called after any action gets dispatched.</li>
<li><strong>observable</strong>: Can be used in libraries like RxJS. Also allowes you to subscribe to changes.</li>
</ul>
<p>Congratulation you made it 🎊🎊👏👏. Now you understand how Redux works under the hood and hopefully have gained an appreciation for the power functional programming.</p>
]]></content:encoded></item></channel></rss>