<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Publiczne prywatne notatki Andrzeja</title>
  <subtitle>Miejsce na przemyślenia, które mogą przydać się więcej niż jednej osobie.</subtitle>
  <link href="https://blog.wodkiewi.cz/feed.xml" rel="self"/>
  <link href="https://blog.wodkiewi.cz/"/>
  <updated>2026-05-31T19:07:00.000Z</updated>
  <id>https://blog.wodkiewi.cz/</id>
  <author><name>Andrzej Wódkiewicz</name></author>
  <entry>
    <title>Kompendium świeżoupieczonego rodzica</title>
    <link href="https://blog.wodkiewi.cz/posts/kompendium-rodzica/"/>
    <updated>2026-05-31T19:07:00.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/kompendium-rodzica/</id>
    <content type="html">&lt;p&gt;Lista formalności, o których warto wiedzieć, szykując się na przyjście dziecka. Możliwe, że niektóre z poniższych sekcji będą kiedyś rozwinięte jako osobne notatki.&lt;/p&gt;
&lt;p&gt;tl;dr:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;wizyty położnej&lt;/li&gt;
&lt;li&gt;zgłoszenie do USC&lt;/li&gt;
&lt;li&gt;zgłoszenie do ZUS/NFZ&lt;/li&gt;
&lt;li&gt;wybór POZ&lt;/li&gt;
&lt;li&gt;zasiłki&lt;/li&gt;
&lt;li&gt;urlopy&lt;/li&gt;
&lt;li&gt;wyprawka&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Lista&lt;/h1&gt;
&lt;h2&gt;Wizyty położnej środowiskowej&lt;/h2&gt;
&lt;p&gt;Położna ma za zadanie opiekować się kobietą w ciąży, a po porodzie sprawdzić stan zdrowia noworodka, jak i samej kobiety w połogu. Żeby dowiedzieć się więcej &lt;em&gt;u źródła&lt;/em&gt;, polecam sprawdzić stronę rządową: &lt;a href=&quot;https://pacjent.gov.pl/system-opieki-zdrowotnej/jakie-sa-kompetencje-poloznej-poz&quot;&gt;&lt;em&gt;Jakie są kompetencje położnej POZ&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Sprawdzenie stanu faktycznego&lt;/h3&gt;
&lt;p&gt;Każda osoba zarejestrowana w NFZ &lt;em&gt;powinna być&lt;/em&gt; przypisana do konkretnego &lt;em&gt;lekarza/lekarki&lt;/em&gt; oraz &lt;em&gt;pielęgniarza/pielęgniarki&lt;/em&gt;, a kobiety dodatkowo przypisane do konkretnej &lt;em&gt;położnej&lt;/em&gt; &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;. Mówię &amp;quot;powinna&amp;quot;, ponieważ np. cudzoziemcy, którzy nigdy nie wypełnili żadnej deklaracji, nie mają nikogo przypisanego z automatu. Najlepiej sprawdzić stan faktyczny w IKP, ponieważ może się równie dobrze okazać, że jesteście przypisani do lekarza z lat dziecięcych w rodzinnym mieście.&lt;/p&gt;
&lt;p&gt;Wybierzcie przychodnię POZ niedaleko Was, i najlepiej udajcie się do niej osobiście w celu spisania deklaracji. Można to zrobić przez IKP, natomiast istnieją placówki, które nie są zsynchronizowane z systemem, bądź osoby, do których się przypiszecie mogą odrzucić Wasze deklaracje (nic nie stoi na przeszkodzie, żeby Gdańszczanin zapisał się w systemie do pielęgniarki z Rzeszowa -- stąd możliwość odrzucenia deklaracji pacjenta).&lt;/p&gt;
&lt;h3&gt;Kontakt z położną&lt;/h3&gt;
&lt;p&gt;Najlepiej nawiązać kontakt we wczesnej fazie ciąży, ponieważ kobiecie w ciąży przysługuje opieka położnej, m.in. edukacja o ciąży, porodzie, połogu, rodzicielstwie, np. w formie spotkań w przychodni.&lt;/p&gt;
&lt;p&gt;Po porodzie, w pierwszych 8 tygodniach życia dziecka powinny odbyć się od 4 do 6 wizyt patronażowych.&lt;/p&gt;
&lt;p&gt;Co prawda szpital sam zgłasza informację o narodzinach do położnej, ale w ekstremalnych przypadkach może to trwać nawet i kilkanaście dni, dlatego najlepiej skontaktować się bezpośrednio z położną bądź z POZ, w którym pracuje. Po zgłoszeniu narodzin wizyta powinna się odbyć w ciągu 2 dni roboczych.&lt;/p&gt;
&lt;p&gt;Trochę prywaty: każde województwo inaczej weryfikuje prawdziwość papierów w systemie i bywa i tak, że wizyty patronażowe w ogóle się nie odbywają. Ba, pary w ogóle nie wiedzą o istnieniu położnych środowiskowych. Dlatego jeśli Wam zależy, to ubiegajcie się o te wizyty. Ale jednocześnie pamiętajcie, że położna nie pojawi się magicznie pod Waszym adresem, jeśli się z nią wcześniej nie umówicie -- to w Waszym interesie jest sprawdzić kto jest położną środowiskową i skontaktować się z nią.&lt;/p&gt;
&lt;p&gt;Twoja położna środowiskowa (położna Twojej partnerki) najpewniej &lt;em&gt;nie jest&lt;/em&gt; związana ze szpitalem, w którym odbywał się poród. Ale to już tłumaczyłem w sekcji wcześniej.&lt;/p&gt;
&lt;h2&gt;Zarejestruj dziecko w Urzędzie Stanu Cywilnego&lt;/h2&gt;
&lt;p&gt;Strona rządowa: &lt;a href=&quot;https://www.gov.pl/web/gov/zglos-urodzenie-dziecka&quot;&gt;&lt;em&gt;Zgłoś urodzenie dziecka&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Strona warszawska: &lt;a href=&quot;https://warszawa19115.pl/-/zgloszenie-urodzenia-dziecka&quot;&gt;&lt;em&gt;Zgłoszenie urodzenia dziecka&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Można to zrobić online bądź w urzędzie. Polecam zgłosić urodzenie online natomiast odebrać dokumenty &lt;strong&gt;osobiście w urzędzie&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Na zgłoszenie masz &lt;strong&gt;21 dni od wystawienia karty urodzenia&lt;/strong&gt; (karta urodzenia to dokument wystawiany po porodzie przez położną bądź lekarza). Jeśli nie zgłosisz sam dziecka do USC w ciągu 21 dni, urzędnik zgłosi dziecko za Ciebie i wybierze mu imię. 😳&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Uwaga:&lt;/strong&gt; jeśli jesteś cudzoziemcem i Twoje akty stanu cywilnego nie są wpisane w polskim USC, musisz przynieść do wglądu oryginały zagranicznych dokumentów stanu cywilnego, które potwierdzają stan cywilny matki dziecka. Dokumenty te muszą być przetłumaczone przez tłumacza przysięgłego na język polski.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Uwaga&lt;/strong&gt;: jeśli nie macie ślubu, proponuję zadbać o &amp;quot;uznanie ojcostwa&amp;quot; &lt;strong&gt;przed narodzinami dziecka&lt;/strong&gt; (również w USC). W przeciwnym razie po narodzinach musielibyście udać się &lt;strong&gt;razem&lt;/strong&gt; do USC, inaczej ojciec będzie &amp;quot;nieznany&amp;quot;.&lt;/p&gt;
&lt;h3&gt;Co dostaniesz w zamian&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;jeden bezpłatny &lt;strong&gt;odpis skrócony aktu urodzenia&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;powiadomienie o nadaniu numeru PESEL (jeśli dziecko otrzymało numer PESEL),&lt;/li&gt;
&lt;li&gt;zaświadczenie o zameldowaniu dziecka (jeśli dziecko zostało zameldowane)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Załatwienie ubezpieczenia zdrowotnego dla dziecka (rejestracja w ZUS)&lt;/h2&gt;
&lt;h3&gt;Podpięcie dziecka do ZUS&lt;/h3&gt;
&lt;p&gt;Zgłaszasz pracodawcy w ciągu 7 dni od nadaniu PESEL-u, bądź jeśli masz swoje JDG sam wypełniasz i wysyłasz formularz &amp;quot;ZUS ZCNA&amp;quot;. Jeśli któreś z Was ma JDG, polecam samemu podpiąć dziecko w ramach własnego ubezpieczenia zdrowotnego. Łatwiej coś &amp;quot;odkręcić&amp;quot; bądź dosłać brakujący dokument &lt;em&gt;samemu&lt;/em&gt;, niż polegać na pracodawcy &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3&gt;Wybór POZ dla dziecka&lt;/h3&gt;
&lt;p&gt;Procedura taka sama jak wspominałem wcześniej, w sekcji o położnych. Dla ułatwienia wszystkich procedur wybierzcie tych samych specjalistów co Wasi (bądź matka).&lt;/p&gt;
&lt;p&gt;Instrukcja ze strony rządowej: &lt;a href=&quot;https://pacjent.gov.pl/aktualnosc/wybierz-dziecku-lekarza-rodzinnego&quot;&gt;&lt;em&gt;Wybierz dziecku lekarza rodzinnego&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;800+ i inne zasiłki&lt;/h2&gt;
&lt;p&gt;Rządowa strona z listą wszystkich świadczeń rodzinnych: &lt;a href=&quot;https://www.gov.pl/web/rodzina/co-robimy-wsparcie-dla-rodzin-z-dziecmi&quot;&gt;&lt;em&gt;Wsparcie dla rodzin z dziećmi&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;800+ (dawniej &amp;quot;500+&amp;quot;)&lt;/p&gt;
&lt;p&gt;Dostępne na każde dziecko. Można zgłosić na wiele sposobów. Najprościej zrobić to przez &lt;strong&gt;własny bank&lt;/strong&gt;. Serio. Jeśli ktoś chce spróbować swoich sił, może to zrobić bezpośrednio przez stronę ZUS-u. Ale po co? &lt;a href=&quot;https://www.gov.pl/web/rodzina/rodzina-500-plus&quot;&gt;Link do strony rządowej&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Becikowe, Kosiniakowe&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gov.pl/web/gov/uzyskaj-becikowe&quot;&gt;Becikowe&lt;/a&gt; przysługuje przy niskich dochodach&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gov.pl/web/rodzina/wiadczenie-rodzicielskie&quot;&gt;Kosiniakowe&lt;/a&gt; przysługuje przy braku możliwości wzięcia zasiłku macierzńskiego (bezrobotni, studenci, pracujący na umowę o dzieło)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Aktywny Rodzic&lt;/p&gt;
&lt;p&gt;Obowiązuje dopiero od 12 miesiąca życia dziecka. Występuje w 3 smakach: &lt;em&gt;Aktywnie w żłobku&lt;/em&gt;, &lt;em&gt;Aktywni rodzice w pracy&lt;/em&gt;, &lt;em&gt;Aktywnie w domu&lt;/em&gt;. &lt;a href=&quot;https://www.gov.pl/web/rodzina/aktywny-rodzic&quot;&gt;Link&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Urlopy&lt;/h2&gt;
&lt;p&gt;Witamy w Europie.&lt;/p&gt;
&lt;p&gt;Lista ze strony rządowej: &lt;a href=&quot;https://www.gov.pl/web/rodzina/uprawnienia-zwiazane-z-rodzicielstwem&quot;&gt;&lt;em&gt;Uprawnienia związane z rodzicielstwem&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gov.pl/web/rodzina/urlop-macierzynski&quot;&gt;&lt;strong&gt;Macierzyński&lt;/strong&gt;&lt;/a&gt;: 20 tygodni&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn3&quot; id=&quot;fnref3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Rozpoczyna się w dniu porodu. Matka &lt;strong&gt;musi&lt;/strong&gt; wziąć co najmniej 14 tygodni. Ojciec może wziąć resztę, nazywane jest to potocznie &amp;quot;tacierzyńskim&amp;quot;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gov.pl/web/rodzina/urlop-rodzicielski&quot;&gt;&lt;strong&gt;Rodzicielski&lt;/strong&gt;&lt;/a&gt;: 41 tygodni&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn4&quot; id=&quot;fnref4&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Można dzielić między matkę a partnera. Ale &lt;strong&gt;uwaga&lt;/strong&gt;: każdy rodzic ma zagwarantowane &lt;em&gt;nieprzenoszalne 9 tygodni urlopu&lt;/em&gt;, co oznacza, że jeśli matka weźmie 41 tygodni, to wtedy ojciec dostaje &amp;quot;on top&amp;quot; 9 tygodni. W sumie 50 tygodni dla dwojga partnerów. Te 9 tygodni można również dzielić na kawałki, nie trzeba brać na raz.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gov.pl/web/rodzina/urlop-ojcowski&quot;&gt;&lt;strong&gt;Ojcowski&lt;/strong&gt;&lt;/a&gt;: 2 tygodnie&lt;/p&gt;
&lt;p&gt;Do wykorzystania do 12. miesiąca życia dziecka. Wyłącznie dla ojca.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gov.pl/web/rodzina/urlop-wychowawczy&quot;&gt;&lt;strong&gt;Wychowawczy&lt;/strong&gt;&lt;/a&gt;: 36 miesięcy (3 lata)&lt;/p&gt;
&lt;p&gt;Udzielany do końca roku kalendarzowego, w którym dziecko kończy 6 lat. Jeden miesiąc jest zagwarantowany dla każdego z rodziców, więc jeden rodzic może wziąć maksymalnie 35 miesięcy (inaczej niż w przypadku rodzicielskiego, gdzie obowiązkowe 9 tygodni dla ojca drugiego z rodziców magicznie pojawia się po wymaksowaniu urlopu przez matkę pierwszego). Dzieli się na &lt;strong&gt;maksymalnie 5 części&lt;/strong&gt; (liczone są wnioski urlopowe).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Miejska wyprawka dla dziecka&lt;/h2&gt;
&lt;p&gt;Różne miasta mają programy dla swoich nowych mieszczan. Każde miasto ma swoje zasady i formę wyprawki.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Warszawa: &lt;a href=&quot;https://warszawa19115.pl/-/-wyprawka-dla-warszawskiego-malucha-&quot;&gt;Wyprawka dla Warszawskiego Malucha&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Kraków: &lt;a href=&quot;https://wyprawka.krakow.pl&quot;&gt;Krakowska wyprawka&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Poznań: &lt;a href=&quot;https://pcs.poznan.pl/strona-glowna/wyprawka-dla-gzubka/&quot;&gt;Wyprawka dla gzubka&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Wrocław: &lt;a href=&quot;https://wcrs.wroclaw.pl/wyprawkawroclawska/&quot;&gt;Wyprawka wrocławska&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;...i inne&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;I tyle&lt;/h1&gt;
&lt;p&gt;Na pewno to, co wymieniłem powyżej, nie wyczerpuje tematu i są jeszcze jakieś inne tematy. Wrzuciłem to, co chodziło mi po głowie od dłuższego czasu. Będę starał się rozwijać tę listę, bądź rozszerzać temat sekcji (najprawdopodobniej w oddzielnych wpisach).&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;W 2018 położni (mężczyźni) stanowili 0,2% wszystkich położnych. &lt;a href=&quot;#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Zwłaszcza jeśli pracodawcą jest placówka oświatowa, a za wysyłanie dokumentów odpowiada &amp;quot;pani Basia&amp;quot; z sekretariatu, która wysyła dokumenty po terminie bądź gubi je bezpowrotnie, a także potrafi wysłać mailem skan dowodu osobistego (trzymanego na pulpicie) do złego adresata. &lt;a href=&quot;#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;31, 33, 35, 37 przy kolejno 2, 3, 4, 5+ dzieciach (przy jednym porodzie) &lt;a href=&quot;#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;43 w przypadku ciąży mnogiej &lt;a href=&quot;#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry>
    <title>I finally understood Nx usefulness</title>
    <link href="https://blog.wodkiewi.cz/posts/2023-12-24-nx-usefulness/"/>
    <updated>2023-12-23T23:44:29.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/2023-12-24-nx-usefulness/</id>
    <content type="html">&lt;p&gt;I was planning on releasing a longer post about Nx, but I got lost in my line of reasoning.
