<?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: Matthias Hryniszak</title>
    <description>The latest articles on DEV Community by Matthias Hryniszak (@padcom).</description>
    <link>https://dev.to/padcom</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%2F354419%2F9fa88359-32aa-44dc-beaa-58569c0e83dc.jpeg</url>
      <title>DEV Community: Matthias Hryniszak</title>
      <link>https://dev.to/padcom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/padcom"/>
    <language>en</language>
    <item>
      <title>Why AI will never replace software developers</title>
      <dc:creator>Matthias Hryniszak</dc:creator>
      <pubDate>Thu, 05 Mar 2026 01:05:36 +0000</pubDate>
      <link>https://dev.to/padcom/why-ai-will-never-replace-software-developers-4pj1</link>
      <guid>https://dev.to/padcom/why-ai-will-never-replace-software-developers-4pj1</guid>
      <description>&lt;p&gt;So we are here. AIs like claude are threatening software developer's jobs. It is promised that "just coding" will be obsolete and solved with AI. It means that if you are a software developer you might want to be afraid if you will be able to pay your bills 2 months for now. After all, just like manual workers 50 years ago, your job is on the line. However.....&lt;/p&gt;

&lt;p&gt;Neither all factories are fully automated and a ton of people still work in factories. What the fuck just happened? We've been promised/told that industrialization will kill so many jobs! So why there are still so many people still working in assembly lines? Shouldn't we have been at a stage where being an assembly worker is pointless with automation taking over?&lt;/p&gt;

&lt;p&gt;Well, with all due respect for OpenAI CEO and all the backers of the AI movement, I have seen it in 1st person how incredibly immature, dull and stupid AI can be.&lt;/p&gt;

&lt;p&gt;To bottom it all up: if you are a software developer and have like 5+ years of XP under your belt you are at least 20 years safe to keep your job - if history has anything to say about it.&lt;/p&gt;

&lt;p&gt;If you've got 20+ years of XP as a software developer you will probably be paid more in the coming years than you can spend (if you are clever about it).&lt;/p&gt;

&lt;p&gt;And if you are, like me, one of the dinosaurs of software development, sky is the limit for what you can become in the coming years. The Nirvana just arrived. And as much as OpenIA, NVidia and others would like to see us being obsolete we are in a better shape than ever before.&lt;/p&gt;

&lt;p&gt;Keep on learning and you'll be fine.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>career</category>
      <category>discuss</category>
      <category>programming</category>
    </item>
    <item>
      <title>Vite config reuse</title>
      <dc:creator>Matthias Hryniszak</dc:creator>
      <pubDate>Thu, 25 Jul 2024 13:10:43 +0000</pubDate>
      <link>https://dev.to/padcom/vite-config-reuse-l3a</link>
      <guid>https://dev.to/padcom/vite-config-reuse-l3a</guid>
      <description>&lt;p&gt;Have you ever wondered how big a &lt;a href="https://vitejs.dev" rel="noopener noreferrer"&gt;Vite&lt;/a&gt; configuration file can get? What if you have a project with tens of workspaces? If any of the issues sound familiar - read on! There's something cool coming your way!&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing reusable Vite configurations
&lt;/h2&gt;

&lt;p&gt;As luck would have it, there is a function exported right from the &lt;code&gt;vite&lt;/code&gt; package called &lt;code&gt;mergeConfig()&lt;/code&gt;. It takes 2 arguments, essentially 2 fragments of Vite configuration and merges them together.&lt;/p&gt;

&lt;p&gt;Based on this we can create a base configuration to use for all our projects. For example, I like all my vite-based projects to have &lt;a href="https://eslint.org" rel="noopener noreferrer"&gt;&lt;code&gt;eslint&lt;/code&gt;&lt;/a&gt; enabled. Here's how you would define it:&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="cm"&gt;/**
 * @param {import('vite').UserConfig} overrides
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;defineBaseConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;overrides&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="nf"&gt;eslint&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;lintOnStart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;mergeConfig&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;overrides&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;Now, instead of importing &lt;code&gt;defineConfig&lt;/code&gt; from &lt;code&gt;vite&lt;/code&gt; you would import this function and define all your other configuration options (besides the &lt;code&gt;eslint&lt;/code&gt; plugin) as usual.&lt;/p&gt;

