Jekyll2022-01-21T14:38:07+00:00http://feugy.github.io/feed.xmlAbout Damien (aka @feugy)Software architect and craftsmanDamien Simonin FeugasNodeConf Remote 20212021-11-19T00:00:00+00:002021-11-19T00:00:00+00:00http://feugy.github.io/nodeconf-2021<h1 id="nodeconf-remote">NodeConf Remote</h1>
<p>NodeConf exists since more than a decade now, with issues first hosted in the US, then in Ireland, and many more countries recently.
With the pandemic, it “went online” in 2020, and so did it this year: <a href="https://www.nodeconfremote.com">NodeConf Remote</a>.</p>
<p>I was lucky to attend NodeConf in 2015, in the beautiful <a href="https://www.youtube.com/watch?v=QSNHsGlonq0">Waterford’s Castle</a>, and in 2017 in <a href="https://www.youtube.com/watch?v=cvKzBEUy6sA">Lyrath’s hotel</a>.
For sure, online conferences don’t offer the same experience, so I decided to leave my comfort zone and submit a talk.</p>
<p>Entering the close circle of a worldwide conference speakers is certainly a challenge.
Everybody can submit a talk, so the best speakers might line up 😱.</p>
<h1 id="what-could-make-an-interesting-talk">What could make an interesting talk?</h1>
<p>What a tricky, very personal question. Looking back at my records, the most valuable topic I found was <a href="https://feugy.github.io/melodie-showcase">Mélodie</a>:</p>
<ul>
<li>a wide showcase of technologies</li>
<li>a long enough history of changes, highlighting good and bad decisions</li>
<li>something that I enjoy talking about</li>
</ul>
<p>But first and foremost, it’s a perfect case for demonstrating the saying</p>
<blockquote>
<p>“Success is a journey, not a destination. The doing is often more important than the outcome.”</p>
<p>~ Arthur Ashe</p>
</blockquote>
<p>It is clear that nobody needs yet another music player.
The whole point of such project is not to build an Open source community either: beside the lack of purpose, I don’t have time and desire to grow it.</p>
<p>The learning journey is extremely valuable. For me as an individual, but also for others if I dare sharing it.</p>
<h1 id="mélodie-a-journey-with-svelte-and-fastify">Mélodie: A journey with Svelte and Fastify</h1>
<p>Watch the conference here:</p>
<div class="centered">
<figure class="card">
<iframe width="560" height="315" src="https://www.youtube.com/embed/eLCJpjDoANk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<figcaption class="caption">
<p>NodeConf Remote 2021 - recording</p>
</figcaption>
</figure>
</div>Damien Simonin FeugasNodeConf RemoteAtelier2021-04-18T00:00:00+00:002021-04-18T00:00:00+00:00http://feugy.github.io/atelier<h1 id="yet-another-workbench">Yet another workbench?</h1>
<p>Atelier (French word for workbench or workshop) is a simple UI component explorer, like <a href="https://reactcosmos.org">angular-playground</a>, <a href="https://storybook.js.org">storybook</a>, <a href="https://react-styleguidist.js.org">styleguidist</a>, <a href="https://svench-docs.vercel.app">svench</a> or <a href="https://github.com/meteor/chromatic">chromatic</a>.</p>
<p>A workbench help you implementing <a href="https://www.componentdriven.org">Component Driven Development</a>: crafting reusable UI components in isolation.</p>
<p>Now, about the elephant in the room:</p>
<blockquote>
<p><em>Storybook is a wonderful tool</em>. Do we need a bad clone of it?</p>
</blockquote>
<p>In my experience, Storybook does not bring an enjoyable developer experience, mostly because of webpack (as the time of writing).</p>
<p>A lot of people throw a lot of effort to improve it for common cases, leading to powerfull starterkits like <a href="https://create-react-app.dev">create-react-app</a>, and many blogpost (try searching for “storybook + nextjs” 😉).</p>
<p>However, if your project is not react-based, you’re very likely to be forced rewriting an entire webpack configuration, leading to a very fragile and unefficient setup. On medium-sized code base, build time is significant, and becomes a barrier to CDD.</p>
<p>Atelier seamlessly integrates with [Vite] bundler, and give you back control. It has bindings for Svelte, and thanks to Vite’s capabilities, will eventually support Vue and React.</p>
<h1 id="how-does-it-work">How does it work?</h1>
<p>The code is organized in an mono-repository.</p>
<ol>
<li>
<p><code class="language-plaintext highlighter-rouge">@atelier-wb/plugin-svelte</code>, is a vite plugin that starts atelier UI</p>
<p>In your <code class="language-plaintext highlighter-rouge">vite.config.js</code> file, add:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nx">svelte</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@sveltejs/vite-plugin-svelte</span><span class="dl">"</span><span class="p">;</span>
<span class="c1">// other vite plugins</span>
<span class="k">import</span> <span class="nx">atelier</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@atelier-wb/vite-plugin-svelte</span><span class="dl">"</span><span class="p">;</span>
<span class="k">export</span> <span class="k">default</span> <span class="nx">defineConfig</span><span class="p">({</span>
<span class="na">plugins</span><span class="p">:</span> <span class="p">[</span><span class="nx">svelte</span><span class="p">(),</span> <span class="cm">/* other plugins */</span> <span class="nx">atelier</span><span class="p">()],</span>
<span class="p">});</span>
</code></pre></div> </div>
<p>It will run the Atelier UI (I call it the “frame”) at http://localhost:3000/, and will update it every time you change your components.</p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">@atelier-wb/ui</code>, contains the UI frame: a component explorer, and several panels to list triggered event, and tweak component properties.
It is built with Svelte, but this does not really matters since users will run a compiled version.</p>
<p>It also has an iframe to host the tested component, and control the display size.</p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">@atelier-wb/svelte</code>, the Svelte language bindings, which allows users to write “Tools” for their components:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o"><</span><span class="nx">script</span><span class="o">></span>
<span class="k">import</span> <span class="p">{</span> <span class="nx">Tool</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@atelier-wb/svelte</span><span class="dl">'</span>
<span class="k">import</span> <span class="nx">MyComponent</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">../src/MyComponent.svelte</span><span class="dl">'</span>
<span class="o"><</span><span class="sr">/script</span><span class="err">>
</span>
<span class="o"><</span><span class="nx">Tool</span> <span class="nx">name</span><span class="o">=</span><span class="dl">"</span><span class="s2">Components/My component</span><span class="dl">"</span> <span class="nx">component</span><span class="o">=</span><span class="p">{</span><span class="nx">MyComponent</span><span class="p">}</span> <span class="sr">/</span><span class="err">>
</span></code></pre></div> </div>
<p>These bindings will allow the UI tweaking component properties, and listening to its events.</p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">@atelier-wb/toolshot</code>, an equivalent of <a href="https://github.com/storybookjs/storybook/tree/next/addons/storyshots/storyshots-core">storyshot</a>, that is a collection of snapshots for your components, so you can find structural regressions as part of your Jest test suite.</p>
</li>
</ol>
<div class="centered">
<figure class="card">
<img src="http://feugy.github.io/image/atelier-ui.png" alt="Atelier UI: on the left, a component explorer. At the bottom, tool panels" />
<figcaption class="caption">
<p>Atelier UI: on the left, a component explorer. At the bottom, tool panels</p>
</figcaption>
</figure>
</div>
<h1 id="whats-next">What’s next?</h1>
<p>More documentation, examples, and a couple of features, like React support and a way to filter the explorer.</p>
<p>I would love Atelier to look better, so I need to poke my designer friends for some help 😁</p>
<h1 id="where-is-it">Where is it?</h1>
<p>It is hosted on <a href="https://github.com/feugy/atelier">github</a> and published on <a href="https://www.npmjs.com/search?q=atelier-wb">npm</a>.</p>Damien Simonin FeugasYet another workbench?Mélodie2020-07-05T00:00:00+00:002020-07-05T00:00:00+00:00http://feugy.github.io/melodie<h1 id="music-for-ballet">Music for Ballet</h1>
<p>My dear wife is a Ballet teacher.
Top-notch Ballet schools have professional pianists, who play during lessons.
One can can not use random music tracks: music is timed and measured to fit very specific exercices: <em>Dégagés, Fondus, Adage</em>…
<a href="https://asgardproductions.com/product/dance-arts-production-vol-27">Here</a> is an example.</p>
<p>In all other schools, the Ballet teacher plays recordings they usually bought on good old CDs. It’s rare to find such specialized music on famous cloud platforms.</p>
<p>So my wife has a decent, legit MP3 library ripped from her CDs. She extracts a selection on an USB key and go give her lessons.
To make her life easier, we considered storing MP3 on a Windows-powered laptop she could bring with her.
One of the requirements was to display album covers first, so she could find tracks the way she would do with physical CDs.</p>
<p>I’m working on an Ubuntu-powered laptop, and was ripping and organizing the library. Surprisingly, finding a portable, decent music player with a cover display was… very hard.</p>
<p>And this is how Mélodie is born.</p>
<h1 id="a-quick-tour">A quick tour</h1>
<p>Mélodie’s features are unsurprisingly boring. In a gist, it plays music.</p>
<p>You’ll find more on the <a href="https://feugy.github.io/melodie">promo page</a>, here are some key highlights:</p>
<ul>
<li>Mélodie only rely on music metadata (tags) to organize your library</li>
<li>It watches your local folders and adapts to changes</li>
<li>Toggling broadcast on, allows you to securely access your library from everywhere using a browser</li>
</ul>
<div class="centered">
<figure class="card">
<img src="http://feugy.github.io/image/melodie.png" alt="The Album Galery, the player and the track queue" />
<figcaption class="caption">
<p>The Album Galery, the player and the track queue</p>
</figcaption>
</figure>
</div>
<p>Under the hood, Mélodie is:</p>
<ul>
<li><a href="https://www.electronjs.org">Electron</a>, an unleashed version of chromium that can run Node.js.</li>
<li><a href="https://svelte.dev">Svelte</a>, an elegant, powerful and reactive UI framework.</li>
<li><a href="https://windicss.org">WindiCSS</a>, a comprehensible utility-first CSS framework.</li>
<li><a href="https://rxjs.dev">RxJS</a>, the JavaScript Reactive eXtension where data flows from sources to sinks.</li>
<li><a href="https://sqlite.org">Sqlite3</a>, a lightweight, embeddable SQL server with JSON extension.</li>
<li><a href="https://www.fastify.io">Fastify</a>, a lightweight, blazing fast, pluggable Web framework.</li>
<li><a href="https://vitejs.dev">Vite</a>, next-gen Frontend tooling for an incredibly good developer experience.</li>
<li><a href="https://jestjs.io/">Jest</a>, my favorite testing tools suite, all you need to ship tested code.</li>
<li><a href="https://feugy.github.ui/atelier">Atelier</a>, my own implementation of Storybook, with Svelte in mind.</li>
</ul>
<p>I gave a conference <a href="https://feugy.github.io/nodeconf-2021">at NodeConf 2021</a> to hightlight some of these.</p>
<h1 id="challenges-faced">Challenges faced</h1>
<p>As for all my side projects, Mélodie is an excuse for learning and up-skilling.</p>
<blockquote>
<p>This time, my goals were to learn Svelte and to sharpen my testing practices.</p>
</blockquote>
<p>Maintaining a side project over a long period is always an interesting challenge, at it allows technical debt to arise, gives multiple opportunities for new, contradicting features. Like in “real” life.</p>
<p>In particular:</p>
<ul>
<li>
<p>the testing harness, given I want a limited set of tools. Jest is wonderful, but <em>jest + svelte + postcss + storybook + tailwindcss + webpack</em> is a nightmare to maintain. Eventually, I replaces the last three to keep an productive, enjoyable developer experience.</p>
</li>
<li>
<p>combining Svelte and Rxjs, thanks to <a href="https://codechips.me/if-svelte-and-rxjs-had-a-baby">this article</a>. Rx requires a completely different mindset, but it’s such a flexible and powerful tool, and Svelte is a perfect fit. They are a robust foundation for an application, gifting the team with both flexibility and efficiency.</p>
</li>
<li>
<p>moving to the web. When adding the broadcast feature, Mélodie moved from inter-process (UI <> core) to client-server communication mechanism (with WebSockets). This also implied adding security (Time-based One Time Password and JSON Web Tokens), and removing some Electron-native features (like dialog). Does this sound a lot? Well, the <a href="https://github.com/feugy/melodie/pull/19">PR</a> <em>is</em> big, but that’s because of the next challenge. The real changes appeared only in 2 files.</p>
</li>
<li>
<p>the mono-repo endeavour. Mélodie started as a monolith, and is now a mono repo with a core (Node.js), a UI (Svelte), a desktop app (Electron) and a promo site. I tried many, many tools (Lerna, pNPM, NX, Yarn) which all failed for various reason. NPM@7 saved the day.</p>
</li>
<li>
<p>distributing a desktop application. Building and testing an app for OSX and Windows, when you’re on a linux platform, is pretty hard. Distributing and maintaining several packager systems per OS (zip, tar.gz, portable exe, image disk, AppImage, Snap) is even harder. I tried for the sake of it, but will certainly consider the smallest acceptable subset in a professional project.</p>
</li>
</ul>
<h1 id="going-further">Going further</h1>
<p>You can download the app from the <a href="https://feugy.github.io/melodie">promo page</a>, and the code is hosted on <a href="https://github.com/feugy/melodie">github</a>.</p>
<p>You can also find it on <a href="https://snapcraft.io/melodie">Snapcraft</a> and on <a href="https://www.microsoft.com/p/melodie/9n41vk2c5vc2">Windows Store</a>.</p>Damien Simonin FeugasMusic for BalletContributing to Nodejs2018-01-01T00:00:00+00:002018-01-01T00:00:00+00:00http://feugy.github.io/contributing-to-node<h1 id="fixing-recurrent-need">Fixing recurrent need</h1>
<p>The project I was working on was entierly promised-based (and later on, using <code class="language-plaintext highlighter-rouge">async</code>/<code class="language-plaintext highlighter-rouge">await</code>).</p>
<p>We also use <a href="https://github.com/power-assert-js/power-assert" target="\_blank">power-assser</a>, a great assertion library which provides very detailed error report and sticks to nodejs’s <a href="https://nodejs.org/api/all.html#assert_assert" target="\_blank">assert module API</a>.</p>
<p>We wrote plenty of tests checking that tested code was rejecting promises:</p>
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">should handle error while getting config from db</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span>
<span class="k">try</span> <span class="p">{</span>
<span class="k">await</span> <span class="nx">config</span><span class="p">.</span><span class="kd">get</span><span class="p">()</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="dl">'</span><span class="s1">should have failed</span><span class="dl">'</span><span class="p">)</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">assert</span><span class="p">(</span><span class="nx">err</span> <span class="k">instanceof</span> <span class="nb">Error</span><span class="p">)</span>
<span class="nx">assert</span><span class="p">(</span><span class="nx">err</span><span class="p">.</span><span class="nx">message</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="dl">'</span><span class="s1">db failure</span><span class="dl">'</span><span class="p">))</span>
<span class="p">}</span>
<span class="p">})</span></code></pre></figure>
<p>If you forget to check the actual message, then you’re not sure that tested code failed for the expected reason.</p>
<p>And here it comes:</p>
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">should handle error while getting config from db</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span>
<span class="k">try</span> <span class="p">{</span>
<span class="k">await</span> <span class="nx">config</span><span class="p">.</span><span class="kd">get</span><span class="p">()</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">assert</span><span class="p">(</span><span class="nx">err</span> <span class="k">instanceof</span> <span class="nb">Error</span><span class="p">)</span>
<span class="nx">assert</span><span class="p">(</span><span class="nx">err</span><span class="p">.</span><span class="nx">message</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="dl">'</span><span class="s1">db failure</span><span class="dl">'</span><span class="p">))</span>
<span class="k">return</span>
<span class="p">}</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="dl">'</span><span class="s1">should have failed</span><span class="dl">'</span><span class="p">)</span>
<span class="p">})</span></code></pre></figure>
<p>The logic in <code class="language-plaintext highlighter-rouge">catch</code> clause is pretty verbose:</p>
<ul>
<li>it checks that an <code class="language-plaintext highlighter-rouge">Error</code> is thrown</li>
<li>it checks an expected pattern in the actual error message</li>
<li>it stops the test.</li>
</ul>
<p>The final <code class="language-plaintext highlighter-rouge">throw</code> ensure the code <em>has failed for the good reason</em>.</p>
<p>We wrote the above dozens and dozens of time…
With synchronous code, we could have wrote:</p>
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">should handle error while getting config from db</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">assert</span><span class="p">.</span><span class="nx">throws</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="kd">get</span><span class="p">(),</span> <span class="nx">err</span> <span class="o">=></span>
<span class="nx">err</span> <span class="k">instanceof</span> <span class="nb">Error</span> <span class="o">&&</span> <span class="nx">err</span><span class="p">.</span><span class="nx">message</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="dl">'</span><span class="s1">db failure</span><span class="dl">'</span><span class="p">)</span>
<span class="p">)</span>
<span class="p">})</span></code></pre></figure>
<p>This is when I decided to propose a change in nodejs’ API.</p>
<h1 id="one-does-not-simply-propose-a-pull-request">One does not simply propose a Pull Request</h1>
<p>It was Christmas time, I was full of energy and motivation.
I downloaded Node’s code on my Windows machine, read how to <a href="https://github.com/nodejs/node/blob/master/BUILDING.md" target="\_blank">build</a>, <a href="https://github.com/nodejs/node/blob/master/CONTRIBUTING.md" target="\_blank">contribute</a>, <a href="https://github.com/nodejs/node/blob/master/doc/STYLE_GUIDE.md" target="\_blank">write code</a>, <a href="https://github.com/nodejs/node/blob/master/doc/guides/writing-tests.md" target="\_blank">write tests</a> and <a href="https://github.com/nodejs/node/blob/master/doc/guides/contributing/pull-requests.md" target="\_blank">issue a PR</a>.</p>
<p>It took me 2 days (mostly because building and running tests on Windows is crzay long).</p>
<p>Then I made a first <a href="https://github.com/nodejs/node/pull/17843" target="\_blank">pull request</a>… …and retrospectively I’m really ashamed of the naiveness of my contribution:
I turned the existing <code class="language-plaintext highlighter-rouge">assert.throws()</code> and <code class="language-plaintext highlighter-rouge">assert.doesNotThrow()</code> to async to they could support my usecase.</p>
<p>I clearly overlooked the impacts of my change, on some functions intensively used in a lot of NPM modules, and in the core itself.
Even the few tests I wrote prouved I was wrong :’(</p>
<p>But thanks the great kidness and patience of the all my reviewers, I didn’t lost faith and retried few days later.</p>
<p>The second <a href="https://github.com/nodejs/node/pull/18023" target="\_blank">pull request</a> (7th of January) was more acceptable: the idea was to add <code class="language-plaintext highlighter-rouge">assert.rejects()</code> and <code class="language-plaintext highlighter-rouge">assert.doesNotReject()</code> to be the promise-based equivalent of the existing functions.</p>
<p>It took me few iterations (11th, 18th of January and 3rd of February) to fully understand my reviewer’s directives, and provides something truely aligned with the existing code base and documentation.</p>
<p>Then the PR was suspended for a month, because of side discussions about removing <code class="language-plaintext highlighter-rouge">assert.doesNotThrow()</code>. Then it would have been a non-sense to add <code class="language-plaintext highlighter-rouge">assert.doesNotReject()</code>.</p>
<p>But finally, on the 11th of March, the PR was landedon the main branch, and will be part of Node 10!</p>
<h1 id="takeways">Takeways</h1>
<p>This was a extremelly long, insightful and educating experience.</p>
<p>Until know, I always shared my side projects as OSS, but actually never worked with an OSS community (except on <a href="/optikey">OptiKey</a>).
I worked with a lot of different people and teams at work (sometime up to 30 devlopers), but always <em>on site</em>.</p>
<p>I really learnt:</p>
<ul>
<li>
<p><em>the benefits of mentoring</em>
Nodejs codebase is completly different from modern project (React/Angular/Mongo…) codebases.
The core contributors truely taught me how it worked and what to do to perform consistent changes and additions.</p>
</li>
<li><em>it takes patience…</em>
OSS is often made by volonteers working during their free time, which necessary makes iteration longer.
I was working mostly during weekends myself, hence why this simple feature took almost 3 months.</li>
<li><em>…and questioning</em>
Having <em>used</em> and <em>taught</em> JavaScript for years doesn’t prevented me for doing newcomer mistakes.
I was tempted to push back on the numerous comments, but after reading them twice or three times, I actually understoog my errors.</li>
</ul>
<p>That was really a great experience, which I hope I could reiterate in the future!</p>Damien Simonin FeugasFixing recurrent needRemote Work !2016-12-13T00:00:00+00:002016-12-13T00:00:00+00:00http://feugy.github.io/remote-work<h1 id="a-lighning-talk">A Lighning talk</h1>
<p>As you may know, I’m working remotely from France with <a href="http://www.nearform.com/">nearForm</a> since March 2016.</p>
<p>This is a great experience, which I had an opportunity to describe during a monthly session of Lyon’s <a href="http://humantalks.com">Human Talks</a>.</p>
<p>We had five talks of 15 minutes each (speech: 10, questions: 5), about electic topics like “Module bundlers in JS”, “Genetic algorithms” or even “Fear of the blank page”. Mine was to relate my current situation.</p>
<h1 id="changing-my-professional-life">Changing my (professional) life</h1>
<p>After almost ten years as developer, lead developer and software architect at <a href="http://worldline.com/en-us/home.html">Worldline</a>, I needed to shake my own dust.
Following the example of <a href="https://github.com/maxired">Maxence</a>, a friends of mine, I looked for a remote job.</p>
<p>My main goals were to challenge myself against top developers and have more flexible working hours so I could train better and be more with my familly. Working for nearForm brought me all that, but also much much more.</p>
<p>Being a remote worker is a brand new experience for me, and even if I tried to prepare myself, it’s a big change.</p>
<p>Of course, everyone can forsee that working from home will make you more lonely, and will require self discipline.
But I didn’t realised the impact it had on my own familly, and even my own morale.</p>
<h1 id="remote-work-talk">Remote work talk</h1>
<p>This talk was the opportunity to share this ongoing experience:</p>
<ul>
<li>my motivations</li>
<li>the challenged I’ve met</li>
<li>tools I use to organise my daily life</li>
<li>what keeps me doing it</li>
</ul>
<p>I was delighted to face a small yet interested audience, who had some questions and constructive reactions.
I hope I can do a longer version of it in the future, and maybe gather more thought and tricks from my remote colleagues !</p>
<p>Here are the slides:</p>
<div class="centered">
<figure class="card">
<iframe src="//www.slideshare.net/slideshow/embed_code/key/gbDeRfrNINfd7q" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen=""> </iframe>
<figcaption class="caption">
<p>Talk slides (in French)</p>
</figcaption>
</figure>
</div>Damien Simonin FeugasA Lighning talkmini-service2016-06-21T00:00:00+00:002016-06-21T00:00:00+00:00http://feugy.github.io/mini-service<h1 id="start-simple-and-scale-big">Start simple and scale big</h1>
<p>Over the past couple of years, I’ve started three projects as MVP (Minimum Viable Products).
In this situation, the team has a short timeframe (around 3 mounths) to build a system used to test both market et the company readiness for a given business case.</p>
<p>Team focuses on building something simple, that could easily evolve.</p>
<p>But if the MVP is successful, then it will be the first iteration of something bigger.
So it also needs the bare minimum robustness and a design who will not prevent it to scale.</p>
<p>Beside the buzz around the word, this is my understanding of µService architecture: start simple and scale big.</p>
<h1 id="its-about-being-pragmatic-but-not-simplistic">It’s about being pragmatic, but not simplistic</h1>
<p>While building those projects, we faced more or less the same pattern:</p>
<ul>
<li>on the first sprint, team builds a single service (usually a REST API backend)</li>
<li>soon after it has to interact with some <a href="https://12factor.net/backing-services" target="\_blank">backing services</a> such as DB/3rd party system/SaaS application…: team adds some abstraction layers through facade objects</li>
<li>later on those layer/objects get bigger, more complex or more greedy. Team turns them to <a href="https://12factor.net/concurrency" target="\_blank">standalone services</a></li>
</ul>
<p>This pragmatic path is a very reasonable strategy in this context.
Building facade objects helps reuse, testing (and mocking), and pave the way for further evolution (making the service standalone).
And maybe this will never happen: team has saved setting up complex system (bus event, discovery services…).</p>
<p>But it overlooks some practical concerns:</p>
<ul>
<li>how developers could easily run and develop these services locally?</li>
<li>how operations could deploy services without restarting the full chain, or following a given order?</li>
<li>how both could leverage from <a href="https://12factor.net/dependencies" target="\_blank">explicit dependencies</a> without introducing tight coupling?</li>
</ul>
<h1 id="providing-seamless-developer-and-operation-experience">Providing seamless developer and operation experience</h1>
<p>I built the <a href="https://feugy.github.io/mini-service" target="\_blank">mini-service</a> and <a href="https://feugy.github.io/mini-client" target="\_blank">mini-client</a> libraries to address the above.</p>
<p>Is imposes very few constraints on services:</p>
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// file calc-service.js</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
<span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">calc-service</span><span class="dl">'</span><span class="p">,</span>
<span class="na">version</span><span class="p">:</span> <span class="dl">'</span><span class="s1">1.0.0</span><span class="dl">'</span><span class="p">,</span>
<span class="na">init</span><span class="p">:</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span>
<span class="na">add</span><span class="p">:</span> <span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="o">=></span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span><span class="p">,</span>
<span class="na">subtract</span><span class="p">:</span> <span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="o">=></span> <span class="nx">a</span> <span class="o">-</span> <span class="nx">b</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>A service has an <code class="language-plaintext highlighter-rouge">init()</code> function (could be <code class="language-plaintext highlighter-rouge">asynch</code>) which exposes a set of functions (APIs).
Those functions could also be <code class="language-plaintext highlighter-rouge">async</code>, and must take and return string, number, booleans, arrays and plain objects.
(Stream and Buffers are also supported, as single parameter/return).</p>
<p>Using this service as part of the main monolith is easy:</p>
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// caller code</span>
<span class="kd">const</span> <span class="nx">getClient</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">mini-client</span><span class="dl">'</span><span class="p">)</span>
<span class="kd">const</span> <span class="nx">calc</span> <span class="o">=</span> <span class="nx">getClient</span><span class="p">(</span><span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">./calc-service</span><span class="dl">'</span><span class="p">))</span>
<span class="k">await</span> <span class="nx">calc</span><span class="p">.</span><span class="nx">init</span><span class="p">()</span>
<span class="kd">const</span> <span class="nx">sum</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">calc</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">`Result is: </span><span class="p">${</span><span class="nx">sum</span><span class="p">}</span><span class="s2">`</span><span class="p">)</span></code></pre></figure>
<p>Once initialized, the <code class="language-plaintext highlighter-rouge">calc</code> object will have a method for each API exposed by <code class="language-plaintext highlighter-rouge">./calc-service.js</code> with the same signature (except they <em>are</em> <code class="language-plaintext highlighter-rouge">async</code>)</p>
<p>Making <code class="language-plaintext highlighter-rouge">./calc-service.js</code> a standalone Http server is straightfoward:</p>
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// file server.js</span>
<span class="kd">const</span> <span class="p">{</span><span class="nx">startServer</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">mini-service</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">startServer</span><span class="p">(</span><span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">./calc-service.js</span><span class="dl">'</span><span class="p">))</span></code></pre></figure>
<p>Then turning the monolith into a µService system is as equally simple:</p>
<figure class="highlight"><pre><code class="language-js" data-lang="js"><span class="c1">// caller code</span>
<span class="kd">const</span> <span class="nx">getClient</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">mini-client</span><span class="dl">'</span><span class="p">)</span>
<span class="kd">const</span> <span class="nx">calc</span> <span class="o">=</span> <span class="nx">getClient</span><span class="p">({</span>
<span class="na">remote</span><span class="p">:</span> <span class="dl">'</span><span class="s1">http://localhost:3000</span><span class="dl">'</span>
<span class="p">})</span> <span class="c1">// was getClient(require('./calc-service'))</span>
<span class="k">await</span> <span class="nx">calc</span><span class="p">.</span><span class="nx">init</span><span class="p">()</span>
<span class="kd">const</span> <span class="nx">sum</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">calc</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">`Result is: </span><span class="p">${</span><span class="nx">sum</span><span class="p">}</span><span class="s2">`</span><span class="p">)</span></code></pre></figure>
<h1 id="the-benefits">The benefits</h1>
<p>We’ve been sucessfully using mini-service and mini-client on a production system for almost two years.
Thanks to it:</p>
<ul>
<li>developers can run <em>locally</em> all services as part of a monolith, easier to debug</li>
<li>there’s a tight coupling locally: developers never get an outdated version of a service…</li>
<li>…and loose coupling in production: ops could deploy a single service without restarting the whole chain</li>
<li>the system is resilient: when service B is redeployed in production, service A will adapts as long as there’s no signature change</li>
<li>incompatible services are detected and reported: in production, if service B doesn’t provides the API service A expects, comprehensible error will be reported.</li>
</ul>
<p>And all this is toggled through the <code class="language-plaintext highlighter-rouge">remote</code> option of mini-client.</p>
<p>Of course there’s are more in it: input and output validation, <a href="https://www.openapis.org" target="\_blank">Open-API</a> descriptor, splitting exposed API into groups, and a tons of parameters.
Please checkoug the <a href="https://feugy.github.io/mini-service" target="\_blank">documentation!</a>.</p>Damien Simonin FeugasStart simple and scale bigOptiKey2015-09-18T00:00:00+00:002015-09-18T00:00:00+00:00http://feugy.github.io/optikey<h1 id="eye-tracking-for-disabled-persons">Eye tracking for disabled persons</h1>
<p>My father-in-law lives since 10 years with an Amyotrophic Lateral Sclerosis (ALS).
This disease left him totally disabled, unable to move anything below the neck.</p>
<p>For a long time I was looking for a way to allow him being autonomous on a computer.
In 2014, I acquired a cheap eye tracking device, <a href="http://www.tobii.com/xperience/" target="\_blank">Tobii’s EyeX</a>, initially made to augment games.</p>
<div class="centered">
<figure class="card">
<img src="http://feugy.github.io/image/eyex.png" alt="The EyeX device, USB3 plugged into a computer and stuck below your screen. © Tobii" />
<figcaption class="caption">
<p>The EyeX device, USB3 plugged into a computer and stuck below your screen. © Tobii</p>
</figcaption>
</figure>
</div>
<p>My idea was to make him control the mouse pointer with his gaze, and use his voice to issue some commands (‘click !’, ‘scroll down !’…).
<a href="https://github.com/feugy/alfred">Alfred</a> was my first attempt, but it did not went very far, due to a lack of time.</p>
<h1 id="the-optikey-project">The Optikey project</h1>
<p>In september 2015, thanks to a colleague, I heard about Julius Sweetland’s <a href="http://optikey.org" target="\_blank">Optikey</a>.
Julius has done an humongous work during 3 years to make barely the thing I dreamed of.</p>
<p>When Optikey is running, a visual keyboard takes your screen’s top, allowing to write words simply by looking to keys.
A dictionnary is used to make word suggestions, and the typed sentences will appear into any fields that previously had focus.
Words can also be spoken using Windows text-to-speech feature.</p>
<div class="centered">
<figure class="card">
<iframe width="560" height="315" src="https://www.youtube.com/embed/HLkyORh7vKk" frameborder="0" allowfullscreen=""></iframe>
<figcaption class="caption">
<p>OptiKey official presentation. © Julius Swettland</p>
</figcaption>
</figure>
</div>
<p>In addition to the classical letters, diacritics and numerical symbols, Optikey includes mouse controls, to click, double click, scroll, drag’n drop…</p>
<h1 id="localization-and-voice-commands">Localization and voice commands</h1>
<p>I immediately got in touch with Julius, offering to merge my work within Optikey.
The usage of voice to trigger commands was in its roadmap, so he accepted my proposal.</p>
<p>But my first work was to entirely localize sources, and share with the growing OptiKey community on <a href="https://www.transifex.com/optikey/optikey/dashboard/" target="\_blank">transifex online localization tool</a>.
After two weeks of intense work, the whole application got English and French localization, and German came few days after.</p>
<h1 id="a-work-in-progress">A work in progress</h1>
<p>Adding the voice commands is still a work in progress.
Optikey is C# program using <a href="https://msdn.microsoft.com/fr-fr/library/aa970268%28v=vs.110%29.aspx" target="\_blank">Windows Presentation foundation</a>, <a href="https://www.nuget.org/" target="\_blank">NuGet package manager</a> and <a href="https://github.com/Reactive-Extensions/Rx.NET" target="\_blank">Reactive eXtention for .Net</a> on .Net 4.5 runtime.
Until now, it’s a Windows-only application, so I’m using the builtin speech recognition engine.</p>
<p>Users are now able to affect a custom spoken word on every possible command (depending on their chosen locale), and the command will apply once the word is recognized.</p>
<h1 id="source-repository">Source repository</h1>
<p>My fork of Optikey is on <a href="https://github.com/feugy/OptiKey" target="\_blank">github</a>, and the documentation comes as a <a href="https://github.com/JuliusSweetland/OptiKey/wiki" target="\_blank">Wiki</a>.</p>Damien Simonin FeugasEye tracking for disabled personsOpen-io GUI2015-05-02T00:00:00+00:002015-05-02T00:00:00+00:00http://feugy.github.io/open-io<h1 id="openio-object-storage">Open.io object storage</h1>
<p><a href="http://openio.io/">Open.io</a> is a french IT company developping an object storage grid solution.
The product can be installed on a cluster of commodity servers, and Open.io runs a mutualized cluster on its own.</p>
<p>The grid is logically made of namespaces, functionnal group of servers (mail, videos, pictures...).
Namespaces gather physical servers, and servers host services of different kinds.</p>
<h1 id="prototyping-the-gui">Prototyping the GUI</h1>
<p>Open.io asks me to do a prototype of a management Web application.
This application is intended for clients and for the mutualized platform monitoring.</p>
<p>The job was to bootstrap an standalone application (all data mocked up) to visualize namespaces, servers and services.
Open.io has only made a light ergonomical study to express their needs. No design expected.</p>
<p>The focus was put on the ability to browse the namespace and accessing contextualized data (number of services on server, CPU usage, available space...)
A important part of the work was to try various means to organize all data.</p>
<p>The mission lasted 20 days.</p>
<div class="centered">
<figure class="card">
<img src="http://feugy.github.io/image/open.io.gif" alt="Browsing the Superhero grid" />
<figcaption class="caption">
<p>Browsing the Superhero grid</p>
</figcaption>
</figure>
</div>
<h1 id="technologies-used">Technologies used</h1>
<p>The prototype is a thin <a href="https://angularjs.org/">AngularJS</a> web application, written in ES6 (transpiled with <a href="https://github.com/google/traceur-compiler">Traceur</a>) with routing and i18n.
Data fixtures are <a href="http://www.superherodb.com/">Super heroes</a> and their respective <a href="http://en.wikipedia.org/wiki/List_of_comics_publishing_companies">publishing companies</a></p>
<p>Data visualization is made with <a href="http://d3js.org/">D3</a>, with a specify data layout involving Jake Gordon's <a href="https://github.com/jakesgordon/bin-packing">binary tree packing algorithm</a>.
The hexagonal representation of services is inspired by <a href="http://www.redblobgames.com/grids/hexagons/">Amit Patel's work</a>.</p>
<p>The build chain is sustained by <a href="http://gulpjs.com/">Gulp</a>, including ES6 and <a href="http://learnboost.github.io/stylus/">Stylus</a> (CSS preprocessor) transpilation, templates compilation and minification</p>Damien Simonin FeugasOpen.io object storageMixIT 20152015-04-16T00:00:00+00:002015-04-16T00:00:00+00:00http://feugy.github.io/mixit<h1 id="the-mix-it-conference">The Mix-IT conference</h1>
<p>Created in 2011 and hosted in Lyon, this conference is organized by <a href="http://www.lyonjug.org" target="\_blank">Lyon JUG</a> (Java User Group) and <a href="http://lyon.clubagilerhonealpes.org" target="\_blank">CARA</a> (Rhone-Alpes Agile Club),
and has this dual goal to share knowledge and activities around progamming (Java and friends, Web and mobile technologies…) and agility (Scrum, Kanban, Lean, DevOps…).
It’s intended to developers, project managers, entrepreneurs, with a strong will of being polyvalent (parallel tracks, conferences, games and workshops, English and French) and cheap (50€ for 2 days, lunchs included).</p>
<p>The small core team made of a dozen IT professionals works with various schools and their student, that are freely hosting the conference.
In 2015, around 550 people attended to 7 keynotes, 37 talks, 20 workshops and 19 lightningh talks animated by 72 speakers.
<a href="http://www.mix-it.fr/mixit15/planning" target="\_blank">7 parallel tracks</a>, 1400 thin pancakes, delightfull bio sandwitches.</p>
<div class="centered">
<figure class="card">
<img src="http://feugy.github.io/image/mixit-2015-2.png" alt="First key note in CPE amphitheater. [© Mix IT 2015](https://www.flickr.com/photos/132667704@N02){:target="_blank"}" />
<figcaption class="caption">
<p>First key note in CPE amphitheater. <a href="https://www.flickr.com/photos/132667704@N02" target="_blank">© Mix IT 2015</a></p>
</figcaption>
</figure>
</div>
<div class="centered">
<figure class="card">
<img src="http://feugy.github.io/image/mixit-2015-3.png" alt="30 seconds to convince audience to come at our talk. [© Mix IT 2015](https://www.flickr.com/photos/132667704@N02){:target="_blank"}" />
<figcaption class="caption">
<p>30 seconds to convince audience to come at our talk. <a href="https://www.flickr.com/photos/132667704@N02" target="_blank">© Mix IT 2015</a></p>
</figcaption>
</figure>
</div>
<p>Even children are invited, with MixTeen, a special event during the second afternoon, where they can discover programming with <a href="https://scratch.mit.edu">Scratch</a>, and make their own games.
With demonstrations to all attendees at the end of the conference !</p>
<h1 id="change-mind-about-javascript">Change mind about JavaScript</h1>
<p>At work, in my team, we had used <a href="http://es6-features.org" target="\_blank">ES6</a> since January 2014 with <a href="https://github.com/google/traceur-compiler" target="\_blank">Traceur</a> transpiler, and I really whished to do a feedback.
As the company is intensively using Java, it had always been difficult to promote JavaScript, always seen as a toy for web kids.
Even with an almost ten years experience on medium and big size projects, it seems to be not enough to be taken seriously.</p>
<p>But with ES6 comes classes, modules and arrow functions, which are 3 things that may cut the grass under feet of grumpy java advocates.
I use JavaScript since 2006, and learned that classes and inheritance are not always the best choice for programming.
But they remain concepts that (in France) make developers feel more… serious.</p>
<p>This talk was firstly the occasion to attract JavaScript haters, and perhaps make them revised their opinion.
So I gave it at <a href="http://worldline.com/fr/accueil.html" target="\_blank">Worldline</a>, to show how the language was evolving, and to convince that working with Node.js in ES6 was a serious alternative to Java in some cases.
And I had the chance to give it at <a href="http://www.mix-it.fr/session/1351/changez-d-avis-sur-javascript">Mix-IT</a>, to touch a wider audience, probably in the same situation in their own companies.</p>
<h1 id="the-talk-itself">The talk itself</h1>
<p>My first intention was to give that conference at Mix-IT 2014, which was a bleeding edge topic.
But that spring, my daughter was born, and I can’t even attend to the conference.</p>
<p>One year later, plethora of blogs had posted on the subject.
So my strategy to innovate was to take a real project example that use ES6 main features, and to do a bit of storytelling.</p>
<p>In the project I was working for, I had written a small long-running jobs orchestrator, nammed “pilot”.
Based upon two simple classes (Task and Parallel), we used it to make data workflows involving several distributed jobs written in <a href="http://scala-lang.org" target="\_blank">Scala</a> with <a href="http://spark.apache.org" target="\_blank">Spark</a>.</p>
<div class="centered">
<figure class="card">
<img src="http://feugy.github.io/image/change-mind-about-js-1.jpg" alt="Pilot's internal classes, extended by specific business classes" />
<figcaption class="caption">
<p>Pilot’s internal classes, extended by specific business classes</p>
</figcaption>
</figure>
</div>
<p>For the demonstration, I’ve implemented a small workflow to retrieve <a href="http://www.chucknorrisfacts.fr" target="\_blank">Chuck Norris facts</a> (through an API) in parallel and sort them by popularity.
By describing the implementation of those classes, I gave example of use for:</p>
<ul>
<li>modules</li>
<li>classes & inheritance</li>
<li>arrow functions</li>
<li>block scoping and destructuring</li>
<li>default parameters and literal objects short syntaxes</li>
<li>rest and spread operators</li>
<li>for-of loop and Array new methods</li>
<li>string interpolations</li>
</ul>
<p>Of course, I did not had time to show examples for Promises, Generators, new collections, Proxies…</p>
<div class="centered">
<figure class="card">
<iframe src="//fr.slideshare.net/slideshow/embed_code/key/dolxjkiP6bhwc3" width="430" height="361" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; max-width: 100%;" allowfullscreen=""> </iframe>
<figcaption class="caption">
<p>Talk’s slides (in French)</p>
</figcaption>
</figure>
</div>
<p>A video was published on <a href="http://www.infoq.com/fr/presentations/changez-avis-sur-javascript" target="\_blank">infoQ</a>, but unfortunately slides are not synchronized with audio track.
The audience had seemed to appreciate the talk, even if I spoke a bit too much before lunch.</p>
<div class="centered">
<figure class="card">
<img src="http://feugy.github.io/image/mixit-2015.png" alt="The audience's feedback" />
<figcaption class="caption">
<p>The audience’s feedback</p>
</figcaption>
</figure>
</div>
<p>Code is available on <a href="https://github.com/feugy/change-mind-about-js" target="\_blank">github</a></p>Damien Simonin FeugasThe Mix-IT conferenceRock the Web with Node.js2015-02-15T00:00:00+00:002015-02-15T00:00:00+00:00http://feugy.github.io/rock-the-web-with-nodejs<p><em>Work in progress</em></p>
<p>http://feugy.github.io/rock-the-web-with-nodejs
https://github.com/feugy/rock-the-web-with-nodejs</p>Damien Simonin FeugasWork in progress