So here goes a shorter note, just to share &lt;em&gt;some&lt;/em&gt; thoughts.&lt;/p&gt;
&lt;h1&gt;TypeScript project references&lt;/h1&gt;
&lt;p&gt;Before I get to the Nx part, I wanted to talk about a useful TypeScript&#39;s feature: &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/project-references.html&quot;&gt;project references&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It allows you to divide your project into separate sub-projects that are understood by TypeScript, as long as you reference the root directories of used projects (or their &lt;code&gt;tsconfig.json&lt;/code&gt; files) inside the &amp;quot;using&amp;quot; project&#39;s &lt;code&gt;tsconfig.json#references&lt;/code&gt;.
What&#39;s neat about this is that whenever you want to build the &lt;code&gt;app&lt;/code&gt; that relies on &lt;code&gt;libA&lt;/code&gt; and &lt;code&gt;libB&lt;/code&gt;, and you run &lt;code&gt;tsc --build&lt;/code&gt;, the TypeScript compiler will first run type-checking and transpilation for those dependencies, before builing the &lt;code&gt;app&lt;/code&gt; itself.
If everything is configured properly with the &lt;code&gt;.tsbuildinfo&lt;/code&gt; files, then the sub-build will be skipped (because cached).&lt;/p&gt;
&lt;h1&gt;Enter Nx&lt;/h1&gt;
&lt;p&gt;So what&#39;s the deal with Nx? One of it&#39;s core features is the fact that it manages the dependencies between the tasks, including &amp;quot;build&amp;quot; tasks.
Why would it matter to me, since TS handles that out of the box?&lt;/p&gt;
&lt;p&gt;Well, I just realized that when you change the transpiler (to, for example, swc), it turns out you have to transpile all the projects one by one yourself.&lt;/p&gt;
&lt;p&gt;So this is where Nx is showing its colors -- if the sub-projects are properly defined as dependencies in the package&#39;s manifest (=&lt;code&gt;package.json&lt;/code&gt;), &lt;strong&gt;and&lt;/strong&gt; the Nx is set up to run &amp;quot;build&amp;quot; target (=&amp;quot;command&amp;quot;) for project&#39;s dependencies whenever the project&#39;s &amp;quot;build&amp;quot; target is run, then you&#39;re all set.
You run &amp;quot;build&amp;quot; for the &lt;code&gt;app&lt;/code&gt;, and all the dependencies (&lt;code&gt;libA&lt;/code&gt;, &lt;code&gt;libB&lt;/code&gt;) are &amp;quot;built&amp;quot; first, regardless of the used transpiler, because Nx knows what to run in what order.&lt;/p&gt;
&lt;p&gt;The benefit? Your CI YAMLs/bash scripts/Dockefiles do not need to contain:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;yarn run $YOUR_TRANSPILER packages/libA
yarn run $YOUR_TRANSPILER packages/libB
yarn run $YOUR_TRANSPILER packages/app
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which would otherwise increase the complexity of the projet and would mean that the YAML/bash/Dockerfile would need to be in sync whenever you decide to add/remove/modify internal dependency of the &lt;code&gt;app&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With Nx, you just need to make sure that Nx is available in the runner context, and then run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;nx app:build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All the relationships between the packages is already defined in the source code and/or the manifests. No need to duplicate the responsiblity.&lt;/p&gt;
&lt;p&gt;And when you are using the cache properly (the easiest scenario is the local one -- practically no setup required), then the projects that were already built once and were not modified are not built again.&lt;/p&gt;
&lt;p&gt;But that&#39;s the benefit I understood only when I decided to migrate to &lt;code&gt;swc&lt;/code&gt;, since &lt;code&gt;tsc&lt;/code&gt; took way to long to build the project.
If not the build times, I&#39;d still orchestrate the builds with &lt;code&gt;tsc&lt;/code&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Envs and Twelve Factor App</title>
    <link href="https://blog.wodkiewi.cz/posts/2023-12-15-envs-and-twelve-factor-app/"/>
    <updated>2023-12-15T11:14:21.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/2023-12-15-envs-and-twelve-factor-app/</id>
    <content type="html">&lt;h1&gt;Intro&lt;/h1&gt;