&lt;p&gt;All things being equal, here is how you could combine multiple functions to essentially build building blocks of configuration:&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="cm"&gt;/**
 * @param {import('vite').UserConfig} overrides
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;defineTestConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;overrides&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;config&lt;/span&gt; &lt;span class="o"&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="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;setupFiles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./vitest.setup.js&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="na"&gt;coverage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;enabled&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;reporter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&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="s1"&gt;lcov&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="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;mergeConfig&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;overrides&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @param {import('vite').UserConfig} overrides
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;defineDefaultConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;overrides&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;return&lt;/span&gt; &lt;span class="nf"&gt;defineBaseConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;defineTestConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;overrides&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;Now, whenever you need a Vite-based project with eslint and &lt;a href="https://vitest.dev" rel="noopener noreferrer"&gt;vitest&lt;/a&gt; all you need to do is to use the &lt;code&gt;defineDefaultConifg()&lt;/code&gt;, create the &lt;code&gt;vitest.setup.js&lt;/code&gt; in your main project and your configuration is done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ready-made configurations for you to use
&lt;/h2&gt;

&lt;p&gt;I'm a lazy man. Extremely lazy. I hate repeating myself. That's why I created those 4 packages that I can later on use in my projects:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@padcom/vite-config-default" rel="noopener noreferrer"&gt;@padcom/vite-config-default&lt;/a&gt; - for use in other configurations&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@padcom/vite-config-lib" rel="noopener noreferrer"&gt;@padcom/vite-config-lib&lt;/a&gt; - for use in TypeScript libraries&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@padcom/vite-config-vue" rel="noopener noreferrer"&gt;@padcom/vite-config-vue&lt;/a&gt; - for use in Vue.js applications&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@padcom/vite-config-vue-lib" rel="noopener noreferrer"&gt;@padcom/vite-config-vue-lib&lt;/a&gt; - for use in Vue.js libraries written in TypeScript&lt;/p&gt;

&lt;p&gt;They are written in plain JavaScript. You can easily navigate to their implementation in vscode to see what is being configured and how. The main thing that you might find odd is those configurations make use of the contents of your &lt;code&gt;package.json&lt;/code&gt; for a lot of things. That's why the first parameter is the package.json imported like so:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;pkg&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;./package.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;json }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then if you need a Vue.js library then simply:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineVueLibConfig&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;@padcom/vite-config-vue-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;pkg&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;./package.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&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="nf"&gt;defineVueLibConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all! Isn't it nice?&lt;/p&gt;

&lt;h3&gt;
  
  
  So is that really all I need to do?
&lt;/h3&gt;

&lt;p&gt;For Vite - yes. For your library - there is a little bit more to it, and it not because of vite, but because you're doing a library that exports things.&lt;/p&gt;

&lt;p&gt;First of all, you need a proper &lt;code&gt;exports&lt;/code&gt; definition for your library. The final build will reside in the &lt;code&gt;dist&lt;/code&gt; folder and will contain the following files, assuming your project's &lt;code&gt;name&lt;/code&gt; property is set to &lt;code&gt;shiny-components&lt;/code&gt;:&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;"shiny-components"&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;"module"&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="s2"&gt;"dist"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"README.md"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exports"&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;"."&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;"require"&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/shiny-components.umd.cjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"import"&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/shiny-components.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;"types"&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/types.d.ts"&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;"./dist/style.css"&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/style.css"&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;"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;"^3"&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;"@padcom/vite-config-vue-lib"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^0.2.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;"typescript"&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.1.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;"vite"&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.2.10"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"vitest"&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.5.2"&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;Please note, that each library you want your library to import but not bundle needs to be declared in &lt;code&gt;dependencies&lt;/code&gt;. Likewise, if you want your library to bundle another library then put it into &lt;code&gt;devDependencies&lt;/code&gt;. That is the reason why the &lt;code&gt;pkg&lt;/code&gt; needs to be passed on to &lt;code&gt;defineVueLibConfig()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And that is really all there is to it! Have fun creating your own configurations or using mine. Let me know how it made your projects more maintainable :)&lt;/p&gt;

&lt;p&gt;Have a nice day!&lt;/p&gt;

</description>
      <category>npm</category>
      <category>monorepo</category>
    </item>
    <item>
      <title>mrdr is born (from hell!)</title>
      <dc:creator>Matthias Hryniszak</dc:creator>
      <pubDate>Wed, 22 Nov 2023 22:01:59 +0000</pubDate>
      <link>https://dev.to/padcom/mrdr-is-born-from-hell-1i47</link>
      <guid>https://dev.to/padcom/mrdr-is-born-from-hell-1i47</guid>
      <description>&lt;p&gt;I've been doing node and frontend for years now. More than anything, it bugs me that some things that should be simple are so darn difficult. For example, setting up projects...&lt;/p&gt;

&lt;h2&gt;
  
  
  The bad
&lt;/h2&gt;

&lt;p&gt;Imagine you have a monorepo that contains a common library and two projects that use it. It makes perfect sense that you'd like them to be in dev mode at the same time, so that during development you can treat the whole thing as a whole. It's just easier to think about it this way...&lt;/p&gt;

&lt;h2&gt;
  
  
  The ugly
&lt;/h2&gt;

&lt;p&gt;There is a catch, though. You can't start the dev server for your apps until the common library is done. So what do you do? you start the build watch in one console and once that has finished you start the next console and run the build for your app1 and a third console for the second app.&lt;/p&gt;

&lt;p&gt;To say that it is tedious is like not saying at all.&lt;/p&gt;

&lt;p&gt;And then there's the final build...&lt;/p&gt;

&lt;p&gt;Of course, you can employ tools like &lt;code&gt;turbo&lt;/code&gt; for the final build (doesn't work for dev mode as you can't &lt;code&gt;dependOn&lt;/code&gt; persistent tasks!) and it works quite well, but then you ask yourself, why is that tool so stupid? If I already have a &lt;code&gt;build&lt;/code&gt; task in all my projects, why do I have to &lt;em&gt;again&lt;/em&gt; express that &lt;code&gt;build&lt;/code&gt; depends on &lt;code&gt;build&lt;/code&gt;? That's ridiculous, to say the least.&lt;/p&gt;

&lt;h2&gt;
  
  
  mrdr to the rescue!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/mrdr"&gt;&lt;code&gt;mrdr&lt;/code&gt;&lt;/a&gt; (pronounced appropriately /mordor/) is exactly what you would expect a runner like that to be. It &lt;em&gt;assumes&lt;/em&gt; that your build task is called &lt;code&gt;build&lt;/code&gt; and that your dev task is, well, called &lt;code&gt;dev&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When you have things laid out like that, all you need to do to start your dev environment is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx mrdr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and off you go. The &lt;code&gt;build -w&lt;/code&gt; will keep on running but once all the &lt;code&gt;exports&lt;/code&gt; are there, it will continue on with projects that depend on them.&lt;/p&gt;

&lt;h2&gt;
  
  
  It really is that simple!
&lt;/h2&gt;

&lt;p&gt;If you want to build your project &lt;em&gt;in order&lt;/em&gt; you run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx mrdr build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and life is good again. No more &lt;code&gt;wait-on&lt;/code&gt;, no more &lt;code&gt;turbo.json&lt;/code&gt;, no more hassle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;Although I wrote mordor myself there is a person that deserves recognition. Aleksej Dix pushed me to do it. I was thinking of it for a long time, hoping that some other person will do it instead, but he finally bugged me so much I've had to do it. Thank you, Aleksej, for being such a good friend!&lt;/p&gt;

</description>
      <category>npm</category>
      <category>monorepo</category>
    </item>
    <item>
      <title>Processing for the masses - p5js on steroids</title>
      <dc:creator>Matthias Hryniszak</dc:creator>
      <pubDate>Thu, 22 Jun 2023 22:46:14 +0000</pubDate>
      <link>https://dev.to/padcom/processing-for-the-masses-p5js-on-steroids-3h7j</link>
      <guid>https://dev.to/padcom/processing-for-the-masses-p5js-on-steroids-3h7j</guid>
      <description>&lt;p&gt;Very recently I have discovered &lt;a href="https://www.youtube.com/@TheCodingTrain"&gt;The Coding Train&lt;/a&gt; YouTube channel. At first, it was kinda weird for a moment, but after two or three videos I was completely sold! I wanted that power of &lt;a href="https://processingfoundation.org/projects"&gt;Processing&lt;/a&gt; for me! And I wanted it NOW!&lt;/p&gt;

&lt;p&gt;As usual in those nice, academic cases, tooling support is, let's just say, somewhat lacky. There is a &lt;a href="https://editor.p5js.org/"&gt;playground&lt;/a&gt; you can use to, well,... play around, but any sort of serious work requires a proper setup with TypeScript, ESLint, proper IDE support for in-place documentation and code completion. I don't think there's a single person on the planet that knows all there is to &lt;a href="https://p5js.org/reference/"&gt;Processing&lt;/a&gt;, is there?&lt;/p&gt;

&lt;p&gt;And so, now, ladies and gents... (drummroll) Badum-tss! Here it is! The all-mighty all-in-one with a cherry on top template you can use NOW!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm create -y from-github padcom/p5 hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You then need to install packages (as with any npm-enabled project):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd hello-world
npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and you're ready to start coding (assuming you do have vscode installed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;code .
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a matter of seconds, you're coding in a TS-enabled, ESlint-backed, full-blown development environment with features you never even dreamed about, but might also be quite familiar to you if you are a frontend developer. In essence, everything that &lt;a href="https://vitejs.dev/"&gt;Vite.js&lt;/a&gt; supports is supported.&lt;/p&gt;

&lt;p&gt;Ok, buuuuut... HOW MANY SECONDS?!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;padcom@padcom:~/learning/p5$ rm -rf ~/.npm hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this stage, my local installation is totally fresh, nothing's cached. So we go with the worst-case scenario:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;padcom@padcom:~/learning/p5$ time npm create -y from-github padcom/p5 hello-world
create-from-github version 0.0.4 by Matthias Hryniszak &amp;lt;padcom@gmail.com&amp;gt; 

cloning https://github.com/padcom/p5 ...
cloning https://github.com/padcom/p5-template ...
cleaning up hello-world ...
configuring hello-world ...
done.

real    0m5,003s
user    0m0,875s
sys 0m0,116s
padcom@padcom:~/learning/p5$ time npm i --prefix hello-world

added 165 packages, and audited 166 packages in 14s

36 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

real    0m14,205s
user    0m2,648s
sys 0m0,476s
padcom@padcom:~/learning/p5$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's about 20 seconds. I call that acceptable, especially that it will save me a lot of time later.&lt;/p&gt;

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

&lt;p&gt;But ok, you don't do that to have just one project, do you? You'd want to use that opportunity and start 10, 20 or a 100 small projects, some will live forever and ever, some will die 10 seconds after they were created.&lt;/p&gt;

&lt;p&gt;Here's how fast it is to create the next project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;padcom@padcom:~/learning/p5$ rm -rf hello-world
padcom@padcom:~/learning/p5$ time npm create -y from-github@latest padcom/p5 hello-world
create-from-github version 0.0.4 by Matthias Hryniszak &amp;lt;padcom@gmail.com&amp;gt; 

cloning https://github.com/padcom/p5 ...
cloning https://github.com/padcom/p5-template ...
cleaning up hello-world ...
configuring hello-world ...
done.

real    0m1,209s
user    0m0,603s
sys 0m0,054s
padcom@padcom:~/learning/p5$ time npm i --prefix hello-world

added 165 packages, and audited 166 packages in 1s

36 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

real    0m1,218s
user    0m1,529s
sys 0m0,307s
padcom@padcom:~/learning/p5$ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Less than 3s to have a new project ready to work. Sounds like a winner to me ;)&lt;/p&gt;

&lt;h2&gt;
  
  
  And the cherry on top I promised?
&lt;/h2&gt;

&lt;p&gt;How about in-editor debugging with step-by-step code execution?&lt;/p&gt;

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

</description>
      <category>p5js</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>We've got it all wrong!</title>
      <dc:creator>Matthias Hryniszak</dc:creator>
      <pubDate>Tue, 02 May 2023 01:37:27 +0000</pubDate>
      <link>https://dev.to/padcom/weve-got-it-all-wrong-2i9h</link>
      <guid>https://dev.to/padcom/weve-got-it-all-wrong-2i9h</guid>
      <description>&lt;p&gt;How many times have you heard: "We're only going to get the architect for the first X time of the project. Then he'll be 'on-demand'"? How many times (besides total fuckups, of course) did hi actually show to meetings?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is that the case?
&lt;/h2&gt;

&lt;p&gt;I think the main reason for this state of things is that there is somehow a notion that architecture is something that needs to be set in stone once, and then everything is built on top of it. There is somehow this connection to buildings and that once an architect has designed the building it stays throughout the build process.&lt;/p&gt;

&lt;p&gt;I hate to break it to you, but oh man is that metaphor false to the deepest levels of hell!&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison to building a house
&lt;/h2&gt;

&lt;p&gt;So let's say there are 4 stages to building a house:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;getting a land&lt;/li&gt;
&lt;li&gt;designing a house&lt;/li&gt;
&lt;li&gt;building it&lt;/li&gt;
&lt;li&gt;using it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you think about it, then building software is pretty-much the same - only the names are different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;securing founds&lt;/li&gt;
&lt;li&gt;building it&lt;/li&gt;
&lt;li&gt;deploying it&lt;/li&gt;
&lt;li&gt;profiting (hopefully!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, there is a difference in the two middle stages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Designing a house
&lt;/h3&gt;

&lt;p&gt;Traditionally, in the real estate business, changing a design from a block to a wing-based system is not a thing that's done very frequently. After all, once the general shape of it is set, everything else it built "on top of it".&lt;/p&gt;

&lt;p&gt;It's even less possible once the construction phase starts, and it turns out the entire groundwork needs to be undone, including the first and second floors of that 20 stories building. That would be madness, right?&lt;/p&gt;

&lt;p&gt;What if I told you that while you're living in your freshly built house, someone would scale it up and down depending on how many people are currently present? Or even depending on which room they're occupying. That's a mind-fuck, isn't it?&lt;/p&gt;

&lt;h3&gt;
  
  
  Designing a software
&lt;/h3&gt;

&lt;p&gt;Well, what if it wouldn't be that insane to think that you do have the possibility to redesign the general plan of the building, even change the number of floors dynamically and then to test, like "for real", if that meets the client's need?&lt;/p&gt;

&lt;p&gt;Guess what! That is &lt;em&gt;&lt;em&gt;exactly&lt;/em&gt;&lt;/em&gt; how software is done!!!&lt;/p&gt;

&lt;p&gt;So architects think they design something, and then it's like the basement and bricks - all set in stone. But in point of fact, it is very much not. It's subject to change just like every other part of the system, be it a single line in a back-water services or the key optimization of the company's most treasured secret AI whatever.&lt;/p&gt;

&lt;p&gt;And if it isn't...&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture is just code
&lt;/h2&gt;

&lt;p&gt;Countless times, I'm asked to draw pretty pictures of the architecture of a system I work on. I have no idea how is that going to help anyone understand what I need them to do if they don't even understand how a simple &lt;code&gt;for&lt;/code&gt; loop works, but hey - the customer wants, the customer gets.&lt;/p&gt;

&lt;p&gt;The problem with that is, that the non-tech guys trying to understand the grand design do think about it as the architecture plan of a house. It is not. It is not a house we're building here. Just please, get over it, m'key?&lt;/p&gt;

&lt;p&gt;Now that we have that out of the way, I need to make sure we are on the same page here:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Architecture is the result of all coding activities, both heavenly-inspired and hellishly-guided. It doesn't matter who told you otherwise. No amount of pretty pictures will ever give you an accurate insight into an architecture of a system than the code itself. That is where The Architecture is. And it needs to change!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The goal of an architecture
&lt;/h2&gt;

&lt;p&gt;It is my strong belief that coding is not only an art. It is a mixture of both craftsmanship and art.&lt;/p&gt;

&lt;p&gt;As such, software development takes skills, out-of-the-box thinking, but also professionalism and modesty. I don't care if you're the CTO of some company or a junior that just joined. If you're wrong, and you can be proven wrong, then you're wrong. It will surface sooner rather than later.&lt;/p&gt;

&lt;p&gt;That adheres most of all to architects. From my experience, those are guys that join a project in the beginning for a few days, set up some scaffolded horse manure, shout how "XYZ has taken over the world of software development and it &lt;em&gt;sexy&lt;/em&gt; it will all be". Then they unload a whole pile of crap onto a team that has no idea what the actual fuck is going on. Weeks from then, the team has finally gotten rid of the bullshit introduced by the highly paid individual, but they're so bored with the project that even the newest toys don't motivate them to work on the project anymore. In other cases, the architect was so messed up the project, even though perfectly doable in the allotted time, will either stretch or be abandoned all together, causing investors to lose money.&lt;/p&gt;

&lt;p&gt;It's sad, but true. Just look at the rate people change jobs in IT. It's madness!!!&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture is in the code
&lt;/h2&gt;

&lt;p&gt;Ok, you might say that we don't have architecture in how the services are deployed or how they run on the server. First of all, that's no longer true if you use something like &lt;code&gt;docker&lt;/code&gt; with &lt;code&gt;docker-compose&lt;/code&gt; or k8s, and with that, you can again start thinking in a bigger picture - the architecture level.&lt;/p&gt;

&lt;p&gt;But does that mean you can't add/remove services? Well... you can! And you can't - if you want your system to remain stable. That's a common problem in software development called "dependencies" and has been solved like in a million different ways. Why is that still a problem with the architecture?&lt;/p&gt;

&lt;p&gt;I think it is a mental problem, not a technical one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Properties of a system's architecture
&lt;/h2&gt;

&lt;p&gt;We can reason about code. We can spot code-smells, review the changes being introduced, and all that &lt;em&gt;corpo-nonsense&lt;/em&gt; we do to make sure that even if this is the one day in your life you were not thinking straight, there will be someone watching your back. That's how professionals do things.&lt;/p&gt;

&lt;p&gt;But that means that if you think about architecture as part of the code, then for example, introducing a dependency on another system shouldn't be the architect's decision. It should be the architect's initiative before anyone even started asking about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's get technical
&lt;/h2&gt;

&lt;p&gt;So, I hear you say: "if architecture is in the code, does it mean that it can be refactored?". And the answer is obviously a big, fat "Yes!". The only difference is that, on that level, you don't deal with concrete classes and direct inter-object relations. You deal with subsystems, concepts, lines of inheritance and inter/extra-system communication rather than discrete implementations of some subsystem's internal caching &lt;em&gt;whatever&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That means that there does not exist a generic programming language that would be "for the architects". There are concepts, architectural guidelines that indeed can and always are implemented in a general-purpose language, but it's often so convoluted that the meaning of it is completely lost in the mud.&lt;/p&gt;

&lt;p&gt;That is a sign of bad architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Refactorings
&lt;/h3&gt;

&lt;p&gt;Here are some examples of refactorings that I would put in the "architectural changes":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;extracting a separately hosted service from another application&lt;/li&gt;
&lt;li&gt;moving a responsibility from one hosted service to another&lt;/li&gt;
&lt;li&gt;removing dependency on a service&lt;/li&gt;
&lt;li&gt;sunsetting services&lt;/li&gt;
&lt;li&gt;introducing a range of services with a common theme&lt;/li&gt;
&lt;li&gt;refactoring services to line-up with a common theme of other services&lt;/li&gt;
&lt;li&gt;maintaining service lifespan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now imagine there's a developer, that has a library that has named exports and proper in-line docs, and he'll just interact with those classes. They will indeed do the architectural things, like spawning new services and the like.&lt;/p&gt;

&lt;p&gt;Now imagine that developer being is asked to introduce a new type of service the company just produced/bought. It has a foreign interface, so you use the design patterns at your disposal to connect it to the rest of the system.&lt;/p&gt;

&lt;p&gt;It's still coding. It always have been. It always will be.&lt;br&gt;
No matter what everyone else will tell you.&lt;/p&gt;

&lt;p&gt;It's just the libraries are different and sometimes things are better expressed using a DSL or as a graph of objects (say a yaml file) than code in some "proper" programming language.&lt;/p&gt;

&lt;p&gt;But it is still code. It needs to be maintained. It needs to be kept on-par with what the rest of the project needs. And if something's is wrong with it, it needs an architect to fix it. And believe me, once you realize that all that is just code, you won't believe how many refactorings your architecture will need and how much more effective your teams will be!&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing thoughts
&lt;/h2&gt;

&lt;p&gt;Having said all that above, I think teams leveraging a coding, in-team architect stand a much better chance of success. Not only will the rapid response force be there all the time when you need it, but your other guys will have someone to learn from, to guide them. If you only allow your "best guys" to dump a truck load of horse manure on the devs and leave, don't expect them to eat that shit and be happy about it.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Inspired by &lt;a href="https://www.youtube.com/watch?v=9A9ZxIrc9CE"&gt;https://www.youtube.com/watch?v=9A9ZxIrc9CE&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>development</category>
      <category>architecture</category>
      <category>refactoring</category>
      <category>foodforthought</category>
    </item>
    <item>
      <title>Working with streams in Node.js</title>
      <dc:creator>Matthias Hryniszak</dc:creator>
      <pubDate>Sun, 09 Apr 2023 11:52:02 +0000</pubDate>
      <link>https://dev.to/padcom/working-with-streams-in-nodejs-288f</link>
      <guid>https://dev.to/padcom/working-with-streams-in-nodejs-288f</guid>
      <description>&lt;p&gt;When working with streams one of the coolest things ever is using async generators to do piped processing. Let's start with a simple example that generates numbers from 1 to 5:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&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;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&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 generator yields 5 numbers, 0 through 4, as strings. Let's pipe them through to see them on the screen:&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;Readable&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;numbers&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boom! Just like that, we're printing the content of the stream to standard output. Let's see how we can do the printing using &lt;code&gt;console.log()&lt;/code&gt;:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AsyncGenerator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;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;for&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;source&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="kr"&gt;number&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;Readable&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;numbers&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Duplex&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;logger&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resume&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The call to &lt;code&gt;Readable.resume()&lt;/code&gt; at the end makes the stream pull all the values and process them.&lt;/p&gt;

&lt;p&gt;What's interesting here is that we're using a &lt;code&gt;Duplex&lt;/code&gt; stream created from an async generator. Since it is a &lt;code&gt;Duplex&lt;/code&gt; stream (so &lt;code&gt;Readable&lt;/code&gt; and &lt;code&gt;Writeable&lt;/code&gt;) we can still process the data further. For example, we can augment the numbers with some description:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;augmenter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AsyncGenerator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;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;for&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="s2"&gt;`This is number &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="kr"&gt;number&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="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;Readable&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;numbers&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Duplex&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;augmenter&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Duplex&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;logger&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resume&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please note that the &lt;code&gt;source&lt;/code&gt; argument to all the generators have a generic type, that will determine the type of element we are iterating over. In our case, the generic type is &lt;code&gt;string&lt;/code&gt; so the &lt;code&gt;number&lt;/code&gt; variable is of type &lt;code&gt;string&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;I think that's totally cool - how about you?&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>node</category>
      <category>streams</category>
    </item>
    <item>
      <title>Pipes! Pipes everywhere!</title>
      <dc:creator>Matthias Hryniszak</dc:creator>
      <pubDate>Tue, 28 Mar 2023 08:40:18 +0000</pubDate>
      <link>https://dev.to/padcom/pipes-pipes-everywhere-2moo</link>
      <guid>https://dev.to/padcom/pipes-pipes-everywhere-2moo</guid>
      <description>&lt;p&gt;I love small bits that do great things. This time it's about adding the &lt;code&gt;pipe()&lt;/code&gt; method to any object, e.g.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;items&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;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&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;sumPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&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;price&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pipeable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sumPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And on and on, you can pipe the result of one callback to another, with the first callback receiving the pipeable value.&lt;/p&gt;

&lt;p&gt;Now, how do we type this so that it makes sense in TypeScript?&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Pipeable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;I&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;O&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;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;I&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;Pipeable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Having the type definition of the &lt;code&gt;Pipeable&lt;/code&gt; type let's try to implement it:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;pipeable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;I&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;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;I&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&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="nx"&gt;result&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error: object is already pipeable&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pipeableResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Pipeable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;I&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;pipeableResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pipe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;O&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;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;I&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;pipeable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;O&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;transform&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;I&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;Pipeable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;I&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on your needs, &lt;code&gt;clone&lt;/code&gt; can either have a trivial implementation like this one:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;clone&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;T&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;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&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;or, you could go full on with packages such as &lt;a href="https://www.npmjs.com/search?q=keywords:clone-deep"&gt;clone-deep&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>nano-pinia</title>
      <dc:creator>Matthias Hryniszak</dc:creator>
      <pubDate>Sun, 12 Mar 2023 02:21:19 +0000</pubDate>
      <link>https://dev.to/padcom/nano-pinia-4fk5</link>
      <guid>https://dev.to/padcom/nano-pinia-4fk5</guid>
      <description>&lt;p&gt;One of the best qualities of Pinia is that it is actually a way to properly implement the singleton pattern. You define it as a function that always returns the same value.&lt;/p&gt;

&lt;p&gt;I thought, since Vue already exposes the reactivity system as  a separate package, can I implement singletons just like Pinia does - just without Pinia? What if I chose to only use the composition API?&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;defineSingleton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cb&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;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cb&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="nx"&gt;state&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it - nano-pinia in 4 lines or less :).&lt;/p&gt;

&lt;p&gt;You use it just like you would use Pinia:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineSingleton&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&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;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;incY&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&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="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;incY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// use the store instance directly&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="c1"&gt;// or destructure the content&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;incY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;incY&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// it doesn't matter - it's a singleton&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="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// outputs: 8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think it's cool that you can do that with so little effort :) And it's a nice example of how to use closures - but who cares, right?&lt;/p&gt;

</description>
      <category>vue</category>
      <category>pinia</category>
    </item>
    <item>
      <title>What's so difficult about being a software developer in 2023?</title>
      <dc:creator>Matthias Hryniszak</dc:creator>
      <pubDate>Tue, 31 Jan 2023 20:08:18 +0000</pubDate>
      <link>https://dev.to/padcom/whats-so-difficult-about-being-a-software-developer-in-2023-ejf</link>
      <guid>https://dev.to/padcom/whats-so-difficult-about-being-a-software-developer-in-2023-ejf</guid>
      <description>&lt;p&gt;A lot of interesting events happened lately. Big companies letting people go, even if they were with the company for a long time. Shocking as it is, it's been a long time coming. Software development is hard, really hard. It's not a hammer and chisel that you'd need a year to master, 5 years to become a master craftsman and a lifetime to become an artist. Programming isn't a form of art. It's more a craft than anything else. It takes time, effort and a tiny grain of talent - like anything else.&lt;/p&gt;

&lt;p&gt;But how complex is it, actually?&lt;/p&gt;

&lt;h2&gt;
  
  
  Complexity for the rest of us
&lt;/h2&gt;

&lt;p&gt;I find that generally speaking, putting things into perspective helps people understand the meaning of something. That tends to sink in better. Most adults use some form of mechanical transportation like a bike, scooter, car or plane. Let's use that to our advantage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning curve
&lt;/h3&gt;

&lt;p&gt;Learning to &lt;em&gt;make the computer do what we need it to do&lt;/em&gt; on the most basic level takes about the same as learning to drive a motorbike. I don't mean passing the driver's license exam, but just basic handling, maybe switching gears and turning without visiting the hospital. It's not impossible, but takes time and effort. Funny enough, young people seem more courageous. It is just easier to learn to drive a motorbike on your friend's rusty old-timer when you're 15. There's a lot of fun in the process, which helps a lot to get it right. Even if you trip and fall, the worst thing that can happen in such a controlled environment will be &lt;a href="https://www.youtube.com/watch?v=aRncrzyD5R4"&gt;&lt;em&gt;a few broken dishes&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It feels like you could conquer the world! Then you learn that besides just going straight and around the block, there are rules you need to follow to limit the chance of messing things up. You learn to pass the exam and if you've spent enough time learning you will succeed. Once you're allowed to take off on your own for the first time, all of a sudden, the motorbike has like 200 HP and can do wheelie for miles on end. That, however brief, fascination either ends with someone dead or scarred enough to stop being irresponsible. That's when you either learn or fail. Generally speaking, youth goes by its own set of rules that rarely carry on into adulthood.&lt;/p&gt;

&lt;p&gt;Once you get a bit older, a car is more what you need. So, you learn and practice passing the driver's license. This, as all drivers will tell you, doesn't make you a racing driver - far from it. Suddenly, you go slower than the motorbike, but you also carry more passengers. The responsibility rises and so does your insurance cost. In many countries, there are additional rules for drivers with less than a year of experience that include speed limits, number of passengers. In extreme cases, for the first 6 months, you might be required to have a seasoned driver to always be present in the car. You know, just to keep you safe in those rare cases you'll panic, close your eyes and let it happen. That should eliminate the urge to go all &lt;em&gt;pedal to the metal&lt;/em&gt;, but we've all been there, and we've all done it, didn't we? Just this one time to see if it will do 160, empty road, no one in sight, YOLO!&lt;/p&gt;

&lt;h3&gt;
  
  
  Congratulations! You're a junior!
&lt;/h3&gt;

&lt;p&gt;Then there's a period of &lt;em&gt;I know I'm in control&lt;/em&gt;, where you don't really think about everything you do. Instead, you let your muscle memory take over. You operate on a whole new level. You're turning the car, shifting gears in the process and accelerating - all at the same time without even thinking about it. It's all so natural, cool and easy. Switching from one car to another does take a bit of effort, but it is generally possible to even switch between different transmission types (and then to realize what an idiot you were &lt;em&gt;sticking to the stick&lt;/em&gt;) and it's not that big of a deal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Congratulations! You're a software developer!
&lt;/h3&gt;

&lt;p&gt;I'd say that most people will end their passion for driving there. There are more important things in life than realizing your youth passion for becoming the next Michael Schumacher. Not only is racing kind of dangerous, but it's also costly. And it requires significant effort to be any good at it.&lt;/p&gt;

&lt;p&gt;But then there are situations in life where you need to go to the UK, rent a car and go to The City. Well, my friend, that's a whole different story. Nothing works the same, muscle memory works against every instinct you have. It's a horror! And then &lt;em&gt;they&lt;/em&gt; come right at you! Crazy people those Brits are! (I love you guys, you know that, right? &amp;lt;3). But if you do it slowly, step by step, your muscles will learn. It takes a while to get the basics off the ground. For example, the driver's seat is on the other side of the car, go figure! I dare you to try to not make that mistake the first time you'll be getting in. It's a bit funny, enlightening, stressful, but at the same time interesting and rewarding once you give it some time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Congratulations! You just discovered the other side! (backend/frontend)
&lt;/h3&gt;

&lt;p&gt;You are still not Robert Kubica, you're a responsible citizen after all, but you can easily drive anywhere in the world. Nothing can stop you, and it feels fucking outstanding! That does mean something. It's been a long road so far, but the reward is worth the effort.&lt;/p&gt;

&lt;p&gt;In some rare cases, you might want to make a living driving a truck. That's a cool idea, definitely not for everyone, but it pays the bills. Training is a bitch, costs a fortune and the exam is really hard. After you pass it, you don't have enough practice, but you know the rules, and you can consciously apply them to your daily routine. It's still stressful to park at the ramp, but with each time, you get more and more used to the procedures, red tape and people around you. Then, one day, you feel it's almost effortless. You make more and more money and life gets easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Congratulations! You just became a senior developer!
&lt;/h3&gt;

&lt;p&gt;You probably work on your own, using some kind of distributed system to find people you can carry transport for. At this point, it isn't so much about the driving, but more about handling the business. You just became a businessman, so all of a sudden your taxes look differently, you've got options you didn't have before.&lt;/p&gt;

&lt;p&gt;For example, you now could lease more cars, hire more drivers and expand the business. It really requires great effort, and very seldom people get to run a million-dollar enterprise. But if you do, you're the architect of your own success. You can effectively communicate with all kinds of people, you're responsible enough not to do crazy moves that will cost you, or your company, its existence. You need to coordinate a ton of things, and you wouldn't believe how crazy some situations can get! If you and your business survive for a few years and keeps growing, you are among the lucky ones.&lt;/p&gt;

&lt;p&gt;All glory be to you!&lt;/p&gt;

&lt;h3&gt;
  
  
  Congratulations! You just became an architect!
&lt;/h3&gt;

&lt;p&gt;You don't drive anymore, and if then very seldom, constantly on the phone, keeping the business going.&lt;/p&gt;

&lt;p&gt;To keep things simple, let's follow that story to the end where your company grew beyond your wildest dreams, you now are the boss of all bosses and don't really work anymore. You're there, but the business is so well-designed it rarely, if ever, requires your immediate intervention. You're more responsible for the overall direction where the company should go. If it should grow or shrink, whether the fleet should go all electric or not. Those are the &lt;em&gt;important&lt;/em&gt; or &lt;em&gt;live changing&lt;/em&gt; decisions that you are uniquely suited to make.&lt;/p&gt;

&lt;h3&gt;
  
  
  Congratulations! You just became the chief architect!
&lt;/h3&gt;

&lt;p&gt;As you can see, up to a given level there are rules that when followed keep you on the rails. Some of those rules you will break, that's inevitable. With time, you'll learn the consequences of your choices. It's not something you can learn from someone. I mean, of course that'd be absolutely wonderful if we could transplant clones of individual synapses from someone &lt;em&gt;who's been there and done it&lt;/em&gt;, but that's not how the world works. &lt;strong&gt;We learn by failing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;At one point, you might want to give someone advice that'll save them a ton of time and produce exceptional results, but it's rarely the case the person will actually follow it. They are in a different place and this advice might plain and simple be no good for them. With time, you learn how to &lt;em&gt;sell your ideas&lt;/em&gt;, maybe you could become active with the local community, give a bit back to the world. After all, it feels great to help others! It feels like you can cure world hunger, AIDS and syphilis - all before lunch, with plenty of time for an afternoon golf session with the prime minister. Now, that you have a lot more time on your hands, it seems to be an adequate option for your personal growth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Congratulations! You just became a mentor!
&lt;/h3&gt;

&lt;p&gt;That's the end of the story. The last thing is to realize where the industry is at, given the analogy.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;half of the developers have less than five years of any kind of experience, that includes the basics, maybe up to the trial period of 6 months of driving under supervision&lt;/li&gt;
&lt;li&gt;about 85% of developers are incapable of creative thinking&lt;/li&gt;
&lt;li&gt;about 75% of developers are incapable of constructive problem-solving&lt;/li&gt;
&lt;li&gt;nobody learns from technical literature anymore because there is no time for it. The industry learns from documentation that is half-baked and rushed to production, but has ready to copy and paste examples that you can tailor to your needs. Plus, the books are difficult to understand if you lack the basics&lt;/li&gt;
&lt;li&gt;the industry drastically overestimates candidates during interviews. It is not uncommon to hire someone right off the school as a senior, just because&lt;/li&gt;
&lt;li&gt;it pays a lot, everyone wants to make &lt;em&gt;easy&lt;/em&gt; money, and...&lt;/li&gt;
&lt;li&gt;the demand for new software is ridiculous!&lt;/li&gt;
&lt;li&gt;on top of all this, every damn car handles completely differently and is obsolete after you've learned to get it off the ground. Some drive forward, some drive forward and backwards, and some fly sideways and upside down. Literally. And there is a new model every 5 minutes, that you need to be able to handle or else you won't find a job.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Closing thoughts
&lt;/h2&gt;

&lt;p&gt;There are and always will be people who at a young age, through their brilliant minds and hard work, achieve fantastic results. But that is not everybody and is indeed an exception signifying the rule. You can always learn more, you can always get better, but that comes at a cost of time, blood and sweat and tears, and &lt;strong&gt;not&lt;/strong&gt; because you just want it to happen.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Type-safe object builder in TS</title>
      <dc:creator>Matthias Hryniszak</dc:creator>
      <pubDate>Mon, 24 Oct 2022 22:31:05 +0000</pubDate>
      <link>https://dev.to/padcom/type-safe-object-builder-in-ts-295e</link>
      <guid>https://dev.to/padcom/type-safe-object-builder-in-ts-295e</guid>
      <description>&lt;p&gt;Long story short - object builder pattern in TypeScript :)&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Builder&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Source&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Target&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;Prop&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;Required&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Source&lt;/span&gt;&lt;span class="o"&gt;&amp;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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Source&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Prop&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Builder&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Target&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Target&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This type defines an object that will have methods of the same name as the &lt;code&gt;Source&lt;/code&gt; object plus the &lt;code&gt;build()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Here's an implementation thereof using Proxy:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;clone&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;T&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;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;T&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;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
  &lt;span class="nx"&gt;Source&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Target&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;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;convert&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;clone&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Builder&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Target&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;proxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Proxy&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Builder&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Target&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;prop&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="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;)&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="nx"&gt;prop&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;build&lt;/span&gt;&lt;span class="dl"&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;build&lt;/span&gt;
      &lt;span class="k"&gt;else&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;prop&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;Source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Target&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;convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="na"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;Source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;
  &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Builder&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Target&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;source&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;proxy&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;proxy&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here's how you could use it:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;source&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;o1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;o2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&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;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="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each call to the builder methods is type-safe so it should be easy to work with it :)&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>oop</category>
    </item>
    <item>
      <title>Software Development Myths</title>
      <dc:creator>Matthias Hryniszak</dc:creator>
      <pubDate>Tue, 18 Oct 2022 13:28:11 +0000</pubDate>
      <link>https://dev.to/padcom/software-development-myths-1hih</link>
      <guid>https://dev.to/padcom/software-development-myths-1hih</guid>
      <description>&lt;p&gt;Have you, as a software developer, ever been told &lt;em&gt;you have to&lt;/em&gt; know the business? That you have to dive deep, and you have to understand the client's needs?&lt;/p&gt;

&lt;p&gt;Well, I in my 30 years of experience, have obviously heard that time and time again. Pretty much every single time I change projects or jobs, I hear the same thing from both product people as well as from devs that have already been working on the product for years. And I flat out disagree with it. Here's why.&lt;/p&gt;

&lt;h2&gt;
  
  
  Required skills
&lt;/h2&gt;

&lt;p&gt;So when you look for a new position you're seldom, if ever, asked about your business knowledge. You're harassed over and over again about frameworks, SOLID, DRY, TDD and what not but the questions about the business area are always left as "ok, so you seem worthy and here's what we actually do". Nobody is actually asking if you know how the planes work or how the financial sector works, because the assumption is that you either "should just know it" or "you'll learn".&lt;/p&gt;

&lt;h2&gt;
  
  
  How about other professions?
&lt;/h2&gt;

&lt;p&gt;That assumption alone is just crazy. You wouldn't expect a dentist to know how to treat heart disease, let alone how to sell houses, but you'd still expect the teeth to be fixed if it is broken. That is what you pay for. It'd be actually hilarious to come to the doctor and tell him you have problems at work and expect that doctor to tell you anything that would help you. It's not what doctors do. They heal people's bodies. Of course, there are doctors that heal the brains too, but anyone who has seen a shrink knows they don't know shit about the job you do. Their preoccupation is your brain, not your work. Even if the problem is connected, the shrink won't help you solve that problem, but rather will help you help yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what about devs?
&lt;/h2&gt;

&lt;p&gt;Why then developers, that deal with code, not with cars, planes, houses, and whatever else, are supposed to be experts at this or that business domain? The answer is, just like with doctors, they are not. Developers will, naturally, assimilate a portion of how the business works while working on a project, but that's accidental knowledge. To put it bluntly: if you want a dev that knows everything about the business, you need to train a non-developer that knows it to become a developer. There is no other way around it.&lt;/p&gt;

&lt;p&gt;Sure, sometimes you'll find a guy that likes coding and has a kick for, let's say, aviation. It's a sexy topic on its own, so it's not that unheard of to meet people interested in both. And that's true for every business out there. But it is, and has rarely been, a point of interest for recruiters. I have never heard of a candidate that was rejected because of lack of knowledge about some business area...&lt;/p&gt;

&lt;h2&gt;
  
  
  So what's a dev to do?
&lt;/h2&gt;

&lt;p&gt;The myth about developers having to learn about the business is just rude and impolite towards the devs because it treats the skills that we have as second-grade. Let me remind you that in 99% of the interview questions you won't find anything about the business itself. It's all technical.&lt;/p&gt;

&lt;p&gt;The way to go is to have realistic expectations. If you need a person that knows, for example, what a hospital patient needs then you should ask someone who is directly involved with patients - not a guy who 6 months ago was writing a game about slashing zombies. The dev will know how to present the scanned image in a 1000 different ways, but in reality all of them are equally good. It is in the hands of whoever knows the business to figure it out and it is in the very capable hands of the developer to make sure whoever comes next will understand what the fuck you meant when writing code that translates business requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Punchline
&lt;/h2&gt;

&lt;p&gt;For you, as a developer, it makes all the sense in the world to learn about programming. It's a tool you get paid to use and the better you are at it the more you will be paid. It is that simple.&lt;/p&gt;

&lt;p&gt;If, by any chance, you get interested in the area you work with - even better. Expecting that every developer will do that is just hilariously misguided and will render the codebase you work on useless due to lack of technical skills. I've seen it done a number of times specifically because the devs working on it were just very poor at actually programming.&lt;/p&gt;

&lt;p&gt;As for the rest of us... Just keep doing what you do best. Someday the world will understand that a doctor is not a police officer and a developer is not a business expert.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>mythbusters</category>
    </item>
    <item>
      <title>Using an F405 flight controller with INav and Arducopter - Serial ports</title>
      <dc:creator>Matthias Hryniszak</dc:creator>
      <pubDate>Thu, 24 Feb 2022 03:14:16 +0000</pubDate>
      <link>https://dev.to/padcom/using-an-f405-flight-controller-with-inav-and-arducopter-serial-ports-gpf</link>
      <guid>https://dev.to/padcom/using-an-f405-flight-controller-with-inav-and-arducopter-serial-ports-gpf</guid>
      <description>&lt;p&gt;It is a bit confusing what to put where when connecting an F405 (like Matek F405-STD). Here's my proposal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;USART3 - CRSF&lt;/li&gt;
&lt;li&gt;UART4  - MSP&lt;/li&gt;
&lt;li&gt;USART1 - GPS&lt;/li&gt;
&lt;li&gt;UART2  - OpFlow&lt;/li&gt;
&lt;li&gt;UART5  - TBS SmartAudio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hope it helps :)&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
