<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Julien Calixte</title>
    <description>The latest articles on DEV Community by Julien Calixte (@jcalixte).</description>
    <link>https://dev.to/jcalixte</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F236%2Fb6af9eae-e440-48d0-bce1-5aaf9c647284.png</url>
      <title>DEV Community: Julien Calixte</title>
      <link>https://dev.to/jcalixte</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jcalixte"/>
    <language>en</language>
    <item>
      <title>Just in time documentation is the right documentation</title>
      <dc:creator>Julien Calixte</dc:creator>
      <pubDate>Mon, 29 May 2023 06:10:00 +0000</pubDate>
      <link>https://dev.to/jcalixte/just-in-time-documentation-is-the-right-documentation-30ma</link>
      <guid>https://dev.to/jcalixte/just-in-time-documentation-is-the-right-documentation-30ma</guid>
      <description>&lt;h2&gt;
  
  
  Falling over the same trap again and again
&lt;/h2&gt;

&lt;p&gt;Many times a problem occurs where new developers fall over the same trap again and again despite the fact that the solution has been well documented. How can it be their fault? They didn't even know the documentation existed!&lt;/p&gt;

&lt;p&gt;The eternal question of "do we write documentation for our project?"... But if no one read it when it needs to, the documentation becomes waste.&lt;/p&gt;

&lt;h2&gt;
  
  
  Just in time
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Just in time&lt;/em&gt; (&lt;code&gt;jit&lt;/code&gt;) is a lean concept: the goal for a team is to produce the right amount of value when the client needs it. No less no more.&lt;/p&gt;

&lt;p&gt;So I created a VS Code extension doing exactly that: &lt;a href="https://marketplace.visualstudio.com/items?itemName=jcalixte.doc-jit"&gt;doc-jit&lt;/a&gt;. It provides the right amount of knowledge the exact moment the developper needs it: &lt;em&gt;just in time documentation&lt;/em&gt;. 🤎&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;You set glob patterns that is affiliated with a documentation file and &lt;a href="https://marketplace.visualstudio.com/items?itemName=jcalixte.doc-jit"&gt;doc-jit&lt;/a&gt; will propose you when your active file matches at least one of them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json-doc"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .doc-jitrc.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"patterns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"**/*.test.ts, **/*.test.tsx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jest documentation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"uri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://jestjs.io/docs/getting-started"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Vitest documentation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"uri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://vitest.dev/guide/"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"**/*.test.tsx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"React Native testing library documentation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"uri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://callstack.github.io/react-native-testing-library/docs/getting-started"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In real life, it looks like this:&lt;/p&gt;


  
  


&lt;p&gt;It's that simple and you can start with ease. For example, just your dependencies first, it's surprisingly powerful. Then add your own documentation, standards, tutorial, videos, etc. One problem solving at a time. Just in time. 😊&lt;/p&gt;

</description>
      <category>documentation</category>
      <category>standard</category>
      <category>vscode</category>
      <category>extensions</category>
    </item>
    <item>
      <title>Developers, make your environment loopy 🔁</title>
      <dc:creator>Julien Calixte</dc:creator>
      <pubDate>Sun, 13 Mar 2022 18:37:17 +0000</pubDate>
      <link>https://dev.to/jcalixte/developers-make-your-environment-loopy-37bg</link>
      <guid>https://dev.to/jcalixte/developers-make-your-environment-loopy-37bg</guid>
      <description>&lt;p&gt;When we work, we want feedback: do we do the expected job? Does it fail? Where does it fail? Therefore, we want to receive feedback loops from our environment that gives us useful information about how well we're doing. This is what &lt;em&gt;loopy&lt;/em&gt; means.&lt;/p&gt;

&lt;p&gt;Hi! My name is Julien and I'm a tech leader at &lt;a href="https://www.bam.tech/bam-agence-experte-design-et-d%C3%A9veloppement-mobile"&gt;BAM&lt;/a&gt; where we design and develop mobile apps. A part of my job is to provide a healthy environment for my fellow developers to work at their best, improve quicker and then become tech leaders themselves.&lt;/p&gt;

&lt;p&gt;In a dynamic system we want to adapt from visible inputs to concrete actions. And to do that, we need standards.&lt;/p&gt;

&lt;h2&gt;
  
  
  It starts with standards
&lt;/h2&gt;

&lt;p&gt;Standards are established rules in the team. They are our best guess about what a good job is. Writing and comparing with real life allow us to distinguish what is normal from what is not.&lt;/p&gt;

&lt;p&gt;Some tips when writing down a standard, make sure you have:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;why it's important to write it down,&lt;/li&gt;
&lt;li&gt;what are its key points,&lt;/li&gt;
&lt;li&gt;what are the common mistakes we can avoid in the first place,&lt;/li&gt;
&lt;li&gt;and what are the concrete examples to better understand it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With these key points in place, we'll be able to compare with the real world and adapt. In a nutshell, to be loopy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loopy code
&lt;/h2&gt;

&lt;p&gt;Once we agree as a team to use a set of standards, we want our tools to know them. Take linters in your code for instance. Linters are scripts that find and sometimes can even fix problems automatically. They are great to provide warnings when a developer diverges from the expected code. It saves time on training, on reviewing and on debugging.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WZDnN1r7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ssfn63tamuaxusylg5rc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WZDnN1r7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ssfn63tamuaxusylg5rc.png" alt="Image description" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The more we use a tool, the more reliant we want it to be. If in the previous paragraph you thought “Well, in my project linters are a pain in the butt, I hate how they force me to do additional work!”; this is a clear hint you are working for your tools and not the other way around. We don't want this. We want computers to execute repetitive tasks and humans to solve problems. So gather your team and update your linter rules so nobody complains. 🤔&lt;/p&gt;

&lt;h2&gt;
  
  
  Loopy tests
&lt;/h2&gt;

&lt;p&gt;Talking about tests. If you want to rush, don't write tests. If you want to go fast and go far, write tests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IGl14i2r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijjbysabl79j3y1hu5aq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IGl14i2r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijjbysabl79j3y1hu5aq.png" alt="Image description" width="474" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mental loads are real and a heavy burden. When we start automating tests of some of our code, we can discharge that cognitive load. This will lead to a freer mind and easier and more effective days.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loopy production flow
&lt;/h2&gt;