&lt;p&gt;In the &lt;a href=&quot;https://12factor.net/&quot;&gt;Twelve Factor App manifesto&lt;/a&gt; there is a section III. dedicated to config management.
In short, it advises that the configuration of the app should come &amp;quot;from outside&amp;quot;, not from inside.&lt;/p&gt;
&lt;p&gt;Then there is this paragraph about &amp;quot;grouping&amp;quot;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called “environments”) named after specific deploys, such as the development, test, and production environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as staging or qa. As the project grows further, developers may add their own special environments like joes-staging, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle.&lt;/p&gt;
&lt;p&gt;In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as “environments”, but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I did not understand this at first. I mean, how can you &lt;em&gt;not&lt;/em&gt; group the environment variables?
At the end of the day you have to have the list of values written down somewhere, so that you can create a release for a particular environment (prod/dev/etc).
&lt;em&gt;It&#39;s turtles all the way down&lt;/em&gt;, right?&lt;/p&gt;
&lt;p&gt;I started imagining some software that would serve as a manager of the env variables, so that you can modify their values per release or something, but it couldn&#39;t be what the author of the manifesto had in mind, because you can achieve the same thing while modifying the files that define the values for a release.
No need for additional technology -- if anything, this should be &lt;em&gt;against&lt;/em&gt; the manifesto.
And even if it was about the software, you will for sure group the variables, the whole idea of having particular values for a release &lt;strong&gt;is&lt;/strong&gt; grouping.&lt;/p&gt;
&lt;p&gt;And then it hit me -- it&#39;s not about storing the variables in groups, it&#39;s about &lt;em&gt;using groups in code&lt;/em&gt;.&lt;/p&gt;
&lt;h1&gt;A good idea&lt;/h1&gt;
&lt;p&gt;Let&#39;s imagine you have some service that is expected to use a local filesystem when run locally and a 3rd party HTTP API when used on actual servers.
We could write it this way:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;class SomeService {
  public run() {
    if (process.env[&#39;APP_ENV&#39;] === &#39;LOCAL&#39;) {
       this.runUsingLocalFs();
    } else {
       this.runUsingHttpApi();
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Seems fine at first. You got the service behaviour designed exactly how you wanted.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;APP_ENV&lt;/code&gt; variable needs to be defined properly in all environment definitions: local environment, dev environment, prod environment, you name it.
So you add these &lt;code&gt;APP_ENV=PROD&lt;/code&gt; or &lt;code&gt;APP_ENV=LOCAL&lt;/code&gt; to some YAMLs or other &lt;code&gt;.env&lt;/code&gt; files to make it work correctly.&lt;/p&gt;
&lt;p&gt;With time you create more services that need to rely on some fallback behaviour, for example a logger service, that pretty-prints when it&#39;s useful, otherwise it creates standardized JSON logs.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;class Logger {
  private print(message: string) {
    if (process.env[&#39;APP_ENV&#39;] === &#39;LOCAL&#39;) {
       this.prettyPrint(message);
    } else {
       this.jsonPrint(message);
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;It gets messier...&lt;/h1&gt;
&lt;p&gt;Then a couple more services that behave in a similar way. Maybe there are some that behave the same way on more than one environment&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;if ([&#39;LOCAL&#39;, &#39;DEV&#39;].includes(process.env[&#39;APP_ENV&#39;])) {
  ...
} else {
  ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You decide to create some utils, maybe &lt;s&gt;an enum&lt;/s&gt; const&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; not to make a typo in the environment name:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;export const APP_ENV = {
  LOCAL = &#39;LOCAL&#39;,
  DEV = &#39;DEV&#39;,
  PROD = &#39;PROD&#39;,
} as const;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or maybe some functions to make it more consise:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;export function isLocalOrDevEnv() {
  return [APP_ENV.LOCAL, APP_ENV.DEV].includes(process.env[&#39;APP_ENV&#39;]);
}
export function isLocalEnv() {
  return [APP_ENV.LOCAL].includes(process.env[&#39;APP_ENV&#39;]);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Adding a new environment? Ok, sure, just extend the &lt;code&gt;APP_ENV&lt;/code&gt;. And the utils. And make sure that all the services are running correctly when they &lt;code&gt;APP_ENV&lt;/code&gt; contains a value that was not decided on previously.&lt;/p&gt;
&lt;h1&gt;...and messier&lt;/h1&gt;
&lt;p&gt;What if you want to run some integration tests that call &lt;code&gt;SomeService&lt;/code&gt;? You either have to define &lt;code&gt;APP_ENV&lt;/code&gt; as &lt;code&gt;LOCAL&lt;/code&gt; or something else, to choose the implementation you want.&lt;/p&gt;
&lt;p&gt;Choosing the &lt;code&gt;APP_ENV&lt;/code&gt; also changes the behaviour of other N services, that now have to behave as if they were on some particular environment.
Trying to get the desired behaviour of one service that relies on &lt;code&gt;APP_ENV&lt;/code&gt; is now a game of whack-a-mole, or a minesweeper -- you change one setting and then you see multiple things changed.&lt;/p&gt;
&lt;p&gt;I believe this is the &lt;em&gt;grouping&lt;/em&gt; of which the manifesto tried to warn us.&lt;/p&gt;
&lt;h1&gt;Solution&lt;/h1&gt;
&lt;p&gt;If the services were implemented with separate config flags, like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;class SomeService {
  public run() {
    if (process.env[&#39;SOME_SERVICE_LOCAL_FS&#39;]) {
       this.runUsingLocalFs();
    } else {
       this.runUsingHttpApi();
    }
  }
}

class Logger {
  private print(message: string) {
    if(process.env[&#39;LOGGER_PRETTY_PRINT&#39;]) {
       this.prettyPrint(message);
    } else {
       this.jsonPrint(message);
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then you avoid the issues mentioned above.&lt;/p&gt;
&lt;p&gt;You still need to decide what is the default behaviour (should it be some particular implementation or throwing errors when the configuration is undefined) -- I guess there are some best practices as well.
But at least you are not grouping unrelated features with an environment name.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;no enums please &lt;a href=&quot;#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry>
    <title>Class fields, again</title>
    <link href="https://blog.wodkiewi.cz/posts/2023-10-31-class-fields-and-ts-2/"/>
    <updated>2023-10-31T08:52:38.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/2023-10-31-class-fields-and-ts-2/</id>
    <content type="html">&lt;p&gt;Two weeks ago I wrote about &lt;a href=&quot;/posts/2023-10-20-class-fields-and-ts/&quot;&gt;class fields, TC39 and TypeScript&lt;/a&gt;.
This time I want to go into the details of transpilation output related to class fields.&lt;/p&gt;
&lt;h1&gt;Intro&lt;/h1&gt;
&lt;p&gt;You see, I have this class in my TypeScript codebase:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;class Foobar {
    public foo = 31;

    constructor(public x: string){
    }
    
    public bar = this.x.toUpperCase();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Obviously, this is some real production-grade code.&lt;/p&gt;
&lt;p&gt;Now, to set the scene: my &lt;code&gt;tsconfig.json&lt;/code&gt; has the &lt;code&gt;target&lt;/code&gt; set to &lt;code&gt;ES2021&lt;/code&gt; and I am &lt;strong&gt;not&lt;/strong&gt; using the &lt;code&gt;useDefineForClassFields&lt;/code&gt; flag yet.&lt;/p&gt;
&lt;p&gt;So the JavaScript result of running &lt;code&gt;tsc&lt;/code&gt; looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;class Foobar {
    constructor(x) {
        this.x = x;
        this.foo = 12;
        this.bar = this.x.toUpperCase();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Idea 1: the flag&lt;/h1&gt;
&lt;p&gt;I want to start using &lt;code&gt;useDefineForClassFields: true&lt;/code&gt; in my repo, to move my TypeScript source code closer to JavaScript.&lt;/p&gt;
&lt;p&gt;So I turn this on in the &lt;code&gt;tsconfig.json&lt;/code&gt;, and with the same &lt;code&gt;ES2021&lt;/code&gt; target, what I get from &lt;code&gt;tsc&lt;/code&gt; now is this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;class Foobar {
    constructor(x) {
        Object.defineProperty(this, &amp;quot;x&amp;quot;, {
            enumerable: true,
            configurable: true,
            writable: true,
            value: x
        });
        Object.defineProperty(this, &amp;quot;foo&amp;quot;, {
            enumerable: true,
            configurable: true,
            writable: true,
            value: 12
        });
        Object.defineProperty(this, &amp;quot;bar&amp;quot;, {
            enumerable: true,
            configurable: true,
            writable: true,
            value: this.x.toUpperCase()
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is definitely more verbose, but not surprising, knowing why the flag was introduced in the first place.&lt;/p&gt;
&lt;p&gt;So far, all&#39;s fine. What&#39;s interesting is that you might already see that there is a specific order in which the properties are defined.
The first defined property is always the class field defined via &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/2/classes.html#parameter-properties&quot;&gt;parameter properties&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;Idea 2(022): electric boogaloo&lt;/h1&gt;
&lt;p&gt;Since I&#39;m already using the flag, and it is now year 2023 (so ES2022 is already released), why won&#39;t I set
the target to &lt;code&gt;ES2022&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;And that&#39;s what I do, with the &lt;code&gt;useDefineForClassFields&lt;/code&gt; flag turned on.&lt;/p&gt;
&lt;p&gt;But &lt;code&gt;tsc&lt;/code&gt; is not happy:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;class Foobar {
    public foo = 31;

    constructor(public x: string){
    }

    public bar = this.x.toUpperCase();
    //                ^ Property &#39;x&#39; is used before its initialization.(2729)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Weird.&lt;/p&gt;
&lt;p&gt;I remove the &lt;code&gt;bar&lt;/code&gt; property from the class, and this is the transpilation output:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;class Foobar {
    x;
    foo = 31;
    constructor(x) {
        this.x = x;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;x;&lt;/code&gt;? No &lt;code&gt;Object.defineProperty&lt;/code&gt; calls anymore? And why was suddenly &lt;code&gt;bar&lt;/code&gt; illegal?&lt;/p&gt;
&lt;h1&gt;Looking for patterns&lt;/h1&gt;
&lt;p&gt;First thing that gets my attention is the fact that there are no &lt;code&gt;Object.defineProperty&lt;/code&gt; calls anymore.
I believe this is because ES2022 now has the class fields as part of the language, so the field being initialized like &lt;code&gt;foo = 31;&lt;/code&gt; &lt;em&gt;has to be realized&lt;/em&gt;
as if there was the &lt;code&gt;Object.defineProperty&lt;/code&gt; call in the code. That is why the &lt;code&gt;useDefineForClassFields&lt;/code&gt; flag&#39;s behaviour was to add these calls
in the first place. Now with ES2022 being a thing, this is not necessary -- the language imposes these &lt;code&gt;[[Define]]&lt;/code&gt; semantics on the runtime.&lt;/p&gt;
&lt;p&gt;Second thing is the lone &lt;code&gt;x;&lt;/code&gt; expression. This does not look like it would be a requirement of the ECMAScript specification.
I searched for some clues in the TypeScript repository, but I couldn&#39;t find any proof for the hypothesis
that it is by TypeScript&#39;s design to define^Wassign&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;
the fields in this specific order: parameter properties, then class fields.&lt;/p&gt;
&lt;p&gt;Because this is what it looks like:&lt;/p&gt;
&lt;h2&gt;Wild theories below&lt;/h2&gt;
&lt;p&gt;With TypeScript&#39;s original decision to use the &lt;code&gt;[[Set]]&lt;/code&gt; semantics for class field initialization, it was also decided that the parameter properies were always assigned first.
An arbitrary decision, but it allows assignments like the one for &lt;code&gt;baz&lt;/code&gt;, where the value is taken from a constructor argument.
And also, you have to have &lt;em&gt;some&lt;/em&gt; order, so placing the parameter properties first looks elegant as opposed to doing it in the order of appearance in the class
(mixing class scope with constructor-parameter scope, yuck!).
I wonder why weren&#39;t parameter properties placed &lt;em&gt;last&lt;/em&gt;, but it&#39;s probably because placing them &lt;em&gt;first&lt;/em&gt; gives you the &lt;code&gt;baz&lt;/code&gt; assigment for free and placing them &lt;em&gt;last&lt;/em&gt; gives you nothing.&lt;/p&gt;
&lt;p&gt;Then, when it turned out that ECMAScript is going to go for &lt;code&gt;[[Define]]&lt;/code&gt; semantics, TypeScript was forced to use &lt;code&gt;Object.defineProperty&lt;/code&gt;. The order was kept,
since the parameter properties are not a JavaScript feature&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt; and the designers wanted to keep the same behaviour. Notice that the &lt;code&gt;bar&lt;/code&gt; initialization
was legal with the ES2021 target. What&#39;s more (that is not highlighted in my example) is that with the &lt;code&gt;[[Define]]&lt;/code&gt; semantics TypeScript needs to emit statements
for uninitialized fields, that were previously removed from the output (since their purpose was only type-checking).&lt;/p&gt;
&lt;p&gt;Finally, when ES2022 arrived, the parameter properties needed to be &amp;quot;mentioned&amp;quot; at the top of the class definition, to keep the already established TS behaviour.
But what&#39;s the most interesting here is that with ES2022 target there is now a separation between &lt;em&gt;definition&lt;/em&gt; and &lt;em&gt;assignment&lt;/em&gt; -- previously, it was happening
in a single expression with the &lt;code&gt;value&lt;/code&gt; sitting in the third argument of &lt;code&gt;Object.defineProperty&lt;/code&gt; call.&lt;/p&gt;
&lt;p&gt;What&#39;s also interesting is that the output for a pre-ES2022 target with &lt;code&gt;useDefineForClassFields&lt;/code&gt; does not separate the &lt;em&gt;definition&lt;/em&gt; from &lt;em&gt;assignment&lt;/em&gt; as the ES2022 output,
while it is totally possible to do technically. My wild guess is that the difference was not made on purpose as a &amp;quot;migration stage&amp;quot;, but the final behaviour of ES2022
was decided &lt;em&gt;after&lt;/em&gt; the flag was implemented in TS 3.7. But again, I have no proof to support this.&lt;/p&gt;
&lt;h1&gt;tsc, why&lt;/h1&gt;
&lt;p&gt;Consider this snippet:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;class Asdf {
    public bar = this.foo;
    //                ^^^ Property &#39;foo&#39; is used before its initialization.(2729)
    public foo = 31;
}

class Qwerty {
    public foo = 31;
    public bar = this.foo; // all&#39;s good
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The order of field initializers is important to TypeScript. And because parameter properties are emitted &lt;em&gt;first&lt;/em&gt;, that&#39;s why
it has been always legal to set &lt;code&gt;bar&lt;/code&gt; like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;class BarX {
    public bar = this.x;
    constructor(public x: string) {
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It looks like you&#39;re trying to use &lt;code&gt;x&lt;/code&gt; before it is initialized, but we already know that this is not the case for pre-ES2022 output.&lt;/p&gt;
&lt;p&gt;But trying to transpile the &lt;code&gt;BarX&lt;/code&gt; class above into ES2022, we will first get a type-checking error from tsc.
TS Playground shows you what would the output be for this code:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;class BarX {
    x;
    bar = this.x;
    constructor(x) {
        this.x = x;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So here&#39;s the problem. The parameter property was defined with ES2022 syntax at the top, but assigned in the constructor body, whereas the &lt;code&gt;bar&lt;/code&gt; class field
assigment &lt;strong&gt;was not&lt;/strong&gt; moved to the constructor. It &lt;em&gt;does&lt;/em&gt; make sense why TS reports an error (&lt;code&gt;bar&lt;/code&gt; will be initialized with &lt;code&gt;undefined&lt;/code&gt;), but
it &lt;em&gt;does not&lt;/em&gt; make sense to me why isn&#39;t the output like the snippet below in the first place:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;class BarX {
    x;
    bar;
    constructor(x) {
        this.x = x;
        this.bar = this.x;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I assume this is due to &amp;quot;TypeScript not wanting to transform the source code&amp;quot; and &amp;quot;being as close to ECMAScript as possible&amp;quot;. Well, unfortunately
you cannot have your cake and eat it too,
because not only the sole existence of parameter properties forces you to transform the code in some way,
it&#39;s also the fact that &lt;code&gt;useDefineForClassFields&lt;/code&gt; behaviour for pre-ES2022 was supposed to bring the forward compatibility with ES2022,
&lt;strong&gt;but it turned out to have a different behaviour than ES2022&lt;/strong&gt;.
By chance it was the &lt;strong&gt;exact&lt;/strong&gt; behaviour that we wanted, and now, we don&#39;t have it.&lt;/p&gt;
&lt;h1&gt;swc, hi&lt;/h1&gt;
&lt;p&gt;And here&#39;s the same snippet ran through swc with ES2022 and &lt;code&gt;useDefineForClassFields&lt;/code&gt; set to &lt;code&gt;true&lt;/code&gt; (by default):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;class BarX {
    x;
    bar;
    constructor(x){
        this.x = x;
        this.bar = this.x;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yes, the default ES2022 behaviour is to emit the equivalent of tsc&#39;s pre-ES2022 + &lt;code&gt;useDefineForClassFields&lt;/code&gt; output.&lt;/p&gt;
&lt;p&gt;Too bad we cannot &lt;em&gt;just&lt;/em&gt; use it, since tsc is going to report compiler errors on the source code anyway.&lt;/p&gt;
&lt;h1&gt;What will I do, a.k.a &amp;quot;Closing words&amp;quot;&lt;/h1&gt;
&lt;p&gt;I&#39;ll probably change my original &lt;code&gt;Foobar&lt;/code&gt; class from this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;class Foobar {
    public foo = 31;

    constructor(public x: string){
    }
    
    public bar = this.x.toUpperCase();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;class Foobar {
    public foo = 31;

    constructor(public x: string){
        bar = this.x.toUpperCase();
    }
    
    public bar: string;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;because this is all it takes to get the old behaviour (for the &lt;code&gt;bar&lt;/code&gt; field assignment) back in ES2022.&lt;/p&gt;
&lt;p&gt;But I&#39;ll be cautiously keeping an eye at all the syntax sugar that is provided by TS from now on.&lt;/p&gt;
&lt;h1&gt;Post scriptum&lt;/h1&gt;
&lt;p&gt;In C# &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/fields&quot;&gt;a field initializer cannot refer to other instance fields&lt;/a&gt;.
You can only do the assignment in the constructor body.&lt;/p&gt;
&lt;p&gt;Had this rule been in TS from the start, we wouldn&#39;t have ended up with some code that is now only valid for old compilation targets.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;the whole thing is actually about the assumption it was supposed to be an &amp;quot;assignment&amp;quot;, not a &amp;quot;definition&amp;quot; &lt;a href=&quot;#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;yet &lt;a href=&quot;#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry>
    <title>Yarn being Yarn</title>
    <link href="https://blog.wodkiewi.cz/posts/2023-10-25-yarn-being-yarn/"/>
    <updated>2023-10-25T14:44:07.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/2023-10-25-yarn-being-yarn/</id>
    <content type="html">&lt;p&gt;When fighting with some tools working not as expected, it is always good to read an
insightful commit message.&lt;/p&gt;
&lt;p&gt;Especially if it&#39;s your own commit message, from 8 months ago.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;chore: set some-package resolution to 2.0.0&lt;/p&gt;
&lt;p&gt;I used the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;   yarn set resolution some-package@npm:^1.0.4 2.0.0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This caused the lock file to be modified. There is no additional entry
inside top-level package.json.&lt;/p&gt;
&lt;p&gt;What&#39;s more, yarn documentation mentions &lt;code&gt;-s&lt;/code&gt; option that should
&amp;quot;Persist the resolution inside the top-level manifest&amp;quot;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;, but it is
not implemented according to an answer from 2020&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;What&#39;s more, &lt;code&gt;resolutions&lt;/code&gt; in package.json and &lt;code&gt;yarn set resolution&lt;/code&gt; are
totally different features...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And then the next message afterwards:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;chore: decided to use package.json resolutions&lt;/p&gt;
&lt;p&gt;Putting a new entry inside package.json is more developer-friendly --
the approach with &lt;code&gt;yarn set resolution&lt;/code&gt; leaves no info other than the
lockfile itself, which if regenerated, loses the information about
the forced resolution.&lt;/p&gt;
&lt;p&gt;The only downside is that it&#39;s now harder to parse the lockfile on its own,
cause the lockfile mentions version 2.0.0 which is not requested by any
package (contrary to &lt;code&gt;yarn set resolution&lt;/code&gt; which kept declarated range
as &amp;quot;^1.0.4&amp;quot; and only modified the actual resolution version).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I checked the issue and the &lt;code&gt;--saved&lt;/code&gt; flag is still mentioned in the docs, and &lt;em&gt;still&lt;/em&gt; not implemented.
The &lt;code&gt;save = Option.Boolean(`-s,--save`)&lt;/code&gt; variable just sits
&lt;a href=&quot;https://github.com/yarnpkg/berry/blob/1a575592f911f471d3ed00bfbb5b5dafbab5fd00/packages/plugin-essentials/sources/commands/set/resolution.ts#L27-L29&quot;&gt;here&lt;/a&gt;,
patiently waiting to be deleted.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;https://yarnpkg.com/cli/set/resolution &lt;a href=&quot;#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;https://github.com/yarnpkg/berry/issues/2202#issuecomment-737788770 &lt;a href=&quot;#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry>
    <title>Class fields, TC39 and TypeScript</title>
    <link href="https://blog.wodkiewi.cz/posts/2023-10-20-class-fields-and-ts/"/>
    <updated>2023-10-20T15:07:00.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/2023-10-20-class-fields-and-ts/</id>
    <content type="html">&lt;p&gt;It&#39;s June 2022 and a new version of ECMAScript has just been released. One of the novelties that this version has brought us are the class fields.&lt;/p&gt;
&lt;p&gt;You see, Object-Oriented languages usually have this feature, where you can declare a field on a class in the top-most scope of the class like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;class Foobar {
  private someNumberField = 10;
  public  aFieldWithNoValue; 
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Well, aside from the obvious lack of access keywords, this was still impossible in JavaScript. Until ES2022 you usually set those in the constructor (or never mentioned them at all):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;class Foobar {
  constructor() {
    this.someNumberField = 10;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But because of the proposal&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; that has been marinating since 2017, this feature has been brought to life in ES2022, and since then, JS is now like any other OO language.&lt;/p&gt;
&lt;p&gt;Hehe.&lt;/p&gt;
&lt;p&gt;Well, it has been decided around 2018/2019 that the declaration of class fields will be done in JS using &lt;code&gt;[[Define]]&lt;/code&gt; semantics and not &lt;code&gt;[[Set]]&lt;/code&gt; semantics.&lt;/p&gt;
&lt;p&gt;This means that whenever a class Foobar defines a property (for example, initialized like: someNumberField = 10), JS is&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;not&lt;/strong&gt; doing &lt;code&gt;this.someNumberField = 10&lt;/code&gt; when creating an instance of the class&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;but&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;running &lt;code&gt;Object.defineProperty(Foobar, &amp;quot;someProp&amp;quot;, 10)&lt;/code&gt; somewhere around the class declaration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Why does it matter? Oh boy, it matters a lot. See the heated discussion &lt;a href=&quot;https://github.com/tc39/proposal-class-fields/issues/151#issuecomment-431597270&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Most importantly to the TS users, the class fields that were in TypeScript long before ES2022, were originally implemented with &lt;code&gt;[[Set]]&lt;/code&gt; semantics.
That&#39;s what the TypeScript creators assumed at that time, and I have to admit, &lt;code&gt;[[Set]]&lt;/code&gt; semantics make total sense to me.&lt;/p&gt;
&lt;p&gt;Sooo, since TS 3.7 there&#39;s this &lt;code&gt;useDefineForClassFields&lt;/code&gt; flag that when turned on, flips the implementation to an ECMAScript-compilant one. &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;But the new ECMAScript-compliant behaviour breaks some existing code related to class inheritance and property setters.
If you have a derived class that &lt;em&gt;narrows&lt;/em&gt; a type of some property (a totally valid thing to do in TS) that is set in the base class with a &lt;code&gt;super()&lt;/code&gt;
call, it will be set to &lt;code&gt;undefined&lt;/code&gt; after the constructor of the derived class returns!&lt;/p&gt;
&lt;p&gt;There are a couple of fixes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;quick and dirty: set &lt;code&gt;useDefineForClassFields&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt; if you have it set to &lt;code&gt;true&lt;/code&gt;. Unless your target is &lt;code&gt;ES2022&lt;/code&gt; or higher, then you&#39;re left with the other option:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;fix the code by marking the property in the derived class with the &lt;code&gt;declare&lt;/code&gt; keyword. Even if originally you overrode it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;or use a transpiler that does provides non-compliant transformation options: https://swc.rs/docs/configuration/compilation#jsctransformusedefineforclassfields&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr class=&quot;footnotes-sep&quot;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;https://github.com/tc39/proposal-class-fields &lt;a href=&quot;#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#the-usedefineforclassfields-flag-and-the-declare-property-modifier &lt;a href=&quot;#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry>
    <title>Https Stuff</title>
    <link href="https://blog.wodkiewi.cz/posts/https-stuff/"/>
    <updated>2022-08-04T21:34:19.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/https-stuff/</id>
    <content type="html">&lt;p&gt;A couple of things I learned yesterday when browsing Hacker News.&lt;/p&gt;
&lt;h1&gt;Upgrade-Insecure-Requests&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;Content-Security-Policy: upgrade-insecure-requests;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This means that if for any reason a non-navigational content on your website contains &lt;code&gt;http&lt;/code&gt; instead of &lt;code&gt;https&lt;/code&gt; (by mistake), then the browser will try to access it via &lt;code&gt;https&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This won&#39;t change navigation &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; links to 3rd party websites.&lt;/p&gt;
&lt;h1&gt;HTTP Strict-Transport-Security (HSTS)&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;Strict-Transport-Security: max-age=&amp;lt;expire-time&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This header instructs the browser that this website needs to be accessed only via &lt;code&gt;https&lt;/code&gt; for as long as the header is not expired.
Even if you click on a link with &lt;code&gt;http&lt;/code&gt; or write the URL by hand using &lt;code&gt;http&lt;/code&gt;, the browser will automatically treat this as &lt;code&gt;https&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But this works only &lt;strong&gt;after&lt;/strong&gt; you initially visited the website via HTTPS.&lt;/p&gt;
&lt;h1&gt;HSTS Preload&lt;/h1&gt;
&lt;p&gt;If you visit the website &lt;code&gt;http://example.com&lt;/code&gt; for the first time, there&#39;s a possibility that you&#39;ll be a victim of a man-in-the-middle attack.
The attacker hijacks your HTTP request, calls the original website themselves via HTTPS and then returns the response to you via HTTP, without the Strict-Transport-Security header.&lt;/p&gt;
&lt;p&gt;In order to make sure that your website is &lt;strong&gt;always&lt;/strong&gt; accessed via HTTPS, you need to add it to the pre-loaded list of websites, curated by browser vendors.
This is the only way the browser will know it has to use HTTPS for the first time, without getting the headers beforehand.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Problems Not Solutions</title>
    <link href="https://blog.wodkiewi.cz/posts/problems-not-solutions/"/>
    <updated>2022-04-07T08:24:55.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/problems-not-solutions/</id>
    <content type="html">&lt;p&gt;Today an interesting read by a Columbia professor:
&lt;a href=&quot;https://statmodeling.stat.columbia.edu/2022/03/27/the-examples-you-see-in-the-textbooks-are-not-representative-of-the-sorts-of-problems-you-see-in-the-real-world/&quot;&gt;&lt;em&gt;The examples you see in the textbooks are not representative of the sorts of problems you see in the real world&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I see it too. But what is even more important to me regarding Maths or Physics is that very often the &lt;em&gt;real&lt;/em&gt; problems you encounter can only be solved/described/modelled using a mix of various approaches. It is sometimes obviously easy when you’re learning a particular topic that the posed problems can be automatically solved by applying &lt;em&gt;this thing you just learned about&lt;/em&gt;. You simply need to use the method or apply the same formula, maybe this time with a slight twist. For me personally it’s hard to apply the knowledge in the real world, if I’ve been using it &lt;strong&gt;only&lt;/strong&gt; in an artificial and very precise problem space.&lt;/p&gt;
&lt;p&gt;How to make it better then? One way could be to mix the problems in such a way that you need to apply different methods, not only &lt;em&gt;the latest thing you’ve just learned&lt;/em&gt;. Science handbooks do that usually at the ends of chapters as a form of summary. Most of them fail anyway, because those problems are usually listed in the very same order as the topics in the chapter — you don’t need an Einstein to figure out that when you use the tools in roughly the same order you learned them several pages ago, you’ll be fine. Why not randomise the order of the problems in the summary sections? Is this idea really that bold?&lt;/p&gt;
&lt;p&gt;Another way would be &lt;strong&gt;not to&lt;/strong&gt; structure the course around the methods, but around the problems. Let’s step back and ask ourselves — why do we want to teach others anything? I guess the most &lt;em&gt;useful&lt;/em&gt; reason would be to help them understand the world around them. So why not guide people through their questions and problems they have, or might have in the future, and not stuffing them with some knowledge that you (or the curriculum) find important. Let people try working with the problems themselves and only then teach them various methods and equations that fill in the missing gaps.&lt;/p&gt;
&lt;p&gt;Teach problems, not solutions. Solutions are only interesting when you had the opportunity to familiarise with the problems first.
People might be not only more interested in the course, but the skills they learn are actually more useful from the day one.
This approach is definitely harder for the tutor, because it requires more creative work and it requires them to understand the topics very well — I would argue it’s possible to teach people from a book and not understanding truly what you’re teaching — but I truly believe that if you care about the students, this is the way to go.&lt;/p&gt;
&lt;p&gt;I wonder if there’s ever going to be such a shift in education.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Simple PR Stats</title>
    <link href="https://blog.wodkiewi.cz/posts/small-pr-stats/"/>
    <updated>2022-03-31T07:28:23.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/small-pr-stats/</id>
    <content type="html">&lt;p&gt;So my Rails project failed before it even started.
I am not surprised, I know myself quite well.
I think I don&#39;t have enough frontend experience and that&#39;s what blocks me from going forward.&lt;/p&gt;
&lt;p&gt;I&#39;d like to say I took a breather and stopped thinking about side-project ideas, until one suddenly appeared to me, but obviously I still had that thing at the back of my head that tried to generate new ideas amd another thing that validated if those are within my reach.&lt;/p&gt;
&lt;p&gt;Well, there was an idea that suddenly popped into my mind yesterday. I was looking for some tool that would automatically generate a small statistics report on GitHub PRs in a repository of my choice. Most of these were paid products, some of them were too comllex and every tool I found required either registration or external intrastructure on which you run the tool. Then I found a GitHub Action that did almost what I wanted, but the stats were calculated per contributor, not per whole repo.&lt;/p&gt;
&lt;p&gt;So I dug into GitHub Actions docs and wrote an action myself. The most important part (for me) is that I have already published it publicly!&lt;/p&gt;
&lt;p&gt;This is the thing: &lt;a href=&quot;https://github.com/akwodkiewicz/simple-pr-stats&quot;&gt;simple-pr-stats&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It&#39;s very simple and needs lots of love, but let&#39;s see if the fact that the project is live and publicly available will help me get &lt;em&gt;unstuck&lt;/em&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>After Hours</title>
    <link href="https://blog.wodkiewi.cz/posts/after-hours/"/>
    <updated>2022-02-16T20:37:32.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/after-hours/</id>
    <content type="html">&lt;p&gt;I have noticed that it takes me about 30 to 60 minutes to clear my mind after work.
Until then, my mind is foggy and I&#39;m living life on auto-pilot for a while.
Sometimes I even feel I&#39;m not completely back for the rest of the day.
It sounds a little bit scary, and I the more I think about it, the more I realise it &lt;em&gt;should&lt;/em&gt; make me scared, for my own good.&lt;/p&gt;
&lt;p&gt;I don&#39;t have any sophisticated takes on this matter,
but I think it is quite obvioue that putting yourself into a mental state
like this one cannot be healthy.
Especially if it happens 5 out of 7 days in the week, each week.&lt;/p&gt;
&lt;p&gt;It&#39;s hard to plan things, it&#39;s hard to get out of the rut.
It&#39;s even hard to read books at times.
What&#39;s easy is mindless scrolling of news websites and feeds on social media.
But it does not help clearing the fog at all.&lt;/p&gt;
&lt;p&gt;What I realised is that the more I focus on &lt;em&gt;being here and now&lt;/em&gt;, the faster I get control over my thoughts, and the more present I am &lt;em&gt;after hours&lt;/em&gt;.
I don&#39;t meditate or do any mindfullness stuff, but sometimes I force myself
to simply close my eyes and &lt;em&gt;get my shit together&lt;/em&gt;.
Tink about past weeks, current date and upcoming days, any chores that
I forgot about -- it&#39;s so simple and silly when I describe it in words,
but I know that it&#39;s often just too hard to do properly.&lt;/p&gt;
&lt;p&gt;I read today that &lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/34516957/&quot;&gt;acute aerobic exercise sessions can help you recover quicker from cognitive fatigue than leisure time&lt;/a&gt;.
The study even used &amp;quot;watching a popular sitcom&amp;quot; as the &amp;quot;leisure&amp;quot; approach.
I guess this means I should do a trial myself.
Let&#39;s say instead of another episode of The Office I should probably do a 20-minute run around the block.
And then compare the results with my &lt;em&gt;notmindfullness&lt;/em&gt; sessions.&lt;/p&gt;
&lt;p&gt;Not sure when I&#39;ll start with this research of my own though -- still waiting for funding.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Ruby on Rails Questions, part 1</title>
    <link href="https://blog.wodkiewi.cz/posts/rails-questions-1/"/>
    <updated>2022-02-13T21:13:07.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/rails-questions-1/</id>
    <content type="html">&lt;p&gt;I decided to give RoR a try. I don&#39;t quite feel it yet, mostly because I&#39;ve never learned any Ruby.
Maybe it&#39;s not the smartest move to learn the framework without learning its &lt;em&gt;mother&lt;/em&gt; language, but at least it&#39;s &lt;em&gt;a&lt;/em&gt; move.&lt;/p&gt;
&lt;p&gt;I opened the official &lt;a href=&quot;https://guides.rubyonrails.org/getting_started.html&quot;&gt;Getting Started&lt;/a&gt; guide on my 2.5 hour long train ride and finished the basic &amp;quot;blog&amp;quot; app by ~copy-past~ following the instructions step by step.&lt;/p&gt;
&lt;p&gt;On my way back (another 2.5h ride) I decided to start with my own app.&lt;/p&gt;
&lt;p&gt;Below are the questions I asked myself during this experiment, sometimes with some answers I managed to find on SO:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Q: How on earth do you know the attributes of the model, if the model class does not contain definitions of possible fields/columns?&lt;/p&gt;
&lt;p&gt;A: &lt;a href=&quot;https://stackoverflow.com/a/1291395/7134149&quot;&gt;You inspect the items in the console with &lt;code&gt;.columns&lt;/code&gt; or &lt;code&gt;.attributes&lt;/code&gt;&lt;/a&gt;, or you write block comments with the database schema in the model class (&lt;a href=&quot;annotate_models&quot;&gt;or use a plugin for that&lt;/a&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;).&lt;/p&gt;
&lt;p&gt;Sounds... not ideal, to say the least. Most of the fields are going to be mentioned in the class anyway, because of some validation rules, but this is just coincidental. I&#39;ve found &lt;a href=&quot;https://ruby-doc.org/core-2.0.0/Module.html#method-i-attr_accessor&quot;&gt;&lt;code&gt;attr_accessor&lt;/code&gt;&lt;/a&gt; that could&#39;ve been used, but it seems that it&#39;s not a conventional thing to do.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Q: Is it common to have models that are not derived from ActiveRecord, so that they &lt;strong&gt;do not&lt;/strong&gt; represent database entities?&lt;/p&gt;
&lt;p&gt;Maybe I do not know MVC well enough.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Q: &lt;a href=&quot;https://stackoverflow.com/questions/71104723/how-to-structure-rails-app-where-calendar-date-is-the-main-view?noredirect=1#comment125692735_71104723&quot;&gt;How to structure Rails app where calendar date is the main view?&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr class=&quot;footnotes-sep&quot;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Remember to include it in the &lt;code&gt;:development&lt;/code&gt; group &lt;a href=&quot;#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry>
    <title>Ruby or Not Ruby</title>
    <link href="https://blog.wodkiewi.cz/posts/ruby-or-not-ruby/"/>
    <updated>2022-02-05T13:58:12.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/ruby-or-not-ruby/</id>
    <content type="html">&lt;p&gt;Hacker news is an interesting place.&lt;/p&gt;
&lt;p&gt;Today I saw &lt;a href=&quot;https://reviewbunny.app/blog/dont-make-me-think-or-why-i-switched-to-rails-from-javascript-spas&quot;&gt;an article&lt;/a&gt; about the superiority of Ruby over Javascript ecosystem when it comes to tooling simplicity.
The points made by the author make sense to me.
They are almost too familiar — I spent my latest &lt;em&gt;creative hour&lt;/em&gt; on comparisons of several javascript... storage approaches? (like a &lt;em&gt;database&lt;/em&gt; wasn’t good enough).
On the other hand Ruby with Rails framework in the centre, has only one particular tool for each job, so you won’t waste time on preoptimizing your tech stack even before you wrote a single line of code.
I was sold and decided to put (Ruby on) Rails onto my backlog.&lt;/p&gt;
&lt;p&gt;Half a day later I saw &lt;a href=&quot;https://solnic.codes/2022/02/02/rails-is-not-written-in-ruby/&quot;&gt;another article&lt;/a&gt; about Ruby.
This time the main theme was that Rails is to Ruby what a Cracow dialect is to Polish language.
Interesting, huh?
I learned that Ruby on Rails community loves monkey-patching and it’s a source of serious problems for the authors of Ruby libraries.
Apparently Rails is powered mainly by the ActiveSupport library which extends every builtin type.
Because it gets the special treatment as the “unofficial stdlib” it’s hard to write other libraries.
You either add more patches and hope that there will be no clashes between the libraries or you propose a different paradigm, which is then rejected by the community so used to the Rails conventions.
Well, it does not sound like the ecosystem is easily extendable and when you try to do something more complex (like &lt;a href=&quot;https://shopify.engineering/shopify-monolith&quot;&gt;Shopify&lt;/a&gt; it gets much harder.&lt;/p&gt;
&lt;p&gt;Even though these two articles at first seem like arguments &lt;em&gt;for&lt;/em&gt; and &lt;em&gt;against&lt;/em&gt; Ruby, they actually agree on the single premise, that you should do the things in a very particular way. All the way. Hard for me to say whether it’s appealing to me or not. Maybe I’ll give it a try one day.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Sent From iPhone</title>
    <link href="https://blog.wodkiewi.cz/posts/sent-from-iphone/"/>
    <updated>2022-01-31T20:33:36.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/sent-from-iphone/</id>
    <content type="html">&lt;p&gt;The title says it all.
I wanted to be able to write and edit posts from my phone. And I made it!&lt;/p&gt;
&lt;p&gt;I installed a Termius app on my iPhone. It allowed me to generate an ECDSA keypair in a secure enclave -- allegedly even the app does not know the key.&lt;/p&gt;
&lt;p&gt;I then exported the public key from Termius via Signal (it was the easiest way to sync the content from my iPhone to my Windows PC) and pasted it into the terminal, where I was logged onto the VPS running the blog.&lt;/p&gt;
&lt;p&gt;Originally I thought about having a separate app for preparing Markdown files and then uploading them onto the VPS. But file uploading might be not possible (or just very incovenient) using the free version of Termius,
so I am currently typing these words in &lt;code&gt;vim&lt;/code&gt;... on a smartphone touchscreen keyboard 🤪&lt;/p&gt;
&lt;p&gt;Why did I do that? Well firstly, because I was curious whether it&#39;s possible.
Secondly, since I&#39;m using my phone &lt;strong&gt;way more&lt;/strong&gt; often than my private laptop, and I consume digital content almost exclusively on a phone, I figured it wpuld be much harder for me to now find an excuse not to write.&lt;/p&gt;
&lt;p&gt;But I alteady see I need to find out how to turn on autocorrect.&lt;/p&gt;
&lt;p&gt;Cheers!
:wq&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Interesting things #1</title>
    <link href="https://blog.wodkiewi.cz/posts/interesting-1/"/>
    <updated>2022-01-30T00:00:00.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/interesting-1/</id>
    <content type="html">&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=BfDLoIvb0w4&quot;&gt;James Hoffman&#39;s 3-part series about moka pot brewing&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/c/NEVERTOOSMALL&quot;&gt;&lt;em&gt;NEVER TOO SMALL&lt;/em&gt; channel&lt;/a&gt; which shows small, but highly functional apartments&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Homo Deus&lt;/em&gt; by Yuval Noah Harari -- very interesting read about the human history and potential future. Lots of author&#39;s personal views on various subjects, so stay cautious and don&#39;t treat it as a scientific book.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://store.playstation.com/en-us/product/UP4064-CUSA17670_00-MOVINGOUT0000000/&quot;&gt;Moving Out&lt;/a&gt; on PS4&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Trivial Pursuit: Friends -- I had no idea my knowledge about the series is &lt;em&gt;that bad&lt;/em&gt;. Somebody should make a &#39;Trivial Pursuit: The Office&#39; 😁&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.powerlanguage.co.uk/wordle/&quot;&gt;Wordle&lt;/a&gt; and its Polish version &lt;a href=&quot;https://literalnie.fun&quot;&gt;literalnie.fun&lt;/a&gt; -- a linguistic version of Mastermind&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://gideonwolfe.com/posts/sysadmin/hugonginx/&quot;&gt;Blog post&lt;/a&gt; on how to deploy a &lt;a href=&quot;https://gohugo.io/&quot;&gt;Hugo&lt;/a&gt; blog with &lt;a href=&quot;https://www.nginx.com/&quot;&gt;NGINX&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.imdb.com/title/tt10944760/&quot;&gt;Titane&lt;/a&gt;, but I definitely don&#39;t recommend it to everyone&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.imdb.com/title/tt13315324/&quot;&gt;The Woman in the House Across the Street from the Girl in the Window&lt;/a&gt;, just released by Netflix. Watched only 3 episodes and I don&#39;t think it&#39;s &lt;em&gt;very&lt;/em&gt; funny, but I appreciate the idea to spoof all the thriller pulp produced in the last decade.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  <entry>
    <title>How not to use merge --squash</title>
    <link href="https://blog.wodkiewi.cz/posts/2019-06-24-how-not-to-merge-squash/"/>
    <updated>2019-06-24T00:00:00.000Z</updated>
    <id>https://blog.wodkiewi.cz/posts/2019-06-24-how-not-to-merge-squash/</id>
    <content type="html">&lt;p&gt;Merging branches using &amp;quot;--squash&amp;quot; has its advocates. The main (and also - the only) reason for squashing is to keep the history clean, but one can of course argue whether a commit containing a whole feature is easier to understand than a &amp;quot;dirty&amp;quot; history of incremental commits.&lt;/p&gt;
&lt;p&gt;Leaving the argument aside, there is one thing that you certainly shouldn&#39;t do and that is &lt;em&gt;squashing commits between long-lived branches&lt;/em&gt;. What&#39;s that? Suppose you have 2 main-ish parallel branches -- those can be 2 maintenance release branches, current and vNext development branches, you name it. Or maybe let &lt;em&gt;me&lt;/em&gt; name it: alpha and beta. And assume (without loss of generality) that beta is a younger, newer branch - all the changes that happen on alpha need to be merged into beta (but not necessarily the other way round).&lt;/p&gt;
&lt;p&gt;Now, let me paint you a picture.&lt;/p&gt;
&lt;h2&gt;Prolog&lt;/h2&gt;
&lt;p&gt;Your team has never squashed before so every merge on the repository has only been performed via pull requests with --no-ff option. Today as usual you are told to fix a bug that was discovered on branch alpha. You make a fix, create a pull request and after a successful review &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; you merge it into alpha. A commit 0a has been created. Because the bug also exists in the newer version of the system, you create a PR that merges alpha (with the fix) into beta. A PR is merged using --no-ff into beta the same day. A commit 0b has been created.&lt;/p&gt;
&lt;h2&gt;The next day&lt;/h2&gt;
&lt;p&gt;On a daily scrum your team decides that from now on you should merge every PR using only the squash method. You all seem to be happy with the proposal, because you&#39;ve always thought that linear git history is the best git history &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;. Your today&#39;s task -- to create a new feature for the alpha version. You push several commits and create a pull request. You then squash the content of the PR into alpha. A commit 1a is created.&lt;/p&gt;
&lt;p&gt;Then, you are told to merge the new stuff into the beta branch. So you create a pull request from alpha to beta. And then you perform the first squash merge into the beta branch. That&#39;s how you&#39;ve created commit 1b.&lt;/p&gt;
&lt;p&gt;At the same time your favourite colleague Andrew has been working on his alpha-feature. He created a PR as well and squashed his feature branch into alpha (creating commit 2a) after you had squashed yours. And now he wants to squash 2a into beta. He tries to do that, but hey, there&#39;s a conflict! Hmm, you and him have been working on different features, different parts of the system even, so how come the merge is not automatic? &amp;quot;I must have done something wrong&amp;quot; -- he thinks. Or more probably -- &amp;quot;Damn you git, what is your problem today?&amp;quot;. So Andrew with a frown on his face abandons the PR, creates an intermediate branch, resolves the conflict by hand locally, pushes the changes on the new branch, makes the PR and then squashes the PR into beta, which results in commit 2b.&lt;/p&gt;
&lt;h2&gt;A day after&lt;/h2&gt;
&lt;p&gt;You want to correct another nasty bug on the alpha branch. You fetch all the branches from remote and repeat the necessary steps to create a squash into alpha. All good for now -- commit 3a. Then you try squashing alpha into beta. Conflicts. And to your surprise, some of them are in Andrew&#39;s files? But how? You have only added new files, not modified anything! And even more, 2a is a direct parent of 3a and commit 2b has exactly the same diff as 2a!&lt;/p&gt;
&lt;p&gt;And that&#39;s how we get to the point -- 2a is an ancestor of 3a, but 2b isn&#39;t. 2a and 2b are two different commits, they just happen to share the exact same content. The same with commits 1a and 1b that caused Andrew some trouble a day earlier. Git merges commits based on their ancestor tree, not their content. Git does not care &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn3&quot; id=&quot;fnref3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt; that 1a contains the same changes to your foo.txt file as 1b. It cares that the last common ancestor of alpha and beta at that time was commit 0a.&lt;/p&gt;
&lt;p&gt;When Andrew tries to merge 2a into beta he wants to merge 2 branches that diverged at 0a and both have the content of foo.txt changed. That’s where the conflict comes from. And then when you try to merge 3a into beta you want to merge 2 branches that… also diverged at 0a but have changes in the foo.txt and bar.txt! The latest common ancestor hasn’t changed and will never do, unless someone finally merges (without squashing!) all the commits that do not exist in beta history. This will finally create a link between the branches that will release your team from neverending merge conflicts. Otherwise, every time you squash a PR from alpha into beta you create one more link in the conflict chain! Try to imagine what would happen if the team merged alpha into beta twice a month and were to discover the problem only after 3 months...&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;For the brevity of the article we skipped several phases. &lt;a href=&quot;#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Unbeknownst to you, the horrors are yet to come. &lt;a href=&quot;#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;citation needed &lt;a href=&quot;#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
</feed>