&lt;p&gt;I wrote &lt;a href="https://dev.to/jcalixte/how-does-visual-management-improve-team-efficiency-4kgd"&gt;an article&lt;/a&gt; about how useful it is to see the steps in the production flow. By showing the production flow, we know where we are and how good we are. We can then adapt our work/prioritization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mg6kTJP2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ywgpssrfv7oxeqa0s7fz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mg6kTJP2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ywgpssrfv7oxeqa0s7fz.png" alt="Image description" width="800" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We then can spot and identify problems and solve them - they are called “red bins” in lean production. Displaying the problems in front of the whole team helps to highlight how they are slowing the whole process down. That way they can't be ignored and actions must be taken.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6Nc1df4E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d6w9oj12cxsr3n19z08r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6Nc1df4E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d6w9oj12cxsr3n19z08r.png" alt="Image description" width="800" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vFs1qkz0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82ao3k9i4zhq5py6vufq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vFs1qkz0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82ao3k9i4zhq5py6vufq.png" alt="Image description" width="474" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Loopy user satisfaction
&lt;/h2&gt;

&lt;p&gt;The better we understand user needs, the clever we can work. There is no shame about being wrong in the first place. The most important thing is to acknowledge and adapt.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gAQGxV5I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/30uudql0ytaocdm5g8hc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gAQGxV5I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/30uudql0ytaocdm5g8hc.png" alt="Image description" width="474" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Make your tools work for you not against you
&lt;/h2&gt;

&lt;p&gt;We tend to believe that a part of our job is to use specific tools and deal with its disadvantages because "we're used to it and it's always been that way". We tell ourselves: this is my job and if I fail, it'll be on me. Of course it's a bit more complex than that. In our day to day work, we all make mistakes: these ‘human errors’ are not a cause but a symptom of a deeper problem in your system. Understanding how and what causes a ‘human error’ to arise is the beginning of understanding a little bit about a complex system. And in an overly complex system, being able to adapt with feedback loops is better than being able to predict.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shorten the loops
&lt;/h2&gt;

&lt;p&gt;Your time is valuable, your focus is valuable, this is all about you and enhancing your work. The quicker you get feedback, the faster you can adapt. And the more feedback you get the more you work smarter.&lt;/p&gt;

&lt;center&gt;
*We shape our tools then the tools shape us.*
&lt;/center&gt;




&lt;p&gt;This article was inspired by the &lt;a href="https://ncase.me/loopy"&gt;Loopy tool&lt;/a&gt; from &lt;a href="https://ncase.me"&gt;Nicky Case&lt;/a&gt;, I can only suggest you take a look!&lt;/p&gt;

</description>
      <category>feedback</category>
      <category>loops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Introduction to smart notes: how to take notes efficiently</title>
      <dc:creator>Julien Calixte</dc:creator>
      <pubDate>Thu, 16 Dec 2021 22:48:45 +0000</pubDate>
      <link>https://dev.to/jcalixte/introduction-to-smart-notes-how-to-take-notes-efficiently-188b</link>
      <guid>https://dev.to/jcalixte/introduction-to-smart-notes-how-to-take-notes-efficiently-188b</guid>
      <description>&lt;p&gt;If you are like me, then you've always struggled to take meaningful notes and usually give up on writing anything down. Still, deep down, you're looking for a way to write efficiently.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why do you still have to write notes?
&lt;/h1&gt;

&lt;p&gt;How frustrating is it to read a book or get a new idea during a meeting, and a few days later realize you already forgot about it? You are not alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our brains are not reliable
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The limits of our short-term memory
&lt;/h3&gt;

&lt;p&gt;Learning new things could be summarized as the process of linking items that are in our short-term memory to our long-term memory, by far more efficient and reliable. Short-term memory is really convenient to retrieve information quickly. Unfortunately, our short-term memory is extremely limited: it's quickly crowded—&lt;a href="https://www.cambridge.org/core/journals/behavioral-and-brain-sciences/article/magical-number-4-in-shortterm-memory-a-reconsideration-of-mental-storage-capacity/44023F1147D4A1D44BDC0AD226838496" rel="noopener noreferrer"&gt;4 (± 1) blocks of information at a time&lt;/a&gt;—and very short-lived. It isn’t suitable for complex reflection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2g5gf0cspgd1mvkxaskm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2g5gf0cspgd1mvkxaskm.png" alt="short-term and long-term memories"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make it even worse, the following curve shows how information is quickly lost over time when there is no attempt to retain it. That’s why we tend to retrieve so little information from a book read months ago. It's called the forgetting curve.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd02a5yl5c20g8aat7rgk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd02a5yl5c20g8aat7rgk.png" alt="the forgetting curve"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a nutshell, our brain is limited and quickly forgets the information it's been exposed to.&lt;/p&gt;

&lt;h3&gt;
  
  
  Our cognitive biases
&lt;/h3&gt;

&lt;p&gt;Besides memory, brains aren't reliable because of many cognitive biases: confirmation bias, attentional bias, mere-exposure effect, normalcy bias, you name it. Even if it's the most complex system in our body, our brain must face many obstacles in order to not fool itself. For instance, more often than necessary, we look for arguments that unconsciously reinforce our original thoughts, we tend to argue with a pre-existing belief. This is what Julia Galef calls the “soldier mindset” in “&lt;a href="https://juliagalef.com" rel="noopener noreferrer"&gt;The Scout Mindset&lt;/a&gt;”. She opposes it to the scout mindset: a mindset in which the search for the truth is what primarily guides its reasoning.&lt;/p&gt;

&lt;p&gt;As the scout's goal is to draw the most accurate map in the battlefield, taking notes becomes the map for your thoughts: they tell you what you know, what you don't know and guide you through your reflection.&lt;/p&gt;

&lt;h1&gt;
  
  
  The concept of &lt;em&gt;smart notes&lt;/em&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Where do smart notes come from?
&lt;/h2&gt;

&lt;p&gt;Smart notes is a term used in the book “&lt;a href="https://takesmartnotes.com" rel="noopener noreferrer"&gt;How To Take Smart Notes&lt;/a&gt;” written by Sönke Ahrens that tells the story of Niklas Luhmann, a sociologist who has published hundreds of articles thanks to his note-taking system: &lt;a href="https://zettelkasten.de/posts/overview" rel="noopener noreferrer"&gt;the Zettelkasten method&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the system
&lt;/h2&gt;

&lt;p&gt;Taking notes tends to mean “jotting down ideas on paper during meetings”. But we rarely use them afterwards. Notes used once or twice are no good, we can’t take advantage of them. Note-taking without structure is pointless. That’s why we have to create a system where each note helps the system snowball effect.&lt;/p&gt;

&lt;p&gt;We want a network of permanent notes. The goal is to write permanent notes and to densely connect them together. But to create notes you're proud of, you must iterate a few times with other kinds of notes. Overall, we can look at 3 kinds of notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fleeting notes,&lt;/li&gt;
&lt;li&gt;literature notes,&lt;/li&gt;
&lt;li&gt;permanent notes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fleeting notes
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Fleeting notes&lt;/em&gt; are your day-to-day notes. When an idea pops into your head or you find an idea interesting in a meeting, you want to write it to free your mental load. They are primarily the pool of new concepts.&lt;/p&gt;

&lt;p&gt;Then comes the refinement of the notes. For this, you need to instigate a routine: clearing and deleting non-relevant paragraphs, extracting the ideas into concise notes. This routine is key to accumulate knowledge.&lt;/p&gt;

&lt;p&gt;I suggest getting a note per day and starting the routine at a small scale: create a fleeting note each day but refine them only once a week.&lt;/p&gt;

&lt;h3&gt;
  
  
  Literature notes
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Literature notes&lt;/em&gt; are the notes you take on the fly when you are reading a book, a blog post or listening to a podcast. With a pen and a paper next to you, you write with your own words your understanding of the read. The key feature here is that we want a much more active lecture and information consumption than just passive reading/listening. It may seem hard at first but once you incorporate this new habit, you feel almost disappointed reading without extracting what seems compelling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Permanent notes
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Permanent notes&lt;/em&gt; are atomic and connected. A permanent note is about one and only one concept, as simple as possible and connected with others. They come from the selected thoughts chosen from your fleeting and literature notes. They are the backbone of the system so you want to be extremely selective about what will become a good durable note.&lt;/p&gt;

&lt;p&gt;When creating a permanent note, scan your previous notes and find connections with the new one. It’s the rule: the only way a permanent note can integrate the system is from connections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improve yourself step by step
&lt;/h2&gt;

&lt;p&gt;We want the system to work like our brain: simple ideas linked together as a network of thoughts. We want to start small, one note at a time.&lt;/p&gt;

&lt;p&gt;Your notes don't need to be perfect straight away, in fact, they will never be. Because writing is hard.&lt;/p&gt;

&lt;p&gt;Actually, writing is a multiple-tasking process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;writing ideas on the go,&lt;/li&gt;
&lt;li&gt;extracting relevant information,&lt;/li&gt;
&lt;li&gt;criticizing,&lt;/li&gt;
&lt;li&gt;making the writing shorter and the concept clearer,&lt;/li&gt;
&lt;li&gt;rewriting and rewriting again…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We want to separate these different tasks as much as possible because they can inhibit each other. When you write, don’t be afraid of being weird or dumb, there will be a time for self-critic. For now just write as if  you were teaching it to your younger self.&lt;/p&gt;

&lt;p&gt;It might feel uncomfortable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FT3W3kwKhU1lHsTouBixHVWog1DPju6HMaPp_UrSvA6jgWh_Cuii1I-cYbajvYu_DNf4ZLOH0ZRygyhd1x87u8blVhFD9JtSa3IcF3_7zUAcbrjBHElEnPzSQG5XBqH1KcJdfFAMS" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FT3W3kwKhU1lHsTouBixHVWog1DPju6HMaPp_UrSvA6jgWh_Cuii1I-cYbajvYu_DNf4ZLOH0ZRygyhd1x87u8blVhFD9JtSa3IcF3_7zUAcbrjBHElEnPzSQG5XBqH1KcJdfFAMS" alt="Is it me or is a 10 year old child writing this?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“Is it me or is a 10 year old child writing this?”. Still the more you iterate, the better your notes become, I promise. 😊&lt;/p&gt;

&lt;h2&gt;
  
  
  Smart notes are your first feedback loop
&lt;/h2&gt;

&lt;p&gt;This is where it gets exciting. Since you know you will be able to review your notes by yourself, you become better and better at writing and therefore your way of thinking. Notes are the medium between your past, present and future self. Plus, if you become comfortable with your own critique, you'll find yourself accepting even more the challenges of others as you simply want to improve your system.&lt;/p&gt;

&lt;h2&gt;
  
  
  How smart notes benefit me
&lt;/h2&gt;

&lt;p&gt;I’ve been using this system for the past year and so far it works!&lt;/p&gt;

&lt;p&gt;Here is a non-exhaustive list of things I like about it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📝 I can write a blog post—like this one–just by picking ideas from my own notes: no more blank page syndrome,&lt;/li&gt;
&lt;li&gt;🧠 trusting one and only one system allows the brain to truly free itself from mental load: you know you can go back to your thoughts and ideas later,&lt;/li&gt;
&lt;li&gt;🕸 making connections between work, hobbies and entertainment create new ideas in a way I didn't expect, I feel more creative!&lt;/li&gt;
&lt;li&gt;📈 as I said earlier, I’m much more incline to face challenges from other people and ask colleagues how I can improve my work,&lt;/li&gt;
&lt;li&gt;🪴 watching your network grow is rewarding! It’s like taking care of your own little garden.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As great as it is, I want to warn you about a few pitfalls into which you could be tempted to fall:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://zettelkasten.de/posts/collectors-fallacy" rel="noopener noreferrer"&gt;collecting&lt;/a&gt; only for the sake of collecting isn’t helpful. &lt;a href="https://observer.com/2017/05/the-collectors-fallacy-why-we-gather-things-we-dont-need" rel="noopener noreferrer"&gt;We don’t need it.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;creating a system per project: we lose the essence of the system; we want to be able to connect notes that don't seem connected at first sight.&lt;/li&gt;
&lt;li&gt;thinking too much of the tree structure for your notes in your taking note app: it is not that important, we just want to look for notes easily,&lt;/li&gt;
&lt;li&gt;copying and pasting what we find on the internet: link the page you want to reference but if the notes are not your own, the system becomes irrelevant (and I quote &lt;a href="https://youtu.be/wf2VxeIm1no?t=493" rel="noopener noreferrer"&gt;CGP Grey&lt;/a&gt;: &lt;em&gt;"If your mind is forever filled with the voice of others, how do you know what you think about anything?"&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With all this in mind, I made &lt;a href="https://litenote.space/lite-note/example" rel="noopener noreferrer"&gt;a personal slip-box&lt;/a&gt; I'll be completing over time to let you explore concrete examples!&lt;/p&gt;

&lt;h1&gt;
  
  
  Introducing smart notes for others
&lt;/h1&gt;

&lt;p&gt;I’m currently wondering if there are other potential applications to the Zettelkasten method other than using it ourselves. At BAM, I work as a team leader and I constantly ask myself how we can improve our way of communication through time in projects. Just like &lt;a href="https://dev.to/jcalixte/how-does-visual-management-improve-team-efficiency-4kgd"&gt;visual management&lt;/a&gt;, good documentation is essential for a project to succeed. Having clear standards connected to more detailed concepts is the ultimate documentation! But I haven’t fully experienced it yet. What do you think? Let me know in the comments or you can reach me on Twitter &lt;a href="https://twitter.com/julien_calixte" rel="noopener noreferrer"&gt;@julien_calixte&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>smartnotes</category>
      <category>thinking</category>
      <category>productivity</category>
      <category>writing</category>
    </item>
    <item>
      <title>How does visual management improve team efficiency?</title>
      <dc:creator>Julien Calixte</dc:creator>
      <pubDate>Wed, 29 Sep 2021 16:51:53 +0000</pubDate>
      <link>https://dev.to/jcalixte/how-does-visual-management-improve-team-efficiency-4kgd</link>
      <guid>https://dev.to/jcalixte/how-does-visual-management-improve-team-efficiency-4kgd</guid>
      <description>&lt;p&gt;When I started my career as a developer 8 years ago I struggled to have a global view and see the big picture in my missions. I developed many projects and sometimes reverted my work depending on what I was asked for. &lt;br&gt;
It was frustrating and counterproductive. Discovering Visual Management has been a game changer in my career.&lt;/p&gt;

&lt;p&gt;We'll see together how visual management can drastically help a team to get a clearer vision, to be more aware of improvements and accountable for the project’s main goals. We will be focused in the production flow that is a tiny part of &lt;em&gt;Visual Management&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Visual management tries to solve ambiguity
&lt;/h2&gt;

&lt;p&gt;Hi, my name is Julien. I'm a manager at BAM and my goal is to bring the team to succeed in every challenge and mission. And that’s not an easy job! At BAM, we are able to simplify the task through what we call Visual Management.&lt;/p&gt;

&lt;p&gt;Let me clarify the problem we want to solve: how can we onboard people, have a common vision and share as much information as possible within the team to make better decisions?&lt;/p&gt;

&lt;p&gt;This is a really ambitious goal. The good news is every step going forward is a small improvement in team comprehension about the product and how the product is made. In order to achieve that we divide it in two main steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Show your flow&lt;/li&gt;
&lt;li&gt;Show your challenges&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  First step: start with the flow
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Draw the steps
&lt;/h3&gt;

&lt;p&gt;Let's say you are developing a product. This product has a set of features. "Show your flow" means displaying everything a feature needs to achieve before ending in the users' hands. So how does the team achieve that goal?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Name the steps,&lt;/li&gt;
&lt;li&gt;make a list of the prerequisites to complete these steps,&lt;/li&gt;
&lt;li&gt;define the output required in each step,&lt;/li&gt;
&lt;li&gt;clarify who needs to complete these steps.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You may need some good tips:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;start from the end,&lt;/li&gt;
&lt;li&gt;prerequisites and outputs should be understood by every one,&lt;/li&gt;
&lt;li&gt;set up the process for a specific feature, then find a more generic flow,&lt;/li&gt;
&lt;li&gt;set up detailed and specific steps into place even if few features need them,&lt;/li&gt;
&lt;li&gt;go as far as you can to define the outputs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are many tools you can use as a board: Miro, Notion, Trello, Fibery, use whichever fits you. Here is an example of what it can look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lg03VmVc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/50s4u78txvha849u07zg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lg03VmVc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/50s4u78txvha849u07zg.png" alt="Visual Management with Kanban" width="800" height="244"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;This is a board of how you develop an app at BAM but it can be done in every profession.&lt;/p&gt;

&lt;p&gt;The board allows you to show the progress of every feature and how close they are to being done. On the one hand it helps clarify the process with your team too and on the other hand it challenges your decisions as a team leader – “why do you start a new feature if we haven’t finished this one yet?”. Trust me, you would be surprised by how much people's thinking process diverges.&lt;/p&gt;

&lt;p&gt;Be as specific as possible, this is not about how your team works but how the product is made. If the product depends on another team, add this information as a step and define what you expect from them. We want to see each team working on the product as blackboxes with inputs and outputs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consolidate and simplify your visual management
&lt;/h3&gt;

&lt;p&gt;Make sure the inputs and outputs are feasible and that every step can be done without going backwards in the process. Then look for simplification: are we able to remove steps? Can we postpone some of them? Are all the team members attending meetings and are those sufficient? Are we able to know if all the prerequisites are outputs from previous steps?&lt;/p&gt;

&lt;p&gt;Then on a daily basis, the team updates the feature status and sets up rules on how to prioritize tasks: pull system, minimum or maximum stock for each step, etc. These rules are your North star and help your daily decision making.&lt;/p&gt;

&lt;p&gt;This is why it is called visual management. It helps you manage a project as it shows you the next thing to do according to your set rules. This is really powerful: the decision process shifts from one manager to a whole team using the information at its disposal to make the best possible decision. And because information is so crucial to making a decision, we can come up with a new project standard: “every shared idea must be written down and available to everyone”.&lt;/p&gt;

&lt;p&gt;Once you are able to create a board with daily updates the real power of visual management is to be able to improve the efficiency of the team which will require you to implement the following mandatory step.&lt;/p&gt;

&lt;h2&gt;
  
  
  The key in visual management is to show problems
&lt;/h2&gt;

&lt;p&gt;Visual management will help you with efficiency  as it will highlight the struggles of your team in the development of a product. There are multiple kinds of problems the team will face and wants to address: steps taking too long, rework, too many features stuck in a particular step, waiting for another team to complete their tasks.&lt;/p&gt;

&lt;p&gt;However, to be able to solve problems, we first need to acknowledge them and see them. Let’s take a look at rework.&lt;/p&gt;

&lt;p&gt;Add a line in your flow called “red bins”. Every time you need to go back to complete a task, create a red bin mentioning the problem and the reason why you need to go back. Red bins are waste that can be prevented in the future if the team solves the root cause of the problem and learns from them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dSxMH7iz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8xb1rhyi9gzyispwzaak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dSxMH7iz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8xb1rhyi9gzyispwzaak.png" alt="Red bins in Kanban" width="800" height="321"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Red bins will start to stack in particular steps. After a while, it will become clear which columns the team needs to focus on. Find out what can be improved and check if red bins are still occuring for similar reasons.&lt;/p&gt;

&lt;h2&gt;
  
  
  Visual management really shines in the long run
&lt;/h2&gt;

&lt;p&gt;Achieving a clear visual process of your work will take some time. The path may not be completely obvious yet but knowing where the improvement lies is the first step to dive into it, transform your entire work dynamic and give you a clear and common vision.&lt;/p&gt;

&lt;p&gt;The more a team is autonomous and proactive on what action to take next, the more the manager's role evolves. He or she takes on a support role in the team, improving and solving problems along the way.&lt;/p&gt;

&lt;p&gt;Again, we've seen here only how we can visualize our production flow, but visual management is much more: detecting defects, lead times, touch times, standards, red bins, blue bins, etc.&lt;/p&gt;

&lt;p&gt;Finally, visual management is like a map you update every day: it guides you through what you know and what you don't know yet. Having red bins is expected and this is OK, what matters most is that you stick on a continuous improving path!&lt;/p&gt;

</description>
      <category>lean</category>
      <category>visualmanagement</category>
    </item>
    <item>
      <title>Are people ready for PWA?</title>
      <dc:creator>Julien Calixte</dc:creator>
      <pubDate>Thu, 28 May 2020 21:13:31 +0000</pubDate>
      <link>https://dev.to/jcalixte/are-people-ready-for-pwa-4dg</link>
      <guid>https://dev.to/jcalixte/are-people-ready-for-pwa-4dg</guid>
      <description>&lt;p&gt;Hi!&lt;/p&gt;

&lt;p&gt;Do you think people are ready to use a product that is only accessible with a PWA?&lt;/p&gt;

&lt;p&gt;People are now trained to search on stores and install the app even when there is a website, only the app is the real product.&lt;/p&gt;

&lt;p&gt;In other words, do you think a product can be profitable with a Progressive Web App only? Or definitely needs a native or desktop apps...&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>pwa</category>
    </item>
    <item>
      <title>Easy Web Worker integration in VueJS</title>
      <dc:creator>Julien Calixte</dc:creator>
      <pubDate>Fri, 17 Apr 2020 15:26:35 +0000</pubDate>
      <link>https://dev.to/jcalixte/easy-web-worker-integration-in-vuejs-3ej8</link>
      <guid>https://dev.to/jcalixte/easy-web-worker-integration-in-vuejs-3ej8</guid>
      <description>&lt;h1&gt;
  
  
  The main thread
&lt;/h1&gt;

&lt;p&gt;Web workers are super handy to make heavy computation and not blocking the main thread. So the user doesn't have his webpage blocked by too much JavaScript working behind.&lt;/p&gt;

&lt;h1&gt;
  
  
  Example in VueJS
&lt;/h1&gt;

&lt;p&gt;We can see how to use them easily in VueJS. Start by installing comlink-loader. Wait, what is Comlink? And comlink-loader?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/GoogleChromeLabs/comlink"&gt;Comlink&lt;/a&gt; is a library that simplify the way we call web workers, it will be as simple as calling an async function in our code. This lib was created by &lt;a href="https://github.com/surma"&gt;Surma&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/GoogleChromeLabs/comlink-loader"&gt;comlink-loader&lt;/a&gt; is simply the webpack loader that we will use to tranform files &lt;code&gt;*.worker.js&lt;/code&gt; into web workers.&lt;/p&gt;

&lt;p&gt;So here we go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; comlink-loader
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, here's the trick to add the loader in your vuejs configuration. It is explained &lt;a href="https://cli.vuejs.org/guide/webpack.html#simple-configuration"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;configureWebpack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;worker&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;js$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comlink-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rules&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally we can use it this way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a file that ends with &lt;code&gt;.worker.js&lt;/code&gt; and export async functions,
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// utils.worker.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;helloWorld&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// heavy computing goes here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Import them in vue files.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;helloWorld&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../workers/utils.worker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HelloWorld&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;mounted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;helloWorld&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember, it will always be async methods, so make sure to await them.&lt;/p&gt;

&lt;p&gt;Set and done!&lt;/p&gt;

&lt;p&gt;You can have a look at the quick example I've made to illustrate how web workers can impact user experience here: &lt;a href="https://vue-worker-example.netlify.app"&gt;vue-worker-example.netlify.app&lt;/a&gt;. See if the button is clickable when the page is computing with and without background tasks.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>vue</category>
      <category>webworker</category>
      <category>mainthread</category>
    </item>
    <item>
      <title>Live sync in React Native with CouchDb</title>
      <dc:creator>Julien Calixte</dc:creator>
      <pubDate>Thu, 16 Jan 2020 16:56:45 +0000</pubDate>
      <link>https://dev.to/jcalixte/live-sync-in-react-native-with-couchdb-59i2</link>
      <guid>https://dev.to/jcalixte/live-sync-in-react-native-with-couchdb-59i2</guid>
      <description>&lt;p&gt;&lt;em&gt;This post was originally published at &lt;a href="https://blog.bam.tech/developer-news/live-sync-in-react-native-with-couchdb" rel="noopener noreferrer"&gt;bam blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Live sync in React Native with CouchDb
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;In this tutorial I will show you how to create a live game with data updating on multiple devices.&lt;/p&gt;

&lt;p&gt;Let's start with something fun and basic! A game in which two people will be able to play together online. Let's make a live &lt;code&gt;Rock - Paper - Scissors&lt;/code&gt; game. I've already programmed it &lt;a href="https://github.com/jcalixte/rnrps" rel="noopener noreferrer"&gt;here&lt;/a&gt; so we can focus straight away on the cool stuff 😄.&lt;/p&gt;

&lt;p&gt;This is a perfect opportunity to see how to build live data syncs in a mobile app with CouchDb. You'll of course be able to exploit these two technologies in many more use cases but this is a good way to start.&lt;/p&gt;

&lt;p&gt;Thanks to CouchDb we don't need to build any backend! By the end we'll have a React Native app connected to a local CouchDb database. This basic game will help us concentrate on the essentials parts: the live sync &amp;amp; update on our React component. Feel free to explore the components to understand how it's displayed. Let's start!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Overview
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Rock-Paper-Scissors
&lt;/h3&gt;

&lt;p&gt;What exactly will our online game be able to do?&lt;/p&gt;

&lt;p&gt;The famous and popular Rock-Paper-Scissors will be played by two people who will join the game thanks to its id. Other users will also be able to participate and join as spectators. After each round, the app will update the game and at the end display the final score.&lt;/p&gt;

&lt;p&gt;Here a quick demo of what a player will see.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjcalixte%2Frnrps%2Fblob%2Fmaster%2Farticle%2Fassets%2Frps-demo.gif%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjcalixte%2Frnrps%2Fblob%2Fmaster%2Farticle%2Fassets%2Frps-demo.gif%3Fraw%3Dtrue" alt="Demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First steps are to clone the &lt;a href="https://github.com/jcalixte/rnrps" rel="noopener noreferrer"&gt;repo&lt;/a&gt; and simply run the command &lt;code&gt;yarn&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is CouchDb
&lt;/h3&gt;

&lt;p&gt;Before getting deeper into the app, let's dive into the technology behind it.&lt;/p&gt;

&lt;h4&gt;
  
  
  CouchDb
&lt;/h4&gt;

&lt;p&gt;CouchDb is a NoSQL database accessible via a RESTFUL API. The singularity of CouchDb is that data is immutable. Each update of a document (NoSQL data) is a new document linked to its previous versions by a common &lt;code&gt;_id&lt;/code&gt;. So, like in git, a historic tree can be made listing all the modifications of a document. Each update modifies the property &lt;code&gt;_rev&lt;/code&gt; like &lt;code&gt;_rev: 12-ad32d26&lt;/code&gt;. This is the version of the document (&lt;code&gt;_rev&lt;/code&gt; is for &lt;code&gt;revision&lt;/code&gt; 🤫).&lt;/p&gt;

&lt;p&gt;CouchDb masters in database replications. As it's possible to know what has been modified by an &lt;code&gt;_id&lt;/code&gt; and a &lt;code&gt;_rev&lt;/code&gt; prop, it's easy for a database to distinguish a delta and replicate from another one. At this stage the most important will be the replication of a distant database to a local one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.couchdb.org/en/stable/" rel="noopener noreferrer"&gt;CouchDb Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To work on our game, we'll need to install CouchDb locally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;To install CouchDb locally, go to their &lt;a href="https://docs.couchdb.org/en/latest/install/index.html" rel="noopener noreferrer"&gt;website&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Configuration
&lt;/h4&gt;

&lt;p&gt;Create an admin and configure CouchDb as a single node.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create the &lt;code&gt;RPS&lt;/code&gt; database
&lt;/h4&gt;

&lt;p&gt;Then, go to the "Databases" tab and create de database called &lt;code&gt;rps&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjcalixte%2Frnrps%2Fblob%2Fmaster%2Farticle%2Fassets%2Fcreate-db.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjcalixte%2Frnrps%2Fblob%2Fmaster%2Farticle%2Fassets%2Fcreate-db.png%3Fraw%3Dtrue" alt="Install CouchDB"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjcalixte%2Frnrps%2Fblob%2Fmaster%2Farticle%2Fassets%2Fname-db.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjcalixte%2Frnrps%2Fblob%2Fmaster%2Farticle%2Fassets%2Fname-db.png%3Fraw%3Dtrue" alt="Name Database"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Install CouchDb in React Native
&lt;/h4&gt;

&lt;p&gt;Easy! You only have to run &lt;code&gt;yarn add pouchdb-react-native&lt;/code&gt; and you're set!&lt;/p&gt;

&lt;h4&gt;
  
  
  PouchDb
&lt;/h4&gt;

&lt;p&gt;If CouchDb can store data in a server, PouchDb helps us manipulate data in locale database. PouchDb is close to CouchDb as they share the same API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pouchdb.com/guides/replication.html" rel="noopener noreferrer"&gt;PouchDb Documentation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's dive into the code!
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Sync
&lt;/h3&gt;

&lt;p&gt;We want to share a document &lt;code&gt;Play&lt;/code&gt; in real-time. How do we do that? We are going to replicate the local database and the database from the server. PouchDb has a really good method for it called &lt;code&gt;sync&lt;/code&gt;. If there is one reason to use PouchDb it's for the &lt;code&gt;sync&lt;/code&gt; method! Take a look at this quote from PouchDb documentation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;CouchDB was designed with sync in mind, and this is exactly what it excels at. Many of the rough edges of the API serve this larger purpose. For instance, managing your document revisions pays off in the future, when you eventually need to start dealing with conflicts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We use it this way: &lt;code&gt;localDB.sync(remoteDB)&lt;/code&gt;. This method is a shortcut for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;localDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replicate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;remoteDB&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;localDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replicate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;remoteDB&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;sync&lt;/code&gt; has many options and in our case we'll need the following settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a live sync so we add the property &lt;code&gt;sync&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;a synchronization that persists and retry when there are connection problems. So we define the &lt;code&gt;retry&lt;/code&gt; prop as &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We don't want to synchronize the whole database, only the current game. Fortunately, CouchDb and PouchDb can manage that for us with a &lt;a href="https://pouchdb.com/api.html#replication" rel="noopener noreferrer"&gt;filtered replication&lt;/a&gt;. There are many ways to do a filtered replication but the most efficient one is to give to &lt;code&gt;sync&lt;/code&gt; the array of ids we want to listen to.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more details, I recommend this excellent &lt;a href="https://pouchdb.com/guides/replication.html#setting-up-sync" rel="noopener noreferrer"&gt;PouchDb documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we have a look at the whole code, this is what we should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Repository/index.ts&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;liveGame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cancelLive&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;Player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Player1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;Player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Player2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sync&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;live&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;retry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;doc_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;change&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;change&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SYNC_UP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is pretty simple, isn't it?&lt;br&gt;
We added an event &lt;code&gt;SYNC_UP&lt;/code&gt; to make our &lt;code&gt;React&lt;/code&gt; component reactive. We'll listen to it later.&lt;/p&gt;
&lt;h3&gt;
  
  
  Merge
&lt;/h3&gt;

&lt;p&gt;During a game each player will update his own document so we won't have to deal with conflicts. But our component can only handle one document &lt;code&gt;Play&lt;/code&gt; to display plays and scores. At this stage we only have one work left to do: to fetch the two documents in the database and merge them into one.&lt;/p&gt;

&lt;p&gt;In the file &lt;code&gt;PlayService.&lt;/code&gt;, we'll call the method &lt;code&gt;mergePlays&lt;/code&gt; where we use a spread operator to merge the two documents. But there is a little more work to do when we want to gather play &lt;code&gt;turns&lt;/code&gt; (in which each player updates their moves). For each &lt;code&gt;turn&lt;/code&gt;, we retrieve the move of the player 1 in the player 1's document and the move of the player 2 in the player 2's document. Like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// PlayService.ts&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;mergePlays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;play1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IPlay&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;play2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IPlay&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;IPlay&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// If one of these two documents is null just return the other one.&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;play1&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;play2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;play1&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;play2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;play&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;play1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;play2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;turnCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;play1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;turns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;play2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;turns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;turnCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;turns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;turns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;turnCount&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;_item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;turn1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;play1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;turns&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;turn2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;play2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;turns&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;player1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;turn1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;turn1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;player2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;turn2&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;turn2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;turn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ITurn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;player1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;player2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;winner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="nx"&gt;turn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;winner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getWinner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;turn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;turn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;play&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The React Native component
&lt;/h3&gt;

&lt;p&gt;Now that all the settings are in place to sync, it's finally time to display our game on screen. The code below is the page &lt;code&gt;Play&lt;/code&gt; after the player submits the game id in the home page. We can initialize the liveGame; telling PouchDb to only syncs documents we need.&lt;/p&gt;

&lt;p&gt;When fetching the play if there is no player 2, we join the play 🙂.&lt;/p&gt;

&lt;p&gt;We can listen to changes by adding a listener to the &lt;code&gt;SYNC_UP&lt;/code&gt; event from our PouchDb repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/views/Play.tsx&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;navigation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;play&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPlay&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IPlay&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getPlay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;playFromDb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;PlayService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;setPlay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;playFromDb&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;

  &lt;span class="c1"&gt;// If there is no player 2 when fetching the game, we'll be able to join in.&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;playFromDb&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;playFromDb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;PlayService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;joinPlay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SYNC_UP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPlay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;liveGame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;getPlay&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SYNC_UP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPlay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A picture is worth a thousand words
&lt;/h2&gt;

&lt;p&gt;For a quick sum up, find below the 3 main steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Player 1 creates the play

&lt;ul&gt;
&lt;li&gt;Player 1 saves a local document
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"12345-player1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"player1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"uuid-player1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"player2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"turns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"_rev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1-abc"&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The app right after syncs with the server and saves the document&lt;/li&gt;
&lt;li&gt;Player 1 waits for a Player 2 to come by listening to any updates from the server of documents with ids "12345-player1" and "12345-player2"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjcalixte%2Frnrps%2Fblob%2Fmaster%2Farticle%2Fassets%2Fstep-1.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjcalixte%2Frnrps%2Fblob%2Fmaster%2Farticle%2Fassets%2Fstep-1.png%3Fraw%3Dtrue" alt="Step 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Player 2 joins the play

&lt;ul&gt;
&lt;li&gt;Player 2 joins the play by fetching and updating the player 1's with his uuid in 'player2' attribute.&lt;/li&gt;
&lt;li&gt;Player 2 creates a local document
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"12345-player2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"player1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"uuid-player1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"player2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"uuid-player2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"turns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"_rev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1-bcd"&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Player 2's app syncs with the database and saves the two documents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjcalixte%2Frnrps%2Fblob%2Fmaster%2Farticle%2Fassets%2Fstep-2.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjcalixte%2Frnrps%2Fblob%2Fmaster%2Farticle%2Fassets%2Fstep-2.png%3Fraw%3Dtrue" alt="Step 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The play is ready

&lt;ul&gt;
&lt;li&gt;Player 1 gets the updates and is now ready to play the first round&lt;/li&gt;
&lt;li&gt;Player 1 and player 2 save their document locally and then share them with the server. That way every player receives updates from their opponent.&lt;/li&gt;
&lt;li&gt;The app merges the two documents into one, so we can calculate who wins the round 1 and update the score.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjcalixte%2Frnrps%2Fblob%2Fmaster%2Farticle%2Fassets%2Fstep-3.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjcalixte%2Frnrps%2Fblob%2Fmaster%2Farticle%2Fassets%2Fstep-3.png%3Fraw%3Dtrue" alt="Step 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;DONE! We've completed our first live sync between two databases in React Native, awesome!&lt;/p&gt;

&lt;p&gt;There is so much more we can explore now. Here a few examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create an offline-first app to provide a seamless experience either the app is online or offline.&lt;/li&gt;
&lt;li&gt;create an app that shares data in Bluetooth without the need of an Internet connection (like shareable books in a region where the Internet is expensive)&lt;/li&gt;
&lt;li&gt;create an app where people can collaborate in live.&lt;/li&gt;
&lt;li&gt;and so on...&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>live</category>
      <category>reactnative</category>
      <category>couchdb</category>
      <category>pouchdb</category>
    </item>
    <item>
      <title>Creating a VueJS component for online/offline events</title>
      <dc:creator>Julien Calixte</dc:creator>
      <pubDate>Thu, 14 Nov 2019 20:03:29 +0000</pubDate>
      <link>https://dev.to/jcalixte/creating-an-vuejs-component-for-online-offline-events-31mc</link>
      <guid>https://dev.to/jcalixte/creating-an-vuejs-component-for-online-offline-events-31mc</guid>
      <description>&lt;p&gt;Hi folks!&lt;/p&gt;

&lt;p&gt;I've recently created a node module and I thought it could be interesting to review it together, if you want to publish a component that you use on multiple VueJS apps.&lt;/p&gt;

&lt;p&gt;The component is named &lt;a href="https://www.npmjs.com/package/vue-online-offline"&gt;vue-online-offline&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Of course, there are others components and directives that can be used to know if your app is online or not. Be I find useful to have a small component with events &amp;amp; slots that can be used everywhere without any global variables, just a simple reusable component 😊.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Here an example when it can be used. (Pro tip: if you're displaying the same component and only change its properties, remember to add a key on your component to force VueJS to rerender it)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;vue-online-offline&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;online=&lt;/span&gt;&lt;span class="s"&gt;"isOnline"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;offline=&lt;/span&gt;&lt;span class="s"&gt;"isOffline"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ArticleList&lt;/span&gt; &lt;span class="na"&gt;slot=&lt;/span&gt;&lt;span class="s"&gt;"online"&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"online"&lt;/span&gt; &lt;span class="na"&gt;:online=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ArticleList&lt;/span&gt; &lt;span class="na"&gt;slot=&lt;/span&gt;&lt;span class="s"&gt;"offline"&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;"offline"&lt;/span&gt; &lt;span class="na"&gt;:online=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/vue-online-offline&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;VueOnlineOffline&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue-online-offline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;VueOnlineOffline&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Now I'm online!`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;// Show toaster 'Success! you're online!'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;isOffline&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Now I'm offline.`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;// Show toaster 'Information: you're now offline but you can still read your local articles.'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;So, here is the component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"online-view"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"online"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"online"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/slot&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;v-else&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"offline"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/slot&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;online&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onLine&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;mounted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;online&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;offline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;beforeDestroy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;online&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;offline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;onchange&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;online&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onLine&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;online&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;online&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;offline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is quite simple with two slots and events emitted thanks to the online/offline events available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create and build the component
&lt;/h2&gt;

&lt;p&gt;First, we will use the &lt;code&gt;vue-cli&lt;/code&gt; command line tool: &lt;code&gt;vue create vue-online-offline&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can remove the components and assets folders as well as the &lt;code&gt;main.js&lt;/code&gt;. Only the App.vue will be useful here, we replace the code with our own component.&lt;/p&gt;

&lt;p&gt;Then VueJS command line tool lets you build a component for npmjs.org simply with a &lt;code&gt;.vue&lt;/code&gt; file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;vue-cli-service build --target lib --name vue-online-offline&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;By default it will search for the App.vue file. You can look for more details in the &lt;a href="https://cli.vuejs.org/guide/build-targets.html#library"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It will create a dist folder with your javascript files that will be used by other apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publish as a node package!
&lt;/h2&gt;

&lt;p&gt;We add the main property and specify the files in the package.json that's it! A new shiny package available for everyone! For instance, here my package.json :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vue-online-offline"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"serve"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vue-cli-service serve"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vue-cli-service build --target lib --name vue-online-offline"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vue-cli-service lint"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist/vue-online-offline.common.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MIT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"dist/*"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"repository"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/jcalixte/vue-online-offline"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"core-js"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^3.3.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"vue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.6.10"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@vue/cli-plugin-babel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@vue/cli-plugin-eslint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@vue/cli-service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"babel-eslint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^10.0.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"eslint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^5.16.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"eslint-plugin-vue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^5.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"vue-template-compiler"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.6.10"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"eslintConfig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"root"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"extends"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"plugin:vue/essential"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"eslint:recommended"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parserOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parser"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"babel-eslint"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"postcss"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"plugins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"autoprefixer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"browserslist"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt; 1%"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"last 2 versions"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"vuejs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"vue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"component"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"online"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"offline"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"slot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"event"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To publish, login &amp;amp; run the command &lt;a href="https://docs.npmjs.com/cli/publish"&gt;&lt;code&gt;npm publish&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Voilà ! Hope you enjoyed this little tutorial! Let me know if you have any question, I'll be glad to answer it.&lt;/p&gt;

&lt;p&gt;Love.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>component</category>
      <category>package</category>
      <category>publish</category>
    </item>
    <item>
      <title>VueJS PWA assets generator</title>
      <dc:creator>Julien Calixte</dc:creator>
      <pubDate>Fri, 25 Oct 2019 07:24:56 +0000</pubDate>
      <link>https://dev.to/jcalixte/vuejs-pwa-assets-generator-4jhn</link>
      <guid>https://dev.to/jcalixte/vuejs-pwa-assets-generator-4jhn</guid>
      <description>&lt;p&gt;&lt;em&gt;TLDR&lt;/em&gt; : &lt;code&gt;npx vue-pwa-asset-generator -a {your_512x512_png_source or your_svg_source} -o {your_output_folder}&lt;/code&gt;. You're done!&lt;/p&gt;

&lt;p&gt;Hi folks!&lt;/p&gt;

&lt;p&gt;When I develop for side projects, most of the time I use the stack &lt;code&gt;VueJS&lt;/code&gt; with the PWA plugin, &lt;code&gt;CouchDb&lt;/code&gt;/&lt;code&gt;PouchDb&lt;/code&gt; for my backend and publish my Progressive Web App on &lt;a href="https://netlify.com"&gt;netlify&lt;/a&gt;. There is a simplicity in this stack I love.&lt;/p&gt;

&lt;p&gt;But I've always been struggling with generating the assets to put in the manifest.json and I haven't found any help on the internet. So here we are, I created the generator myself!&lt;/p&gt;

&lt;p&gt;It is named &lt;a href="https://www.npmjs.com/package/vue-pwa-asset-generator"&gt;vue-pwa-asset-generator&lt;/a&gt;! With &lt;a href="https://www.npmjs.com/package/sharp"&gt;sharp&lt;/a&gt; it was really simple.&lt;/p&gt;

&lt;p&gt;So, what does it do? It generates all the assets that exist by default in your public/img folder and the favicon.ico as well as the icons attribute in a manifest.json that you can merge with your actual manifest.json. All you need is one png image first and it does the rest!&lt;/p&gt;

&lt;p&gt;Here an example of use, once installed : &lt;code&gt;vue-asset-generate -a logo.png -o img&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Hope it helps you too! 😃&lt;/p&gt;

&lt;p&gt;Love.&lt;/p&gt;

&lt;p&gt;Extra: it now works with svg files too!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/vue-pwa-asset-generator"&gt;https://www.npmjs.com/package/vue-pwa-asset-generator&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/jcalixte/vue-pwa-asset-generator"&gt;https://github.com/jcalixte/vue-pwa-asset-generator&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>pwa</category>
      <category>asset</category>
      <category>generator</category>
    </item>
    <item>
      <title>Programming and the fight against climate change</title>
      <dc:creator>Julien Calixte</dc:creator>
      <pubDate>Wed, 20 Dec 2017 07:29:33 +0000</pubDate>
      <link>https://dev.to/jcalixte/programming-and-the-fight-against-climate-change-3nm7</link>
      <guid>https://dev.to/jcalixte/programming-and-the-fight-against-climate-change-3nm7</guid>
      <description>&lt;p&gt;I've been programming for 5 years and I've never worked directly in a project with a clear goal like to lower our carbon footprint even if this is a question I'm asking myself everyday to improve the situation. The only thing that comes close is that I'm currently developing a web app for a French company to limit paper documents on their parts repair.&lt;/p&gt;

&lt;p&gt;In the meantime, &lt;a href="https://climatecare.org/infographic-the-carbon-footprint-of-the-internet/"&gt;our domain has a footprint exceeding air travel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, in my case, this is obviously not enough in a larger scale. I need to do a lot more. So I was wondering what do you do in your workday to improve the climate situation? Do you work in the climate field? Is the Earth a concern in your every day business?&lt;/p&gt;

&lt;p&gt;Finally, in general, do you think, as a developer, we can have a positive impact on this global warming?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>future</category>
    </item>
    <item>
      <title>Hi, I'm Julien</title>
      <dc:creator>Julien Calixte</dc:creator>
      <pubDate>Tue, 10 Jan 2017 18:20:33 +0000</pubDate>
      <link>https://dev.to/jcalixte/hi-im-julien-calixte</link>
      <guid>https://dev.to/jcalixte/hi-im-julien-calixte</guid>
      <description>&lt;p&gt;I have been coding for 3 years.&lt;/p&gt;

&lt;p&gt;You can find me on Twitter as &lt;a href="https://twitter.com/julien_calixte" rel="noopener noreferrer"&gt;@julien_calixte&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I live in Paris.&lt;/p&gt;

&lt;p&gt;I mostly program in these languages: C#, JavaScript, &lt;/p&gt;

&lt;p&gt;I am currently learning more about vuejs, webpack.&lt;/p&gt;

&lt;p&gt;Nice to meet you :-)&lt;/p&gt;

</description>
      <category>introduction</category>
    </item>
  </channel>
</rss>
