-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
11 lines (7 loc) · 159 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>Codestar</title><meta name="description" content="Codestar blog"/><link rel="icon" href="/favicon.ico"/><meta name="next-head-count" content="5"/><link rel="preload" href="/_next/static/css/1dae025d113c10be.css" as="style"/><link rel="stylesheet" href="/_next/static/css/1dae025d113c10be.css" data-n-g=""/><link rel="preload" href="/_next/static/css/d928f4badedd04ed.css" as="style"/><link rel="stylesheet" href="/_next/static/css/d928f4badedd04ed.css" data-n-p=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-c67a75d1b6f99dc8.js"></script><script src="/_next/static/chunks/webpack-8fa1640cc84ba8fe.js" defer=""></script><script src="/_next/static/chunks/framework-7751730b10fa0f74.js" defer=""></script><script src="/_next/static/chunks/main-591bb7ec51acdc0d.js" defer=""></script><script src="/_next/static/chunks/pages/_app-7a7f6d01b75c52d8.js" defer=""></script><script src="/_next/static/chunks/247-af388da6cd2f75a5.js" defer=""></script><script src="/_next/static/chunks/pages/index-1a2c103b1fcd2611.js" defer=""></script><script src="/_next/static/UsvdpHIkUDDJ6_nTxVjoP/_buildManifest.js" defer=""></script><script src="/_next/static/UsvdpHIkUDDJ6_nTxVjoP/_ssgManifest.js" defer=""></script></head><body><div id="__next"><nav class="TopBar_top-bar__nWyL_"><div><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%27150%27%20height=%2740%27/%3e"/></span><img alt="Codestar Logo" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Codestar Logo" src="/_next/static/media/codestar_logo_dark.a44a4c76.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span><ul><li><a href="https://www.ordina.nl/vakgebieden/scala/">Contact</a></li></ul></div></nav><div class="Home_content__WcTpR"><aside><div class="EmbeddedSocialMedia_embedded-social-media___dIe_"><section class="TootCard_toot-card__jPU8P"><a href="https://mastodon.social/@codestar">@<!-- -->codestar<!-- -->@mastodon.social</a><div><p><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2724%27%20height=%2724%27/%3e"/></span><img alt="Codestar Mastodon" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Codestar Mastodon" src="/_next/static/media/mastodon_logo.a69bbfa8.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span><span>Thu, 10 Nov 2022</span></p><a href="https://mastodon.social/@codestar/109318878709762915">Join us on the 24th of november for a Robotics workshop at the Ordina office!!!
FREE registration through the link below and join us for an evening with a great developer community, lots of fun and challenging
assignments. Looking forward to seeing you there!!
https://docs.google.com/forms/d/e/1FAIpQLScausKDt8EA1TFds04ghHKXQ2cMeJHDt019nn1X0obOD3InvA/viewform
See the trailer here: https://www.linkedin.com/posts/rickyvanrijn_azure-ros2-cloud-activity-6996406427263082496-e1fX
#azure #ros2 #cloud #robotics #ordina #workshop #ros #fun</a><div class="TootCard_toot-card--badges__GmoM1"><span title="Replies"><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2718%27%20height=%2718%27/%3e"/></span><img alt="Replies" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Replies" src="/_next/static/media/fa-reply.0e7ce559.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span>0</span><span title="Reblogs"><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2718%27%20height=%2718%27/%3e"/></span><img alt="Reblogs" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Reblogs" src="/_next/static/media/fa-retweet.6b220c49.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span>1</span><span title="Favourites"><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2718%27%20height=%2718%27/%3e"/></span><img alt="Favourites" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Favourites" src="/_next/static/media/fa-star.54d45dfc.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span>1</span></div></div><div><p><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2724%27%20height=%2724%27/%3e"/></span><img alt="Codestar Mastodon" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Codestar Mastodon" src="/_next/static/media/mastodon_logo.a69bbfa8.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span><span>Wed, 09 Nov 2022</span></p><a href="https://mastodon.social/@codestar/109312667568153179">Join our meetup on 1 December with @StacyClouds about #Azure Web Apps with #Blazor!
https://www.meetup.com/codestar-night/events/289022760/</a><div class="TootCard_toot-card--badges__GmoM1"><span title="Replies"><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2718%27%20height=%2718%27/%3e"/></span><img alt="Replies" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Replies" src="/_next/static/media/fa-reply.0e7ce559.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span>0</span><span title="Reblogs"><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2718%27%20height=%2718%27/%3e"/></span><img alt="Reblogs" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Reblogs" src="/_next/static/media/fa-retweet.6b220c49.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span>1</span><span title="Favourites"><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2718%27%20height=%2718%27/%3e"/></span><img alt="Favourites" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Favourites" src="/_next/static/media/fa-star.54d45dfc.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span>1</span></div></div></section><div class="Playlist_playlist__Czddo viewport-sm"><a href="https://youtube.com/watch?v=v8rFXbLV03Q"><section class="PlaylistItemCard_playlistitem-card__JV1cM"><div class="img" style="background-image:url(https://i.ytimg.com/vi/v8rFXbLV03Q/mqdefault.jpg)"></div><h3>Met moderne technologie bouwen aan een duurzame software-oplossing</h3><p>Fri, 20 May 2022</p></section></a><a href="https://youtube.com/watch?v=yWV1eOozlOQ"><section class="PlaylistItemCard_playlistitem-card__JV1cM"><div class="img" style="background-image:url(https://i.ytimg.com/vi/yWV1eOozlOQ/mqdefault.jpg)"></div><h3>Ordina Codestar at Port Of Rotterdam</h3><p>Tue, 09 Nov 2021</p></section></a><a href="https://youtube.com/watch?v=tSesmVPwKZk"><section class="PlaylistItemCard_playlistitem-card__JV1cM"><div class="img" style="background-image:url(https://i.ytimg.com/vi/tSesmVPwKZk/mqdefault.jpg)"></div><h3>Ordina's draagt bij aan duurzame doelen van Havenbedrijf Rotterdam</h3><p>Wed, 27 Oct 2021</p></section></a><a href="https://youtube.com/watch?v=EaQt031BByw"><section class="PlaylistItemCard_playlistitem-card__JV1cM"><div class="img" style="background-image:url(https://i.ytimg.com/vi/EaQt031BByw/mqdefault.jpg)"></div><h3>Martin van Es - GraphQL for the Lazy Developer</h3><p>Tue, 01 Jun 2021</p></section></a><a href="https://youtube.com/watch?v=Uq5Y080Por0"><section class="PlaylistItemCard_playlistitem-card__JV1cM"><div class="img" style="background-image:url(https://i.ytimg.com/vi/Uq5Y080Por0/mqdefault.jpg)"></div><h3>Bart Kuijper - The Power of Demystifying Your Stack</h3><p>Tue, 01 Jun 2021</p></section></a><p><a href="https://youtube.com/c/codestar">More on YouTube...</a></p></div></div></aside><main class="Home_main__OVLM4"><section class="WelcomeCard_welcome-card__kInJh">Codestar makes highly available, scalable solutions with functional reactive programming in the back-end and frontend. Our colleagues are published in magazines and on blogs. Also see the<!-- --> <a href="https://youtube.com/c/codestar">Codestar YouTube</a> channel for our talks at conferences.</section><div class="UpcomingMeetupList_upcoming-meetup-list__lsISq viewport-xs"></div><a href="https://medium.com/codestar-blog/micro-frontends-in-a-nutshell-cbf6741337d?source=rss----ea5cff13e3c9---4" class="PublicationCard_publication-card__nbEiY"><section><div class="PublicationCard_publication-card--avatar__zhBBA" style="background-image:url(https://miro.medium.com/fit/c/176/176/0*gTl35Xy5zRcgu5wJ.png)"></div><div><p class="PublicationCard_publication-card--author__N0_M_">mdworld</p><p class="PublicationCard_publication-card--date__E68DP">Fri, 08 Apr 2022</p><h2>Micro Frontends in A Nutshell</h2></div></section></a><a href="https://medium.com/codestar-blog/tika-nerding-getting-started-using-named-entity-recognition-with-opennlp-on-the-jvm-scala-java-befc396d6dc5?source=rss----ea5cff13e3c9---4" class="PublicationCard_publication-card__nbEiY"><section><div class="PublicationCard_publication-card--avatar__zhBBA" style="background-image:url(https://miro.medium.com/fit/c/88/88/0*Bqr-dMZplB-namyY.jpg)"></div><div><p class="PublicationCard_publication-card--author__N0_M_">Nathan Perdijk</p><p class="PublicationCard_publication-card--date__E68DP">Fri, 06 Nov 2020</p><h2>Tika NERding: Getting started using Named-Entity Recognition with OpenNLP on the JVM (Scala, Java…</h2></div></section></a><a href="https://medium.com/codestar-blog/tika-tika-getting-started-doing-ocr-with-apache-tika-andtesseract-from-the-jvm-f5d2bfe9b397?source=rss----ea5cff13e3c9---4" class="PublicationCard_publication-card__nbEiY"><section><div class="PublicationCard_publication-card--avatar__zhBBA" style="background-image:url(https://miro.medium.com/fit/c/88/88/0*Bqr-dMZplB-namyY.jpg)"></div><div><p class="PublicationCard_publication-card--author__N0_M_">Nathan Perdijk</p><p class="PublicationCard_publication-card--date__E68DP">Fri, 10 Apr 2020</p><h2>Tika Tika! Getting started doing OCR with Apache Tika andTesseract from the JVM</h2></div></section></a><a href="https://medium.com/codestar-blog/upgrading-to-angular-9-my-experience-65158c284034?source=rss----ea5cff13e3c9---4" class="PublicationCard_publication-card__nbEiY"><section><div class="PublicationCard_publication-card--avatar__zhBBA" style="background-image:url(https://miro.medium.com/fit/c/176/176/0*o9UzuQyUwobacrCt.jpeg)"></div><div><p class="PublicationCard_publication-card--author__N0_M_">Bjorn ‘Bjeaurn’</p><p class="PublicationCard_publication-card--date__E68DP">Fri, 14 Feb 2020</p><h2>Upgrading to Angular 9: My experience</h2></div></section></a><a href="https://medium.com/codestar-blog/leibniz-equality-in-typescript-2aeff1303749?source=rss----ea5cff13e3c9---4" class="PublicationCard_publication-card__nbEiY"><section><div class="PublicationCard_publication-card--avatar__zhBBA">W</div><div><p class="PublicationCard_publication-card--author__N0_M_">Werner de Groot</p><p class="PublicationCard_publication-card--date__E68DP">Tue, 25 Jun 2019</p><h2>Leibniz equality in TypeScript</h2></div></section></a><a href="https://medium.com/codestar-blog/event-sourcing-with-akka-persistence-6a3f4b167852?source=rss----ea5cff13e3c9---4" class="PublicationCard_publication-card__nbEiY"><section><div class="PublicationCard_publication-card--avatar__zhBBA" style="background-image:url(https://miro.medium.com/fit/c/88/88/2*k7vMxGfKwfqJ86TcprDA_Q.jpeg)"></div><div><p class="PublicationCard_publication-card--author__N0_M_">Nick ten Veen</p><p class="PublicationCard_publication-card--date__E68DP">Fri, 07 Jun 2019</p><h2>Event sourcing with Akka Persistence</h2></div></section></a><a href="https://medium.com/codestar-blog/how-we-automated-our-angular-updates-9790212aa211?source=rss----ea5cff13e3c9---4" class="PublicationCard_publication-card__nbEiY"><section><div class="PublicationCard_publication-card--avatar__zhBBA" style="background-image:url(https://miro.medium.com/fit/c/176/176/0*o9UzuQyUwobacrCt.jpeg)"></div><div><p class="PublicationCard_publication-card--author__N0_M_">Bjorn ‘Bjeaurn’</p><p class="PublicationCard_publication-card--date__E68DP">Tue, 21 May 2019</p><h2>How we automated our Angular updates</h2></div></section></a><a href="https://medium.com/codestar-blog/apollo-client-in-practice-f81434f6f8d7?source=rss----ea5cff13e3c9---4" class="PublicationCard_publication-card__nbEiY"><section><div class="PublicationCard_publication-card--avatar__zhBBA" style="background-image:url(https://miro.medium.com/fit/c/176/176/0*gTl35Xy5zRcgu5wJ.png)"></div><div><p class="PublicationCard_publication-card--author__N0_M_">mdworld</p><p class="PublicationCard_publication-card--date__E68DP">Thu, 02 May 2019</p><h2>Apollo Client in Practice</h2></div></section></a><a href="https://medium.com/codestar-blog/sharing-is-caring-domain-objects-in-both-scala-and-r-with-graalvm-polyglot-bindings-b561e8cfbcfa?source=rss----ea5cff13e3c9---4" class="PublicationCard_publication-card__nbEiY"><section><div class="PublicationCard_publication-card--avatar__zhBBA" style="background-image:url(https://miro.medium.com/fit/c/88/88/0*Bqr-dMZplB-namyY.jpg)"></div><div><p class="PublicationCard_publication-card--author__N0_M_">Nathan Perdijk</p><p class="PublicationCard_publication-card--date__E68DP">Wed, 01 May 2019</p><h2>Sharing is Caring! Domain objects in BOTH Scala and R with GraalVM Polyglot bindings.</h2></div></section></a><a href="https://medium.com/codestar-blog/using-generative-art-to-create-a-pulsating-svg-star-cd7456268dc5?source=rss----ea5cff13e3c9---4" class="PublicationCard_publication-card__nbEiY"><section><div class="PublicationCard_publication-card--avatar__zhBBA" style="background-image:url(https://miro.medium.com/fit/c/176/176/2*1JTGoMi8_nuGQVO1EoItXg.png)"></div><div><p class="PublicationCard_publication-card--author__N0_M_">Hamza Haiken</p><p class="PublicationCard_publication-card--date__E68DP">Fri, 12 Apr 2019</p><h2>Using generative art to create a pulsating SVG star</h2></div></section></a><div class="Playlist_playlist__Czddo viewport-xs"><a href="https://youtube.com/watch?v=v8rFXbLV03Q"><section class="PlaylistItemCard_playlistitem-card__JV1cM"><div class="img" style="background-image:url(https://i.ytimg.com/vi/v8rFXbLV03Q/mqdefault.jpg)"></div><h3>Met moderne technologie bouwen aan een duurzame software-oplossing</h3><p>Fri, 20 May 2022</p></section></a><p><a href="https://youtube.com/c/codestar">More on YouTube...</a></p></div></main><aside><div class="MeetupCardList_meetup-list__A1TuS"><div class="UpcomingMeetupList_upcoming-meetup-list__lsISq viewport-sm"></div><section class="MeetupCard_meetup-card__0J0_Y "><h2>PAST MEETUPS</h2><ul><li><a href="https://www.meetup.com/codestar-night/events/296766473/"><h3>Workshop Red Hat Ansible Lightspeed and other Ansible development tools</h3><p>Thu, 30 Nov 2023</p></a></li><li><a href="https://www.meetup.com/codestar-night/events/296966454/"><h3>Codesmiths Unite </h3><p>Thu, 23 Nov 2023</p></a></li><li><a href="https://www.meetup.com/codestar-night/events/296928992/"><h3>Tech Women Connect</h3><p>Thu, 23 Nov 2023</p></a></li><li><a href="https://www.meetup.com/codestar-night/events/296486807/"><h3>Ordina Frontend Community presents: Back to basics panel discussion</h3><p>Thu, 19 Oct 2023</p></a></li><li><a href="https://www.meetup.com/codestar-night/events/295795991/"><h3>Creating UI libraries by utilizing Storybook, ReactJs, NPM and Azure.</h3><p>Thu, 28 Sept 2023</p></a></li><li><a href="https://www.meetup.com/codestar-night/events/296251627/"><h3>Workshop Red Hat OpenShift</h3><p>Wed, 27 Sept 2023</p></a></li><li><a href="https://www.meetup.com/codestar-night/events/292995726/"><h3>AI Hackathon</h3><p>Thu, 29 Jun 2023</p></a></li><li><a class="external" href="https://www.meetup.com/codestar-night/events/past/">More past meetups...</a></li></ul></section></div></aside></div><footer class="Footer_footer__Dhw_9"><div><ul class="contact-info"><li><a href="mailto:codestar@ordina.nl">codestar@ordina.nl</a></li><li><a href="tel:+31306637000">+31 30 6637000</a></li><li><a href="https://maps.google.com/maps?ll=52.057652,5.111462&z=16&t=m&hl=en-GB&gl=NL&mapclient=embed&cid=15918536717636328792" target="_blank" rel="noopener noreferrer">Ringwade 1, 3439 LM Nieuwegein</a></li></ul><p class="social-links"><a href="https://mastodon.social/@codestar" aria-label="Mastodon" rel="me"><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2732%27%20height=%2732%27/%3e"/></span><img alt="Codestar Mastodon" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Codestar Mastodon" src="/_next/static/media/mastodon_logo.a69bbfa8.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span></a><a href="https://twitter.com/codestar_nl" aria-label="Twitter"><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2732%27%20height=%2732%27/%3e"/></span><img alt="Codestar Twitter" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Codestar Twitter" src="/_next/static/media/twitter_logo.db6b7c1a.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span></a><a href="https://github.com/code-star" aria-label="Github"><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2732%27%20height=%2732%27/%3e"/></span><img alt="Codestar Github" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Codestar Github" src="/_next/static/media/github_logo.6b78551b.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span></a><a href="https://medium.com/codestar-blog" aria-label="Medium"><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2732%27%20height=%2732%27/%3e"/></span><img alt="Codestar Medium" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Codestar Medium" src="/_next/static/media/medium_logo.085f2fbb.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span></a><a href="https://www.linkedin.com/company/codestar-powered-by-ordina/" aria-label="Linkedin"><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2732%27%20height=%2732%27/%3e"/></span><img alt="Codestar Medium" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Codestar Medium" src="/_next/static/media/linkedin_logo.8dbb4d97.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span></a><a href="https://www.youtube.com/channel/UCqwHhJNEUe7D-HGsX4zvKzQ" aria-label="Youtube"><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2736%27%20height=%2732%27/%3e"/></span><img alt="Codestar Medium" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Codestar Medium" src="/_next/static/media/youtube_logo.1dfaa880.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span></a><a href="https://www.meetup.com/Code-Star-Night" aria-label="Meetup.com"><span style="box-sizing:border-box;display:inline-block;overflow:hidden;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;position:relative;max-width:100%"><span style="box-sizing:border-box;display:block;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0;max-width:100%"><img style="display:block;max-width:100%;width:initial;height:initial;background:none;opacity:1;border:0;margin:0;padding:0" alt="" aria-hidden="true" src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2732%27%20height=%2732%27/%3e"/></span><img alt="Codestar Medium" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%"/><noscript><img alt="Codestar Medium" src="/_next/static/media/meetup_logo.32a9c75f.svg" decoding="async" data-nimg="intrinsic" style="position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%" loading="lazy"/></noscript></span></a></p></div></footer></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"publications":[{"id":"https://medium.com/p/cbf6741337d","title":"Micro Frontends in A Nutshell","author":"mdworld","latestPublishedAt":"Fri, 08 Apr 2022 06:56:06 GMT","uniqueSlug":"https://medium.com/codestar-blog/micro-frontends-in-a-nutshell-cbf6741337d?source=rss----ea5cff13e3c9---4","paragraphs":"\u003cp\u003eYou may have heard of a Micro Frontends recently and felt it a bit difficult to grasp what exactly it is and if it is something you should get involved in. I’ll try to give a summary of the what, why, how, and when of the current state. To provide a high-over summary, I’ll also add some recommended reading if you would like to get more details.\u003c/p\u003e\u003ch3\u003eWhy use Micro Frontends?\u003c/h3\u003e\u003cp\u003eDo you have a very large front-end code-base?\u003c/p\u003e\u003cp\u003eAnd by large, I’m talking about 50+ developers in a dozen of teams or more, probably cross-department, working on the same code-base in some manner. Do you have enterprise-scale continuous integration with e.g. GitLab, Bamboo running so many pipelines that the bottleneck is no longer a matter of adding more pods? Do you employ configuration managers or an Ops department to make sure deployments won’t affect each other too much? Do you have considerable codebases in incompatible front-end stacks, e.g. because of a migration from AngularJS to Angular \u003e2?\u003c/p\u003e\u003cp\u003eThen chances are you need to use Micro Frontends. Or actually, you most probably are \u003cem\u003ealready\u003c/em\u003e using Micro Frontends.\u003c/p\u003e\u003ch3\u003eWhat are Micro Frontends?\u003c/h3\u003e\u003cp\u003eHow is it possible you would not know you are using Micro Frontends? And why are we just now hearing so much about them? The truth is that although the term is relatively new it actually covers \u003cstrong\u003eany range of solutions to integrate a collection of smaller frontends into one application\u003c/strong\u003e.\u003c/p\u003e\u003cp\u003eSimilar to Micro Service architectures, Micro Frontends facilitate large codebases by breaking them up into manageable pieces. This means:\u003c/p\u003e\u003cul\u003e\u003cli\u003eTechnological stack across Micro Frontends in the same application may differ\u003c/li\u003e\u003cli\u003eA Micro Frontend has a clear and concise purpose, following the SOLID principles\u003c/li\u003e\u003cli\u003eTeams of developers maintain one or more Micro Frontend that are isolated in runtime from the rest of the code\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eThe term is now popularized because of the advent of \u003cem\u003eModule Federation\u003c/em\u003e in Webpack 5. Webpack 5 has been released towards the end of 2020, but this new major release is taking some time to be integrated in relevant tooling, e.g. Nx and Ng CLI.\u003c/p\u003e\u003cp\u003eNote that Micro Frontends (MFEs) are sometimes also referred to as \u003cem\u003eMicro Apps\u003c/em\u003e.\u003c/p\u003e\u003ch3\u003eHow do you build Micro Frontends?\u003c/h3\u003e\u003cp\u003eSince Micro Frontends as a concept are not new, some solutions that can be classified as Micro Frontends are ancient, considering the speed of development in the frontend ecosystem. Here are some of them, to give an idea of how broad Micro Frontends can be interpreted:\u003c/p\u003e\u003cul\u003e\u003cli\u003eRun several frontend applications on different URLs and cross refer them with plain \u003cstrong\u003ehyperlinks\u003c/strong\u003e\u003c/li\u003e\u003cli\u003eRun several frontend applications on different URLs on the same page in \u003cstrong\u003eiframes\u003c/strong\u003e\u003c/li\u003e\u003cli\u003eDevelop frontend components in separate teams and integrate them at build time to be deployed as a \u003cstrong\u003edeployment monolith\u003c/strong\u003e\u003c/li\u003e\u003cli\u003eUse macro \u003cstrong\u003eWeb Components\u003c/strong\u003e as an abstraction layer for components\u003c/li\u003e\u003cli\u003eDevelop frontend components in separate teams and integrate them at runtime with \u003cstrong\u003eModule Federation\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eI won’t go into all the details about the pros and cons of each of these solutions. Instead I refer you to the recommended reading list below.\u003c/p\u003e\u003cp\u003eNote that solutions can be combined: you can have a deployment monolith (that expects components that are all using the same stack) but wrap components in Web Components to provide an abstraction layer and use different stacks to produce the Web Components. Additionally, you can use Web Components in combination with Module Federation for instance if you are migrating towards Module Federation as a Micro Frontends solution. Consider this schematic representation of a web application:\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/1024/1*pql8S-NvSjqcqruEhI9mSw.png\" /\u003e\u003cfigcaption\u003eSchematic representation of a web application\u003c/figcaption\u003e\u003c/figure\u003e\u003cp\u003eThis could be implemented with different platforms like Angular and React by wrapping them in Web Components:\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/1024/1*sJHpfDClwKyFoaIpNp6sgg.png\" /\u003e\u003cfigcaption\u003eWeb Components diagram\u003c/figcaption\u003e\u003c/figure\u003e\u003cp\u003eModule Federation is the newest solution and many libraries are still adapting to it. Last year, Nx 12 released with support for Webpack 5 and Module Federation. See a real working example here \u003ca href=\"https://code-star.github.io/nx-reference-shell/\"\u003ehttps://code-star.github.io/nx-reference-shell/\u003c/a\u003e or its source in \u003ca href=\"https://github.com/code-star/nx-reference\"\u003ehttps://github.com/code-star/nx-reference\u003c/a\u003e.\u003c/p\u003e\u003cp\u003eBecause Micro Frontends break up a codebase into smaller, more manageable fragments, they are often mentioned in combination with Monorepo solutions like Nx or yarn/npm workspaces. However, it is perfectly possible to implement Micro Frontends without monorepos!\u003c/p\u003e\u003ch3\u003eWhen to use Micro Frontends?\u003c/h3\u003e\u003cp\u003eNew technology inspires developers to experiment, but Micro Frontends and with that Module Federation are not worth the upkeep for small to medium applications. All-in solutions like Next or Gatsby are great fits for smaller applications and custom Angular applications, when well organized, scale very well up to enterprise level.\u003c/p\u003e\u003cp\u003eHowever, no framework inherently supports older versions of itself. So if a big bang migration from AngularJS to Angular or any other framework for that matter, you’ll end up with some kind of Micro Frontends solution. Plenty of enterprise codebases currently use some combination of hyperlinks and deployment monoliths.\u003c/p\u003e\u003cp\u003eThis could look like a bank that offers a set of public pages (e.g. the general home page, and the landing pages of its departments) referencing each other with hyperlinks and a protected monolith app with many components (e.g. checking account, subscriptions to bank products, investments on one page).\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/1024/1*QJZ-f4Ptx1_eZ24nLZ4Kow.png\" /\u003e\u003cfigcaption\u003eHyperlinks and Monolith diagram\u003c/figcaption\u003e\u003c/figure\u003e\u003cp\u003eExploring Module Federation can be worth it if continuous integration is slowed down too much because of the large amounts of tests and compilation of all the involved components. But note that there are other approaches, such as using Nx monorepos with properly set up hierarchy and running only affected tests.\u003c/p\u003e\u003cp\u003eAnother reason to use Module Federation can be the need to support multiple frameworks. Compared to Web Components, Module Federation improves the runtime isolation of components while simultaneously reducing isolation of shared dependencies to reduce the overall footprint of the application.\u003c/p\u003e\u003cp\u003eCompare to the diagram for the earlier example using macro Web Components, you can see that lodash, Angular and React are only loaded once, despite being used by multiple isolated components:\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/1024/1*WqOZsQ8xnX1iJg3PPHcilg.png\" /\u003e\u003cfigcaption\u003eModule Federation diagram\u003c/figcaption\u003e\u003c/figure\u003e\u003ch3\u003eWant to know more?\u003c/h3\u003e\u003cp\u003eIf you want to know more about Micro Frontends, Module Federation or Monorepos, you can contact met at \u003ca href=\"https://twitter.com/mdworldNL\"\u003e@mdworldNL\u003c/a\u003e on Twitter or mail codestar@ordina.nl. We have experience with enterprise frontend at all the major banks and many governmental departments in the Netherlands.\u003c/p\u003e\u003cp\u003eWhen you want more background information as a developer, you can also read the articles provided below.\u003c/p\u003e\u003ch3\u003eRecommended in-depth reading\u003c/h3\u003e\u003cul\u003e\u003cli\u003eIntroduction to Micro Frontends: \u003ca href=\"https://micro-frontends.org/\"\u003ehttps://micro-frontends.org/\u003c/a\u003e\u003c/li\u003e\u003cli\u003eIntroduction to Micro Frontends: \u003ca href=\"https://martinfowler.com/articles/micro-frontends.html\"\u003ehttps://martinfowler.com/articles/micro-frontends.html\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eAngular Architects:\u003c/p\u003e\u003cul\u003e\u003cli\u003eMicro Frontends introduction: \u003ca href=\"https://www.angulararchitects.io/en/aktuelles/a-software-architects-approach-towards/\"\u003ehttps://www.angulararchitects.io/en/aktuelles/a-software-architects-approach-towards/\u003c/a\u003e\u003c/li\u003e\u003cli\u003eMicro Frontends series: \u003ca href=\"https://www.angulararchitects.io/en/aktuelles/micro-apps-with-web-components-using-angular-elements/\"\u003ehttps://www.angulararchitects.io/en/aktuelles/micro-apps-with-web-components-using-angular-elements/\u003c/a\u003e\u003c/li\u003e\u003cli\u003eModule Federation series: \u003ca href=\"https://www.angulararchitects.io/en/aktuelles/the-microfrontend-revolution-module-federation-in-webpack-5/\"\u003ehttps://www.angulararchitects.io/en/aktuelles/the-microfrontend-revolution-module-federation-in-webpack-5/\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eBy my colleague Peter Eijgermans:\u003c/p\u003e\u003cul\u003e\u003cli\u003eMicro Frontends by Example: \u003ca href=\"https://dzone.com/articles/micro-frontends-by-example-8\"\u003ehttps://dzone.com/articles/micro-frontends-by-example-8\u003c/a\u003e\u003c/li\u003e\u003cli\u003e(Video) Micro Frontends: The What, the Why and the How by Peter Eijgermans \u003ca href=\"https://youtu.be/TWcoziCdPkE\"\u003ehttps://youtu.be/TWcoziCdPkE\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eThis article was originally published at \u003ca href=\"https://mdworld.nl/micro-frontends-in-a-nutshell\"\u003ehttps://mdworld.nl/micro-frontends-in-a-nutshell\u003c/a\u003e\u003c/p\u003e\u003cimg src=\"https://medium.com/_/stat?event=post.clientViewed\u0026referrerSource=full_rss\u0026postId=cbf6741337d\" width=\"1\" height=\"1\" alt=\"\"\u003e\u003chr\u003e\u003cp\u003e\u003ca href=\"https://medium.com/codestar-blog/micro-frontends-in-a-nutshell-cbf6741337d\"\u003eMicro Frontends in A Nutshell\u003c/a\u003e was originally published in \u003ca href=\"https://medium.com/codestar-blog\"\u003eCodestar blog\u003c/a\u003e on Medium, where people are continuing the conversation by highlighting and responding to this story.\u003c/p\u003e"},{"id":"https://medium.com/p/befc396d6dc5","title":"Tika NERding: Getting started using Named-Entity Recognition with OpenNLP on the JVM (Scala, Java…","author":"Nathan Perdijk","latestPublishedAt":"Fri, 06 Nov 2020 15:14:42 GMT","uniqueSlug":"https://medium.com/codestar-blog/tika-nerding-getting-started-using-named-entity-recognition-with-opennlp-on-the-jvm-scala-java-befc396d6dc5?source=rss----ea5cff13e3c9---4","paragraphs":"\u003ch3\u003eTika NERding: Getting started using Named-Entity Recognition with OpenNLP on the JVM (Scala, Java, Kotlin…)\u003c/h3\u003e\u003cp\u003e\u003cem\u003eFor DataScience!\u003c/em\u003e\u003c/p\u003e\u003cp\u003eSome things are hard, some things are not… Turns out that doing NER (Named-Entity Recognition) on the JVM is… not! (Wait, \u003ca href=\"https://medium.com/codestar-blog/tika-tika-getting-started-doing-ocr-with-apache-tika-andtesseract-from-the-jvm-f5d2bfe9b397\"\u003e\u003cem\u003ethat sounds familiar\u003c/em\u003e\u003c/a\u003e…)\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/292/1*QvLkMzKtFw0DxqZ-pWiL8g.jpeg\" /\u003e\u003c/figure\u003e\u003cp\u003e\u003ca href=\"https://en.wikipedia.org/wiki/Named-entity_recognition\"\u003eNER\u003c/a\u003e is the automated process of annotating words and phrases in sentences with relevant entity information, such as marking a word as a Person, or a Location. This can come in quite handy when doing automated text analysis and is a staple in the DataScience community. As the trouble with DataScience is often getting it into production, it is extremely handy that this technique can be directly used from JVM-languages. Now we can embed this technology in production ready applications built in Java, Scala, Kotlin...\u003c/p\u003e\u003cp\u003eFirst things first, the dependencies. These are all the dependencies from the .pom.xml file used for this example project:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/263fe830248a9ab31ed27dc9f4c55d4f/href\"\u003ehttps://medium.com/media/263fe830248a9ab31ed27dc9f4c55d4f/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eYes, that’s it.\u003c/p\u003e\u003cp\u003eFor doing NER on String this is really all we need, but Apache Tika can also extract text from PDFs or even \u003ca href=\"https://medium.com/codestar-blog/tika-tika-getting-started-doing-ocr-with-apache-tika-andtesseract-from-the-jvm-f5d2bfe9b397\"\u003eperform OCR\u003c/a\u003e, but you’ll need additional dependencies.\u003c/p\u003e\u003cp\u003eThen we need to download the models that we want to use and place them in our resources folder. You can download suitable OpenNLP models from \u003ca href=\"http://opennlp.sourceforge.net/models-1.5/\"\u003ehttp://opennlp.sourceforge.net/models-1.5/\u003c/a\u003e. These are conveniently wrapped in .bin format and should NOT be unpacked.\u003c/p\u003e\u003cp\u003eFor this example, we will be using English language Models that can recognise Date, Location, Organization and Person, but there are also models available in other languages. Every model you want to use, you’ll need to add to a Java Map (or you can use SystemProperties for Tika to “discover”, but that’s a method I don’t like very much):\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/900c319c1e33e98775dfd07672bb5099/href\"\u003ehttps://medium.com/media/900c319c1e33e98775dfd07672bb5099/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eNow models contains four models, so let’s feed them to Tika:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/addf4d01e6a3f6ef13603e4498d38934/href\"\u003ehttps://medium.com/media/addf4d01e6a3f6ef13603e4498d38934/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eAlright, now all we need is to feed a String of text to the nerRecogniser:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/107c4b2797d7b06aee4d6160c7fd37e9/href\"\u003ehttps://medium.com/media/107c4b2797d7b06aee4d6160c7fd37e9/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eAnd now you can just go about using the results. Tika will return a Map, containing a key for each model that has managed to find matching results, and with each key there’s a value containing those results. In order to improve the prints, I’ve done a bit of tinkering as it is now DEMO time.\u003c/p\u003e\u003cp\u003eI’m using the contents of the \u003ca href=\"https://en.wikipedia.org/\"\u003eWikipedia\u003c/a\u003e article on the \u003ca href=\"https://en.wikipedia.org/wiki/Peace_of_Utrecht\"\u003ePeace of Utrecht\u003c/a\u003e.\u003c/p\u003e\u003cp\u003eFor the first paragraph, this is my input text:\u003c/p\u003e\u003cpre\u003e\"The Peace of Utrecht is a series of peace treaties signed by the belligerents in the War of the Spanish Succession, in the Dutch city of Utrecht between April 1713 and February 1715. The war involved three contenders for the vacant throne of Spain, and involved much of Europe for over a decade. The main action saw France as the defender of Spain against a multinational coalition. The war was very expensive and bloody and finally stalemated. Essentially, the treaties allowed Philip V (grandson of King Louis XIV of France) to keep the Spanish throne in return for permanently renouncing his claim to the French throne, along with other necessary guarantees that would ensure that France and Spain should not merge, thus preserving the balance of power in Europe.\\n\\nThe treaties between several European states, including Spain, Great Britain, France, Portugal, Savoy and the Dutch Republic, helped end the war. The treaties were concluded between the representatives of Louis XIV of France and of his grandson Philip on one hand, and representatives of Anne of Great Britain, Victor Amadeus II of Sardinia, John V of Portugal and the United Provinces of the Netherlands on the other. Though the king of France ensured the Spanish crown for his dynasty, the treaties marked the end of French ambitions of hegemony in Europe expressed in the continuous wars of Louis XIV, and paved the way to the European system based on the balance of power.[1] British historian G. M. Trevelyan argues:\\n\\nThat Treaty, which ushered in the stable and characteristic period of Eighteenth-Century civilization, marked the end of danger to Europe from the old French monarchy, and it marked a change of no less significance to the world at large, — the maritime, commercial and financial supremacy of Great Britain.[2]\\n\\nAnother enduring result was the creation of the Spanish Bourbon Dynasty, still reigning over Spain up to the present while the original House of Bourbon has long since been dethroned in France.\"\u003c/pre\u003e\u003cp\u003eAnd these are the results from Tika NER:\u003c/p\u003e\u003cpre\u003eLocations: Britain, Milan, Nova Scotia, Cape Breton, Italy, France, Africa, Sicily, North Sea, North America, Amazon, Spain, Rastatt, Portugal, Sacramento, North\u003c/pre\u003e\u003cpre\u003eOrganisations: Article XIII, Spain\u003c/pre\u003e\u003cpre\u003ePersons: Philip V, Philippe, Philip, Louis XIV's, Louis XV, Charles VI., Oyapock, Saint Kitts\u003c/pre\u003e\u003cpre\u003eDate: 1713, 1720, 1713., 1712, 1714\u003c/pre\u003e\u003cp\u003eAnd a second example, the second part of the article:\u003c/p\u003e\u003cpre\u003e\"The War of the Spanish Succession was occasioned by the failure of the Habsburg king, Charles II of Spain, to produce an heir. Dispute followed the death of Charles II in 1700, and fourteen years of war were the result.\\n\\nFrance and Great Britain had come to terms in October 1711, when the preliminaries of peace had been signed in London. The preliminaries were based on a tacit acceptance of the partition of Spain's European possessions. Following this, the Congress of Utrecht opened on 29 January 1712, with the British representatives being John Robinson, Bishop of Bristol, and Thomas Wentworth, Lord Strafford.[3] Reluctantly the United Provinces accepted the preliminaries and sent representatives, but Emperor Charles VI refused to do so until he was assured that the preliminaries were not binding. This assurance was given, and so in February the Imperial representatives made their appearance. As Philip was not yet recognized as its king, Spain did not at first send plenipotentiaries, but the Duke of Savoy sent one, and the Kingdom of Portugal was represented by Luís da Cunha. One of the first questions discussed was the nature of the guarantees to be given by France and Spain that their crowns would be kept separate, and little progress was made until 10 July 1712, when Philip signed a renunciation.[4]\\n\\nWith Great Britain, France and Spain having agreed to a \\\"suspension of arms\\\" (armistice) covering Spain on 19 August in Paris, the pace of negotiation quickened. The first treaty signed at Utrecht was the truce between France and Portugal on 7 November, followed by the truce between France and Savoy on 14 March 1714. That same day, Spain, Great Britain, France and the Empire agreed to the evacuation of Catalonia and an armistice in Italy. The main treaties of peace followed on 11 April 1713. These were five separate treaties between France and Great Britain, the Netherlands, Savoy, Prussia and Portugal. Spain under Philip V signed separate peace treaties with Savoy and Great Britain at Utrecht on 13 July. Negotiations at Utrecht dragged on into the next year, for the peace treaty between Spain and the Netherlands was only signed on 26 June 1714 and that between Spain and Portugal on 6 February 1715.[5]\\n\\nSeveral other treaties came out of the congress of Utrecht. France signed treaties of commerce and navigation with Great Britain and the Netherlands (11 April 1713). Great Britain signed a like treaty with Spain (9 December 1713).[5]\"\u003c/pre\u003e\u003cp\u003eAnd the results:\u003c/p\u003e\u003cpre\u003eLocations: 1715.[16], Britain, Spanish Netherlands, Austrian Netherlands, France\u003c/pre\u003e\u003cpre\u003eOrganisations: Oxford, House of, United Provinces, Dutch, Austro-Dutch Barrier Treaty, Harley, Duke, Earl, Allied\u003c/pre\u003e\u003cpre\u003ePersons: Robert Harley, William III, Earl\u003c/pre\u003e\u003cpre\u003eDate: 1710, 1709., May 1711), 1706\u003c/pre\u003e\u003cp\u003eAs you can see, not everything is found, or classified correctly, but it provides a good starting point for further text analysis and it took very little effort to get this working at all! Named-Entity Recognition is a tricky technique, so you may need to preprocess your texts a bit before you get good analysis results for your particular data set, but it’s definitely not difficult to get started.\u003c/p\u003e\u003cp\u003eYou can download suitable OpenNLP models from \u003ca href=\"http://opennlp.sourceforge.net/models-1.5/\"\u003ehttp://opennlp.sourceforge.net/models-1.5/\u003c/a\u003e.\u003c/p\u003e\u003cp\u003eCheck out the \u003ca href=\"https://tika.apache.org/\"\u003eApache Tika documentation\u003c/a\u003e to see what other great functionality is available.\u003c/p\u003e\u003cp\u003eIf you want to take a closer look at this example, you can check it out from Github: \u003ca href=\"https://github.com/NRBPerdijk/examplenertikascala/\"\u003ehttps://github.com/NRBPerdijk/examplenertikascala/\u003c/a\u003e\u003c/p\u003e\u003cp\u003eLast but not least, kudos to the Apache Software Foundation for their continuing work towards great Open Source solutions.\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/700/1*cQGXudGNVjRGDM2uB-BuGA.jpeg\" /\u003e\u003c/figure\u003e\u003cimg src=\"https://medium.com/_/stat?event=post.clientViewed\u0026referrerSource=full_rss\u0026postId=befc396d6dc5\" width=\"1\" height=\"1\" alt=\"\"\u003e\u003chr\u003e\u003cp\u003e\u003ca href=\"https://medium.com/codestar-blog/tika-nerding-getting-started-using-named-entity-recognition-with-opennlp-on-the-jvm-scala-java-befc396d6dc5\"\u003eTika NERding: Getting started using Named-Entity Recognition with OpenNLP on the JVM (Scala, Java…\u003c/a\u003e was originally published in \u003ca href=\"https://medium.com/codestar-blog\"\u003eCodestar blog\u003c/a\u003e on Medium, where people are continuing the conversation by highlighting and responding to this story.\u003c/p\u003e"},{"id":"https://medium.com/p/f5d2bfe9b397","title":"Tika Tika! Getting started doing OCR with Apache Tika andTesseract from the JVM","author":"Nathan Perdijk","latestPublishedAt":"Fri, 10 Apr 2020 15:29:03 GMT","uniqueSlug":"https://medium.com/codestar-blog/tika-tika-getting-started-doing-ocr-with-apache-tika-andtesseract-from-the-jvm-f5d2bfe9b397?source=rss----ea5cff13e3c9---4","paragraphs":"\u003ch3\u003eTika Tika! Getting started doing OCR with Apache Tika andTesseract from the JVM (Scala, Java, Kotlin…).\u003c/h3\u003e\u003cp\u003e\u003cem\u003eI can do DataScience, mate!\u003c/em\u003e\u003c/p\u003e\u003cp\u003eSome things are hard. Some things are not… Turns out that using OCR (Object Character Recognition) using Tesseract from the JVM is… not hard!\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/292/1*Aj8UgvxNf7r4zTjs-JqL7A.jpeg\" /\u003e\u003c/figure\u003e\u003cp\u003eThe trickiest part, really, is \u003ca href=\"https://github.com/tesseract-ocr/tesseract/wiki\"\u003esetting up Tesseract\u003c/a\u003e on the machine you want to do your OCR on. Once you have managed to do that, you can just use the following Scala examples to use \u003cstrong\u003eApache Tika\u003c/strong\u003e to do OCR in your own JVM project.\u003c/p\u003e\u003ch4\u003e\u003cstrong\u003eFirst things first. Taking care of your dependencies…\u003c/strong\u003e\u003c/h4\u003e\u003cp\u003eAdd these to your pom.xml or other build tool equivalent:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/ef00268a7d4395d5285646425ef161fa/href\"\u003ehttps://medium.com/media/ef00268a7d4395d5285646425ef161fa/href\u003c/a\u003e\u003c/iframe\u003e\u003ch4\u003eThen, we need to properly configure a Tika Parser\u003c/h4\u003e\u003cp\u003eWe need one in order to do actually do any \u003ca href=\"https://tika.apache.org/1.24/parser.html\"\u003eparsing\u003c/a\u003e. Because this kind of configuration tends to be ugly, I have put it all inside its own object/class to keep it separate from the rest of the code:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/d06b778f674cc7ebfa6c0d5ac31584fb/href\"\u003ehttps://medium.com/media/d06b778f674cc7ebfa6c0d5ac31584fb/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eFinally, we have to create…\u003c/p\u003e\u003ch4\u003eThe code that provides the file to be OCRed.\u003c/h4\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/97fa286ad55672dc413e9eb32a7c5e78/href\"\u003ehttps://medium.com/media/97fa286ad55672dc413e9eb32a7c5e78/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eWe just turn the file we want to OCR into an InputStream and hand that off to the TikaOCRParser we specified above for parsing. Because using InputStreams and doing parsing are two IO processes that can (definitely) throw Exceptions, I have delegated the handling of the InputStream using Scala’s Using functionality, which will automatically wrap the whole operation into a Try while also making sure that the InputStream is closed when everything is done, \u003cem\u003eeven when exceptions are thrown\u003c/em\u003e. If the result is a Success, I convert it into a regular String, which can then be printed, or otherwise used at your convenience.\u003c/p\u003e\u003cp\u003e\u003cem\u003e(The example file is a \u003c/em\u003e\u003cem\u003ejpeg, but lots of different image formats, as well as \u003c/em\u003e\u003cem\u003ePDF, are supported. Some, like \u003c/em\u003e\u003cem\u003eJPEG2000, might require extra supporting software to be installed on the machine.)\u003c/em\u003e\u003c/p\u003e\u003cp\u003eSo, that’s it. Pretty easy, right? Check out the \u003ca href=\"https://tika.apache.org/\"\u003eApache Tika documentation\u003c/a\u003e to see what other great functionality is available. Tesseract OCR is a pretty tricky field in and off itself, so be sure to check out all the \u003ca href=\"https://tesseract-ocr.github.io/tessdoc/ImproveQuality\"\u003etweaks\u003c/a\u003e you may have to make for your particular dataset. If you want to see the full code for this example, you can \u003ca href=\"https://github.com/NRBPerdijk/tikascalaexample\"\u003echeck it out on GitHub\u003c/a\u003e. Last but not least, kudos to the Apache Software Foundation for their continuing work towards great Open Source solutions.\u003c/p\u003e\u003cp\u003eEdit: I also wrote a short intro using Apache Tika to do Named-Entity Recognition (NER): \u003ca href=\"https://medium.com/codestar-blog/tika-nerding-getting-started-using-named-entity-recognition-with-opennlp-on-the-jvm-scala-java-befc396d6dc5\"\u003eTika NERding: Getting started using Named-Entity Recognition with OpenNLP on the JVM\u003c/a\u003e\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/1024/1*P93TyWUqN0foFjmMaB0ehQ.jpeg\" /\u003e\u003c/figure\u003e\u003cimg src=\"https://medium.com/_/stat?event=post.clientViewed\u0026referrerSource=full_rss\u0026postId=f5d2bfe9b397\" width=\"1\" height=\"1\" alt=\"\"\u003e\u003chr\u003e\u003cp\u003e\u003ca href=\"https://medium.com/codestar-blog/tika-tika-getting-started-doing-ocr-with-apache-tika-andtesseract-from-the-jvm-f5d2bfe9b397\"\u003eTika Tika! Getting started doing OCR with Apache Tika andTesseract from the JVM\u003c/a\u003e was originally published in \u003ca href=\"https://medium.com/codestar-blog\"\u003eCodestar blog\u003c/a\u003e on Medium, where people are continuing the conversation by highlighting and responding to this story.\u003c/p\u003e"},{"id":"https://medium.com/p/65158c284034","title":"Upgrading to Angular 9: My experience","author":"Bjorn ‘Bjeaurn’","latestPublishedAt":"Fri, 14 Feb 2020 12:32:47 GMT","uniqueSlug":"https://medium.com/codestar-blog/upgrading-to-angular-9-my-experience-65158c284034?source=rss----ea5cff13e3c9---4","paragraphs":""},{"id":"https://medium.com/p/2aeff1303749","title":"Leibniz equality in TypeScript","author":"Werner de Groot","latestPublishedAt":"Tue, 25 Jun 2019 16:21:37 GMT","uniqueSlug":"https://medium.com/codestar-blog/leibniz-equality-in-typescript-2aeff1303749?source=rss----ea5cff13e3c9---4","paragraphs":"\u003cp\u003eIn this post I’ll explain how you can use Leibniz equality to safely type your higher-order components in React, although it can be used in many other places (outside the React ecosystem) too.\u003c/p\u003e\u003ch3\u003eIntroduction\u003c/h3\u003e\u003cp\u003eAt the client I’m currently working for we use a lot of different charts to visualize processes over time. We have line charts, Gantt charts, you name it. Each of those charts features buttons which allows users to zoom in or out.\u003c/p\u003e\u003cp\u003eI’d like to use a simplified version of one of those graphs to explain what Leibniz, a German mathematician who lived well over 300 years ago, has to do with TypeScript.\u003c/p\u003e\u003ch3\u003eMotivating example\u003c/h3\u003e\u003cp\u003eLet’s suppose our graph looks a bit like this:\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/494/1*iBVlr8lOKvIzbqA8-qvHoQ.gif\" /\u003e\u003c/figure\u003e\u003cp\u003eI use a component Graph which takes the following props:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/8fd6625d7338ffb2d8f27ee8923b427f/href\"\u003ehttps://medium.com/media/8fd6625d7338ffb2d8f27ee8923b427f/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eWhat do we need to show a graph? We need:\u003c/p\u003e\u003cul\u003e\u003cli\u003eactivities to show;\u003c/li\u003e\u003cli\u003edayStart and dayEnd, which specify the range of the time axis;\u003c/li\u003e\u003cli\u003eonZoomIn and onZoomOut to control the range of the time axis from inside the component.\u003c/li\u003e\u003c/ul\u003e\u003ch3\u003eZooming in and out\u003c/h3\u003e\u003cp\u003eIn this aside, I’d like to show you the function that handles zooming in or out. It’s not really relevant to the rest of the story (and you can skip this if you like) but it might come in handy if you wish to code along with this blog post.\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/5d62a026746da4ee205c6b5d1cfd0f52/href\"\u003ehttps://medium.com/media/5d62a026746da4ee205c6b5d1cfd0f52/href\u003c/a\u003e\u003c/iframe\u003e\u003ch3\u003eHigher-order component\u003c/h3\u003e\u003cp\u003eAlthough it is tempting to let this component manage its own dayStart and dayEnd (especially now that we can use hooks), it has two benefits to manage that state externally:\u003c/p\u003e\u003cul\u003e\u003cli\u003eI can easily expose the component to different states, which makes it easy to test;\u003c/li\u003e\u003cli\u003eI can change that state from the outside if I need to (for instance to ensure that all visible charts share the same time axis).\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eIf I would create a higher-order component (HOC) to manage that state for me, I would get the best of both worlds. I get an easy to use component which manages its own state if I wrap Graph in this HOC, but I get a lot of power if I choose not to.\u003c/p\u003e\u003cp\u003eFurthermore, I can apply this HOC to many other components which have a time axis and support some form of zooming in and out.\u003c/p\u003e\u003cp\u003eWhat should this HOC look like? What is the input? And what is the output?\u003c/p\u003e\u003cul\u003e\u003cli\u003eThe component that we pass to the HOC (the “inner component”) should have some props provided automatically by the component that the HOC produces (the “outer component”).\u003c/li\u003e\u003cli\u003eThe outer component should forward any other props to the inner component. Those are the only props that we need to provide to the outer component.\u003c/li\u003e\u003cli\u003eTypeScript should be able to infer all of this automatically.\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eThe HOC we will write will provide the following props to the inner component (which we’ll call Inner in what follows):\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/8b76ef6710a77582a8ae8b0555d101f8/href\"\u003ehttps://medium.com/media/8b76ef6710a77582a8ae8b0555d101f8/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eIt will produce a component (which we’ll call Outer from now on) that takes the following props¹:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/15ab60303123509b5c6b4e048ea753d3/href\"\u003ehttps://medium.com/media/15ab60303123509b5c6b4e048ea753d3/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eThis might be a bit intimidating. What this says is that we can determine the props to the outer component (OuterProps) from the props to the inner component (InnerProps) by removing all values that are shared with TimeAxisProps (dayStart, dayEnd, onZoomIn and onZoomOut to be precise)².\u003c/p\u003e\u003cp\u003eNow that we know what the HOC should do, we can focus on \u003cem\u003ehow\u003c/em\u003e it should do it:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/dc85cb534801d0ca89ae3c215069e433/href\"\u003ehttps://medium.com/media/dc85cb534801d0ca89ae3c215069e433/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eThat’s a big piece of code! We can see how to handle zooming in and zooming out. We can also see how we can combine both the OuterProps and the TimeAxisProps to render the Inner-component. You might also have noticed that InnerProps extends TimeAxisProps. Constraining our generic type parameter it this way ensures that we can only apply this HOC on components that have at least the props dayStart, dayEnd, onZoomIn and onZoomOut that we’d like to provide to it. If that component doesn’t have these four props, why even apply WithTimeAxis, right?\u003c/p\u003e\u003ch3\u003eTrouble\u003c/h3\u003e\u003cp\u003eThere is, however, a tiny problem… It doesn’t compile!\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/833/1*6mEccGy9WNOJ5zU_8a35DA.png\" /\u003e\u003c/figure\u003e\u003cp\u003eBut why doesn’t it? TypeScript has trouble figuring out that the combination of OuterProps\u003cInnerProps\u003e and TimeAxisProps is equal to InnerProps. Although this is true for the case with GraphProps, it isn’t true in general.\u003c/p\u003e\u003cp\u003eTo give you an example in which this isn’t true, let’s suppose that we try to apply the HOC to a component CounterExample with the following props:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/c5c113258aeee9aebb16e320957a1bf2/href\"\u003ehttps://medium.com/media/c5c113258aeee9aebb16e320957a1bf2/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003ewhere I’d like to point your attention to the dayStart: 0.\u003c/p\u003e\u003cp\u003eI admit, this is a bit farfetched, but it does illustrate the point. We shouldn’t apply WithTimeAxis to CounterExample as the HOC might provide a dayStart that is not equal to zero. In fact, changing the zoom level multiple times ensures that dayStart will eventually be non-zero, even if it was equal to zero initially.\u003c/p\u003e\u003cp\u003eThe TypeScript isn’t complaining about this when we do try to apply WithTimeAxis to CounterExample, as CounterExampleProps nicely extends TimeAxisProps as I required. CounterExampleProps is more specific than TimeAxisProps (because the type 0 is more specific than number) but that is allowed for subtypes. Instead, the compiler has noticed this possibility even before we did, and that is why our HOC doesn’t compile!\u003c/p\u003e\u003cp\u003eThe root of our issues is with the InnerProps extends TimeAxisProps constraint. What we try to express is that all properties of TimeAxisProps are shared with InnerProps without allowing for subtypes. Unfortunately extends is currently the best we can do. In fact, it’s the only type of constraint we can express on our generic type parameters in TypeScript.\u003c/p\u003e\u003ch3\u003eHope on the horizon\u003c/h3\u003e\u003cp\u003eWe can solve this problem by pushing the burden of proof up a level. We ask the user for a function convert that is able to convert the combination of OuterProps\u003cInnerProps\u003e and TimeAxisProps (which can be expressed in TypeScript as OuterProps\u003cInnerProps\u003e \u0026 TimeAxisProps) to InnerProps. If the user can do that, we can call Inner with the right props:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/d33910d05ac4789a904c27f227daebd3/href\"\u003ehttps://medium.com/media/d33910d05ac4789a904c27f227daebd3/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eWhat does this conversion function look like in the example of GraphProps? It’s not very difficult at all! In the example of GraphProps we can see that:\u003c/p\u003e\u003cul\u003e\u003cli\u003eThe parameter type is Omit\u003cGraphProps, keyof TimeAxisProps\u003e \u0026 TimeAxisProps, which the compiler knows is just a fancy way to write GraphProps;\u003c/li\u003e\u003cli\u003eThe return type is GraphProps.\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eWhat it boils down to is that we are asked to provide a function that makes this very trivial conversion:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/73915cfc6b5c30035941b28cb50122df/href\"\u003ehttps://medium.com/media/73915cfc6b5c30035941b28cb50122df/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eWe can even use the identity function if we’d like:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/93c93d1d239d09c7b05059fc51ec102f/href\"\u003ehttps://medium.com/media/93c93d1d239d09c7b05059fc51ec102f/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eFor CounterExample we are asked to provide a conversion function that takes an object with dayStart: number to dayStart: 0. We could simply provide a conversion function that maps every dayStart (whether it is 1, 2, 99 or something else) to 0 but that would clearly not be in the spirit of WithTimeAxis. If I would instead try to use something identity in this case, TypeScript would complain.\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/927/1*g_5XkBVLaWIkvs7W_XHv8g.png\" /\u003e\u003c/figure\u003e\u003cp\u003ewhich is a rather nice way of hearing about this compilation error I think. (Especially the note at the bottom that says “Type ‘number’ is not assignable to type ‘0’” points you in the right direction immediately.)\u003c/p\u003e\u003cp\u003eAs we’ve concluded earlier, OuterProps\u003cCounterExampleProps\u003e \u0026 TimeAxisProps is not equal to CounterExampleProps, and the compiler can tell you that. If you cannot use something like identity or trivial, that means you probably shouldn’t use this HOC.\u003c/p\u003e\u003cp\u003eThis is really the crucial step of this blog, so take some time to digest this. We’ve pushed the burden of proving that OuterProps\u003cInnerProps\u003e \u0026 TimeAxisProps to InnerProps from Outer (where that’s hard or even impossible to do) to the consumers of this component (where that is easy or even trivial to do). We can’t prove this in general, but we can do it case-by-case every time we apply WithTimeAxis.\u003c/p\u003e\u003ch3\u003eLeibnizian equality\u003c/h3\u003e\u003cp\u003eA famous mathematician called Leibniz described a form of equality in which two things (\u003cem\u003ea\u003c/em\u003e and \u003cem\u003eb\u003c/em\u003e) can be considered to be equal if every predicate that holds for \u003cem\u003ea\u003c/em\u003e also holds for \u003cem\u003eb\u003c/em\u003e (and vice versa).\u003c/p\u003e\u003cp\u003eIn TypeScript, we can express this as\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/0003891a80c301954c22135f2ae89276/href\"\u003ehttps://medium.com/media/0003891a80c301954c22135f2ae89276/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eTwo types A and B are equal if every function that maps A to B is also a mapping from B to A. You can see that it’s only possible to construct such a function if A is equal to B. In that case Leibniz\u003cA, B\u003e collapses to type Leibniz\u003cA, A\u003e = (a: A) =\u003e A (in other words, it is our identity function).\u003c/p\u003e\u003cp\u003eLeibniz is a formalization of the technique we used in the previous section with a HOC:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/b8e604fad0b336ff9bd6690a6144f3d7/href\"\u003ehttps://medium.com/media/b8e604fad0b336ff9bd6690a6144f3d7/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eBy requiring a Leibniz\u003cOuterProps\u003cInnerProps\u003e \u0026 TimeAxisProps, InnerProps\u003e this function expresses that it can only do its job if OuterProps\u003cInnerProps\u003e \u0026 TimeAxisProps and InnerProps are equal.\u003c/p\u003e\u003cp\u003eBecause Leibniz\u003c...\u003e serves as our type constraint, we can even drop the extends from InnerProps extends TimeAxisProps. This is no real loss as that extends wasn’t doing a very good job anyways.\u003c/p\u003e\u003ch3\u003eConclusion\u003c/h3\u003e\u003cp\u003eSometimes we need something stricter than extends, or we’d like to constrict the type parameter in the other direction (number extends T instead of T extends number). In those cases Leibniz\u003c...\u003e can be your friend. In my experience using a Leibniz\u003c...\u003e improves the readability of your type constraints when those constraints get more complicated (or include three or more different types).\u003c/p\u003e\u003ch3\u003eAfterthoughts\u003c/h3\u003e\u003cp\u003eThis technique was first used in \u003ca href=\"http://portal.acm.org/citation.cfm?id=583852.581494\"\u003eTyping Dynamic Typing (Baars and Swierstra, ICFP 2002)\u003c/a\u003e but I haven’t seen it used in TypeScript anywhere yet. I’m really interested to hear how you would tackle the problem addressed in this post without using a Leibniz\u003c...\u003e or if you’ve seen it used in similar (or different!) places. Let me know!\u003c/p\u003e\u003cp\u003e[1]: Omit will be introduced in TypeScript 3.5. In the meantime, you can define it yourself as type Omit\u003cO, K extends keyof O\u003e = Pick\u003cO, Exclude\u003ckeyof O, K\u003e\u003e .\u003c/p\u003e\u003cp\u003e[2]: We’ve defined OuterProps in terms of InnerProps. Like in mathematics, where you can express \u003cem\u003ey\u003c/em\u003e in terms of \u003cem\u003ex\u003c/em\u003e (\u003cem\u003ey\u003c/em\u003e = 2\u003cem\u003ex\u003c/em\u003e) or \u003cem\u003ex\u003c/em\u003e in terms of \u003cem\u003ey\u003c/em\u003e (\u003cem\u003ex\u003c/em\u003e = \u003cem\u003ey\u003c/em\u003e / 2), TypeScript allows me to reverse this relationship. We get\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/6b167f9d1d20ec94c10cea7fd2c316c6/href\"\u003ehttps://medium.com/media/6b167f9d1d20ec94c10cea7fd2c316c6/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eNo need for complicated tricks like Omit\u003c...\u003e. Unfortunately, this doesn’t work. Because we start out with an Inner-component, from which we generate an Outer-component, we should start out with an InnerProps, from which we derive the OuterProps. If we would reverse this relationship by writing\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/40fbe7040d4bd177462b93777724ce0a/href\"\u003ehttps://medium.com/media/40fbe7040d4bd177462b93777724ce0a/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003ewe’d lose the ability for TypeScript to correctly infer the right types:\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/930/1*JmOikDAspLJuHPY07W1-Lw.png\" /\u003e\u003c/figure\u003e\u003cp\u003eIn our example, the compiler would infer OuterProps to be equal to GraphProps, which includes dayStart, dayEnd, onZoomIn and onZoomOut so when you try to use the resulting component you are still asked to provide those props (even though they will by overwritten by the ones the HOC provides).\u003c/p\u003e\u003cp\u003eIf you don’t mind helping the compiler a hand by providing the type yourself (instead of letting TypeScript infer it) then this is a very nice way of writing HOC’s and you needn’t read the rest of the blog.\u003c/p\u003e\u003cimg src=\"https://medium.com/_/stat?event=post.clientViewed\u0026referrerSource=full_rss\u0026postId=2aeff1303749\" width=\"1\" height=\"1\" alt=\"\"\u003e\u003chr\u003e\u003cp\u003e\u003ca href=\"https://medium.com/codestar-blog/leibniz-equality-in-typescript-2aeff1303749\"\u003eLeibniz equality in TypeScript\u003c/a\u003e was originally published in \u003ca href=\"https://medium.com/codestar-blog\"\u003eCodestar blog\u003c/a\u003e on Medium, where people are continuing the conversation by highlighting and responding to this story.\u003c/p\u003e"},{"id":"https://medium.com/p/6a3f4b167852","title":"Event sourcing with Akka Persistence","author":"Nick ten Veen","latestPublishedAt":"Fri, 07 Jun 2019 12:40:24 GMT","uniqueSlug":"https://medium.com/codestar-blog/event-sourcing-with-akka-persistence-6a3f4b167852?source=rss----ea5cff13e3c9---4","paragraphs":"\u003ch4\u003eAsynchronous pains\u003c/h4\u003e\u003cp\u003eIn one of our projects at the Port of Rotterdam we do a lot of stream processing where we require intermediate state. We are using Event Sourcing with \u003ca href=\"https://doc.akka.io/docs/akka/current/typed/persistence.html\"\u003eAkka Persistence\u003c/a\u003e. It allows us to create robust stateful streaming applications that can maintain state between application restarts. We were struggling a bit writing our command handlers since we do a bunch of asynchronous operations. Akka Persistence does not allow you to handle command asynchronously which means you need to deal with this yourself. Let us explore the problem in a simplified event sourcing application.\u003c/p\u003e\u003ch4\u003eEvent Sourcing\u003c/h4\u003e\u003cp\u003eLet us create a simple implementation of an event sourcing system. A simple calculator that can add and subtract values. First we define our state, which is simply an integer value:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/5d07332ecc9f80747f4ccc337a8273ac/href\"\u003ehttps://medium.com/media/5d07332ecc9f80747f4ccc337a8273ac/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eThe state can only be modified by firing events. Let us create two possible operations, adding and subtracting from the state:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/62541bf29f1b3892b120aff8034bd4cd/href\"\u003ehttps://medium.com/media/62541bf29f1b3892b120aff8034bd4cd/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eNow that we have a definition for our state and possible events, we can write a handler that will process these events:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/f977354dda7e13ecde4eab9931c297fb/href\"\u003ehttps://medium.com/media/f977354dda7e13ecde4eab9931c297fb/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eWe can test the event handler to verify that the events are processed correctly:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/25740c4cfde538c6c2e06eba4ee7d9be/href\"\u003ehttps://medium.com/media/25740c4cfde538c6c2e06eba4ee7d9be/href\u003c/a\u003e\u003c/iframe\u003e\u003ch4\u003eCommands\u003c/h4\u003e\u003cp\u003eIn event sourcing, events are immutable facts that happened. These events should be handled deterministically without any side effect. However, sometimes we need to perform side effects. For example when we need to query a database to check if an operation is allowed. We can use the command abstraction for this purpose. A command is a request to do something. Requests can be accepted or denied, or even transformed. They are also allowed to perform side effects. We can define commands for addition and subtraction:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/3a0d54d783a9e5785f1147b8029cae28/href\"\u003ehttps://medium.com/media/3a0d54d783a9e5785f1147b8029cae28/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eA command handler can process these commands and decide to fire zero or more events:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/1ad75d70e2dab02037a5928bb1d9b459/href\"\u003ehttps://medium.com/media/1ad75d70e2dab02037a5928bb1d9b459/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eWe can test the command handler to verify it will fire events accordingly:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/ab4957892a4c78e046c24a2df851293c/href\"\u003ehttps://medium.com/media/ab4957892a4c78e046c24a2df851293c/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eThe command handler and event handler can be folded together to calculate the state for a given list of commands:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/e2ec3d55ea53da5bc06bc02461c379ec/href\"\u003ehttps://medium.com/media/e2ec3d55ea53da5bc06bc02461c379ec/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eThis all works fine, but if we want to recover the state during a crash or restart, we also need to store the events that we persist. We need a function that accumulates the events while calculating the state:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/0b2e607e74d6a86c575971d4c57df104/href\"\u003ehttps://medium.com/media/0b2e607e74d6a86c575971d4c57df104/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eWe can keep the accumulated state in memory during processing and at the same time persist the generated events somewhere. On restarts we can replay these events with the eventHandler to restore our state.\u003c/p\u003e\u003ch4\u003eAkka Persistence\u003c/h4\u003e\u003cp\u003eThis pattern is encoded in Akka Persistence and allows us to have actors with state that can be recovered after crashes and restarts. The command handler is a little bit different. Instead of returning a list of events that happened, you can specify an Effect. These effects are simply an encoding of possible actions a persistent actor can do after receiving a command:\u003c/p\u003e\u003cul\u003e\u003cli\u003ePersist an event\u003c/li\u003e\u003cli\u003eStop the actor\u003c/li\u003e\u003cli\u003eStash the command\u003c/li\u003e\u003cli\u003eDo nothing\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eThese effects can be composed together to (for example) persist multiple events. In our example we can write a simple command handler:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/f6718504ef695cb7e2ce9e4380fba243/href\"\u003ehttps://medium.com/media/f6718504ef695cb7e2ce9e4380fba243/href\u003c/a\u003e\u003c/iframe\u003e\u003ch4\u003eAsynchronous command handling\u003c/h4\u003e\u003cp\u003eOne issue about the commandHandler is that it is synchronous. \u003ca href=\"https://github.com/akka/akka/issues/25650\"\u003eThere are currently no plans for aynchronous command handlers in akka\u003c/a\u003e persistence.\u003cbr\u003eIf you want to do some asynchronous processing before deciding to persist an event, you need to introduce extra commands. For example, lets say we want to have a check if a specific addition or subtraction is allowed before we emit an event. We really need to do this asynchronously for some reason, so lets create a definition of our permission check:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/c1b62ffb83ccde773ba063938dbb57a8/href\"\u003ehttps://medium.com/media/c1b62ffb83ccde773ba063938dbb57a8/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eTo be able to add this to our command handler, we need an extra command that is fired after validation. We also group our previous commands into a subtype so it can be a parameter of our new command:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/92c2de50dc026f7ea003117690b031a7/href\"\u003ehttps://medium.com/media/92c2de50dc026f7ea003117690b031a7/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eWith this definition we can rewrite our event handler to take this check into account:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/d76cbff50bb56201bf8a9976137b8d60/href\"\u003ehttps://medium.com/media/d76cbff50bb56201bf8a9976137b8d60/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eThis does work, however we lost a property that might be important to us. \u003cbr\u003eThe order in which the algebraic commands are processed is lost due to the asynchronous boundary. Say our check is really slow for some specific elements. Other elements that arrived later might have been processed already and arrive out of order:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/eb9dc629dd33e621c308219abece7984/href\"\u003ehttps://medium.com/media/eb9dc629dd33e621c308219abece7984/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eIf we would process the following commands in order, the outcome might have a different order:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/d8fcebd84408bd53f03f8673ca48c98c/href\"\u003ehttps://medium.com/media/d8fcebd84408bd53f03f8673ca48c98c/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eYou could fix this by storing inflight messages in some (non-persistent) state, \u003cbr\u003eor by using the ask pattern and waiting for replies before sending each command. Currently (as far as I am aware) you are unable to store volatile state in a persistent actor. This means that if you want to store messages that are in flight, you need to use persistence for this. We can extend the state to store this along with a persistent event to signal inflight messages:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/137c495e4617b589ec586093539a0d8a/href\"\u003ehttps://medium.com/media/137c495e4617b589ec586093539a0d8a/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003ePreviously we only fired a command if an operation is allowed, but since we also need to unstash if an operation is not allowed, we always need to fire a command for a result. So we need to modify our OperationAllowed command:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/77909a2f33d897027ea29e5f37aa5589/href\"\u003ehttps://medium.com/media/77909a2f33d897027ea29e5f37aa5589/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eOur event handler is now responsible for handling this extra event and cleaning up after a command has been successfully processed:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/7939bcca43e31638fea8c1f3601a5b7c/href\"\u003ehttps://medium.com/media/7939bcca43e31638fea8c1f3601a5b7c/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eFinally we need to rewrite our command handler to stash incoming commands as long as there is still a message in flight.\u003cbr\u003eAfter a command is successfully processed, we need to unstash to continue processing potentially stashed commands:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/0a0f3a59d6fd65959ce18f46fe0d0e43/href\"\u003ehttps://medium.com/media/0a0f3a59d6fd65959ce18f46fe0d0e43/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eAfter all this there are still a few concerns with this implementation. \u003cbr\u003eWhat if checkPermission fails? We would need to extend the example to deal with failing futures as well. Moreover, we persist the state of inflight messages so it survives restarts. However after a restart this message is not in flight and we might wait for eternity for it to resolve. This example illustrates that you can handle commands asynchronously, but in order to ensure messages are processed in the correct order, we needed to add error-prone synchronisation code.\u003c/p\u003e\u003ch4\u003eConclusion\u003c/h4\u003e\u003cp\u003eYou can do asynchronous command handling with Akka Persistence. It does however require you to write some error-prone boilerplate code. Can we do better? Are persistent actors the correct approach for this problem? Maybe we can express the problem in a different paradigm where we still have the nice property of state recovery, while also allowing us to handle commands asynchronously. Maybe we could use stream processing to have a cleaner solution to our problem. But that is for another blog post.\u003c/p\u003e\u003cimg src=\"https://medium.com/_/stat?event=post.clientViewed\u0026referrerSource=full_rss\u0026postId=6a3f4b167852\" width=\"1\" height=\"1\" alt=\"\"\u003e\u003chr\u003e\u003cp\u003e\u003ca href=\"https://medium.com/codestar-blog/event-sourcing-with-akka-persistence-6a3f4b167852\"\u003eEvent sourcing with Akka Persistence\u003c/a\u003e was originally published in \u003ca href=\"https://medium.com/codestar-blog\"\u003eCodestar blog\u003c/a\u003e on Medium, where people are continuing the conversation by highlighting and responding to this story.\u003c/p\u003e"},{"id":"https://medium.com/p/9790212aa211","title":"How we automated our Angular updates","author":"Bjorn ‘Bjeaurn’","latestPublishedAt":"Tue, 21 May 2019 13:37:13 GMT","uniqueSlug":"https://medium.com/codestar-blog/how-we-automated-our-angular-updates-9790212aa211?source=rss----ea5cff13e3c9---4","paragraphs":""},{"id":"https://medium.com/p/f81434f6f8d7","title":"Apollo Client in Practice","author":"mdworld","latestPublishedAt":"Thu, 02 May 2019 18:24:29 GMT","uniqueSlug":"https://medium.com/codestar-blog/apollo-client-in-practice-f81434f6f8d7?source=rss----ea5cff13e3c9---4","paragraphs":"\u003cp\u003eSome time ago I joined a team that is working on a search application. The application takes search terms and displays the results in a table with potentially dozens of columns and hundreds of rows, even before pagination. It is implemented in React and uses \u003ca href=\"https://www.apollographql.com/\"\u003eApollo\u003c/a\u003e for GraphQL calls. I was surprised to find it noticeably slow when a lot of search results were retrieved. React is well-known for leveraging virtual DOM to optimize performance and GraphQL should even be able to add caching to further optimize performance on the side of network requests.\u003c/p\u003e\u003cp\u003eLooking into the performance tab of Chrome dev tools lead me to believe the performance problems were caused by computations in the bottom components (e.g. formatting in cells). Because there are so many and they are re-rendered quite often, this approach is quite intensive on resources.\u003c/p\u003e\u003cp\u003eBesides that, the application had obvious state synchronization problems. When moving between views it was not maintaining the same state of selected rows. Even though Redux was used to store application state and communicate it between components, it was not used consistently. There were still plenty of React class components that stored some parts of the state locally.\u003c/p\u003e\u003cp\u003eTo summarize, there were two issues that needed to be solved:\u003c/p\u003e\u003col\u003e\u003cli\u003ePoor performance due to excessive re-rendering\u003c/li\u003e\u003cli\u003eLoss of application state when navigating views due to decentralized state stores\u003c/li\u003e\u003c/ol\u003e\u003cp\u003eSince both issues were caused by (a lack of) architecture, we redesigned the structure of the application. The original implementation used:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://www.apollographql.com\"\u003eApollo Client\u003c/a\u003e as a GraphQL client\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://github.com/axios/axios\"\u003eAxios\u003c/a\u003e as an HTTP client for REST endpoints\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://redux.js.org\"\u003eRedux\u003c/a\u003e and \u003ca href=\"https://reactjs.org/docs/hooks-reference.html#usestate\"\u003eReact local state\u003c/a\u003e to manage the state between components\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eIt used Apollo, but by \u003ca href=\"https://www.apollographql.com/docs/react/essentials/queries#manual-query\"\u003emanually firing\u003c/a\u003e client.query() and after processing the response, it stored the result in the Redux store.\u003c/p\u003e\u003ch3\u003eFixing application state with Apollo Local State\u003c/h3\u003e\u003cp\u003eWhen restructuring the application, Apollo Client was updated to 2.5. This version has a built-in \u003ca href=\"https://www.apollographql.com/docs/react/essentials/local-state\"\u003elocal state manager\u003c/a\u003e (formerly \u003cem\u003eapollo-link-state\u003c/em\u003e) and it supports REST calls with the \u003ca href=\"https://www.apollographql.com/docs/link/links/rest\"\u003eapollo-link-rest\u003c/a\u003e plugin. The \u003ca href=\"https://github.com/apollographql/apollo-client/tree/master/packages/apollo-boost\"\u003eapollo-boost\u003c/a\u003e package contains the client and several useful plugins. Adopting these means that both Redux and Axios can be removed and Apollo will be used as a single source of truth. If there is a single store for the data, there is no need for synchronization and with that one of the issues is solved.\u003c/p\u003e\u003cp\u003eThe way we used Apollo Client was also updated, to create a better separation of UI and data. Instead of using client.query() directly in the component lifecycle methods, components are split into a presentational component and enhanced with the \u003ca href=\"https://www.apollographql.com/docs/react/api/react-apollo#graphql\"\u003egraphql()\u003c/a\u003e HOC to add data from remote (i.e. GraphQL back-end) or local fields. Both utilize the Apollo cache, which fulfills multiple functions, one of them an application local state store.\u003c/p\u003e\u003cp\u003eExample of wrapping a component in a Query HOC:\u003c/p\u003e\u003cpre\u003econst Books = ({ data: { books } }) =\u003e (\u003cbr\u003e \u003cul\u003e\u003cbr\u003e {books.map(book =\u003e \u003cli\u003e{book.title}\u003c/li\u003e}\u003cbr\u003e \u003c/ul\u003e);\u003c/pre\u003e\u003cpre\u003eexport graphql({ query: gql`\u003cbr\u003e query($author: String!) {\u003cbr\u003e books(author: $author) {\u003cbr\u003e title\u003cbr\u003e }\u003cbr\u003e }`, \u003cbr\u003e variables: { author: \"Mickiewicz\" })(Books);\u003c/pre\u003e\u003cp\u003eApollo reactively updates when using Query as a container, basically like the connect HOC in Redux. When the variables prop on the Query component is updated, it will automatically re-query. It uses the cache if possible and falls back to a network call if needed, although this behavior can be configured.\u003c/p\u003e\u003ch3\u003eImproving performance with Local Field Resolvers\u003c/h3\u003e\u003cp\u003eHaving a single source of truth fixes the state synchronization problem. It also paves the way for improving the performance. In general, when a lot of data enters the application, it is a good idea to format it once and cascade the formatted data down to the components and it’s descendants with as little transformations to the data itself. This reduces the amount of computations in the lower components, which solves our other issue.\u003c/p\u003e\u003cp\u003eWhen using Redux, a common way to transform data in the store is using \u003ca href=\"https://github.com/reduxjs/reselect\"\u003eReselect\u003c/a\u003e, which computes derived data from the Redux store with selectors. For Apollo this is done by:\u003c/p\u003e\u003cul\u003e\u003cli\u003ewrapping the table in a Query that queries a local prop rows @client, using the \u003ca href=\"https://www.apollographql.com/docs/react/essentials/local-state\"\u003e@client\u003c/a\u003e directive\u003c/li\u003e\u003cli\u003emaking client side resolvers for rows that queries GraphQL endpoint\u003c/li\u003e\u003cli\u003emapping the data in a resolver from a raw format to a format ready for the table components, e.g.:\u003c/li\u003e\u003c/ul\u003e\u003cp\u003efrom a data object\u003c/p\u003e\u003cpre\u003e{ \u003cbr\u003e author: \"Mickiewicz\", \u003cbr\u003e publications: [ \u003cbr\u003e { \u003cbr\u003e title: \"Pan Tadeusz\",\u003cbr\u003e date: -4291747200 \u003cbr\u003e } \u003cbr\u003e ] \u003cbr\u003e}\u003c/pre\u003e\u003cp\u003eto an array rows of cells\u003c/p\u003e\u003cpre\u003e[\u003cbr\u003e [ \"Mickiewicz\", \"Pan Tadeusz\", \"January 1834\" ]\u003cbr\u003e]\u003c/pre\u003e\u003ch3\u003eNext steps\u003c/h3\u003e\u003cp\u003eApollo is excellent for merging data from multiple sources (in this case GraphQL, REST, local state and cache) and functions as a “single source of truth” which should solve the state synchronization problems. The local fields that Apollo uses in its local state manager can derive data, moving expensive operations from component render functions to resolvers in its application level cache. Although the issues mentioned in the introduction are now dealt with, we did encounter plenty of other issues I may dive into later. However, these are some things that you might want to take into account when working with Apollo Client:\u003c/p\u003e\u003cp\u003eOutside of restructuring the application, we improved performance with \u003ca href=\"https://github.com/bvaughn/react-virtualized\"\u003ereact-virtualized\u003c/a\u003e which speeds up rendering large tables. Apollo also offers GraphQL pagination. We did not use that, as we have to do our pagination on the client side to keep the sorting feature of react-virtualized in tact.\u003c/p\u003e\u003cp\u003eApollo Client offers support for TypeScript, it is even possible to generate queries and typed React components from GraphQL schemas with \u003ca href=\"https://graphql-code-generator.com/\"\u003e@graphql-codegen/cli\u003c/a\u003e.\u003c/p\u003e\u003cp\u003eAlso definitely use the \u003ca href=\"https://jimkyndemeyer.github.io/js-graphql-intellij-plugin/\"\u003eJS GraphQL IntelliJ Plugin\u003c/a\u003e because it will not only auto complete queries, but it will help you think about (client side) schema’s.\u003c/p\u003e\u003cp\u003eWhen the Query component mounts, it creates an observable that subscribes to the query in the query prop. This encourages reactive behavior like RxJS (which can also be used as a \u003ca href=\"https://github.com/mdvanes/realtime-planner\"\u003estate store\u003c/a\u003e). However, it seems that Apollo offers much less fine-grained control over the observables than what RxJS provides. And considering observables, Apollo Client effortlessly \u003ca href=\"https://www.apollographql.com/docs/link/links/ws\"\u003escales to web sockets\u003c/a\u003e!\u003c/p\u003e\u003cp\u003eAre you looking for inspiration on how Apollo client can be applied? I can recommend \u003ca href=\"https://www.youtube.com/watch?v=g6Mhm9W76jY\"\u003ethis talk by Uri Goldshtein\u003c/a\u003e and this \u003ca href=\"https://www.youtube.com/watch?v=2RvRcnD8wHY\"\u003eintroduction to Apollo state management by Sara Vieira\u003c/a\u003e.\u003c/p\u003e\u003cimg src=\"https://medium.com/_/stat?event=post.clientViewed\u0026referrerSource=full_rss\u0026postId=f81434f6f8d7\" width=\"1\" height=\"1\" alt=\"\"\u003e\u003chr\u003e\u003cp\u003e\u003ca href=\"https://medium.com/codestar-blog/apollo-client-in-practice-f81434f6f8d7\"\u003eApollo Client in Practice\u003c/a\u003e was originally published in \u003ca href=\"https://medium.com/codestar-blog\"\u003eCodestar blog\u003c/a\u003e on Medium, where people are continuing the conversation by highlighting and responding to this story.\u003c/p\u003e"},{"id":"https://medium.com/p/b561e8cfbcfa","title":"Sharing is Caring! Domain objects in BOTH Scala and R with GraalVM Polyglot bindings.","author":"Nathan Perdijk","latestPublishedAt":"Wed, 01 May 2019 07:53:54 GMT","uniqueSlug":"https://medium.com/codestar-blog/sharing-is-caring-domain-objects-in-both-scala-and-r-with-graalvm-polyglot-bindings-b561e8cfbcfa?source=rss----ea5cff13e3c9---4","paragraphs":"\u003cp\u003e\u003cstrong\u003eIn any domain that goes beyond a sample project, it becomes almost inevitable that you want to use objects that accurately represent that domain. GraalVM does an adequate job of converting datastructures from R to JVM languages and back by using sensible defaults, but what do you do when the sensible defaults are not sufficient? Given that GraalVM can perform translation between its multitude of supported languages, is it possible to define a “Domain” that can be accessed by all?\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003eThis is, of course, a rhetorical question and the answer is “Yes”.\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/proxy/1*LPCG2xlLiUdqcYJulzxvmw.png\" /\u003e\u003c/figure\u003e\u003cp\u003eIn this article I’ll demonstrate how to share domain objects between JVM languages and guest languages on the GraalVM platform. I’m using Scala domain objects (because Scala is awesome), but you could do the same with, for instance, Java or Kotlin.\u003c/p\u003e\u003cp\u003e(If you’re new to GraalVM Polyglot abilities, consider also reading my previous article on the subject: \u003ca href=\"https://medium.com/codestar-blog/in-search-of-the-holy-graalvm-putting-the-r-in-scala-or-java-or-b057494f77\"\u003eusing GraalVM to execute R files from Scala\u003c/a\u003e.)\u003c/p\u003e\u003ch3\u003eThe Problem\u003c/h3\u003e\u003cp\u003eTo demonstrate the problem we are trying to solve, we first need a pretend domain. Let’s do something with Weather Forecasts, because people always talk about the weather!\u003c/p\u003e\u003cp\u003eCreating weather forecasts is the kind of terribly complicated modelling business that could be built in R, but luckily we don’t actually \u003cem\u003eneed \u003c/em\u003ea\u003cem\u003e \u003c/em\u003eworking model for this article. So let’s just pretend we already have this awesome R functionality that creates weather forecasts, cleanly abstracted away in a separate file called fun_MagicHappensHere.R:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/e5c3b681f21a734cde53718097b48260/href\"\u003ehttps://medium.com/media/e5c3b681f21a734cde53718097b48260/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eWhen brought into scope with R’ssource the above file will yield a magicHappensHere function that can be called and returns a data.frame with some weather forecast information. We can then return the result to Scala by simply making it the return of our R function:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/2c7e7eec84737fdd738af52569b5b619/href\"\u003ehttps://medium.com/media/2c7e7eec84737fdd738af52569b5b619/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eWow, that doesn’t look too bad! This won’t get many complaints from the Data Scientist, I reckon.\u003c/p\u003e\u003cblockquote\u003eSo, what’s wrong with this? What’s the problem?\u003c/blockquote\u003e\u003cp\u003eI’m glad you asked, \u003ca href=\"https://www.dictionary.com/browse/interlocutor\"\u003einterlocutor\u003c/a\u003e! Let’s take a look on the Scala/JVM side of this equation, to see what the Data Engineer has to deal with:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/ec12de6f2b6c4cac4c2a8bdd2f083906/href\"\u003ehttps://medium.com/media/ec12de6f2b6c4cac4c2a8bdd2f083906/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eWhoa… creating the Graal Context and Source is trivial, but look at the nasty type signature on that call to R! Let’s pick it apart for a bit:\u003c/p\u003e\u003cul\u003e\u003cli\u003eA Map that contains Lists of each data.frame row keyed by its name… That makes sense, well done Graal! It’s just too bad it’s Stringly typed, rather than actual methods on an actual class, so any typo will mess us up at runtime.\u003c/li\u003e\u003cli\u003eUnknown content type of the Lists?… That’s unfortunate, we know that some rows should only contain String, while others contain Int but this information is lost in conversion… We have to do a bunch of casting!\u003c/li\u003e\u003cli\u003eThe returned Collections are Java? That’s just sad! The polyglot representation of collections doesn’t transfer to Scala, but Scala Map and List are much more powerful than their Java equivalent, so we’ll have to convert the Java equivalents!\u003c/li\u003e\u003cli\u003eEvery element of each List doesn’t actually belong to the rest of the List, but instead should be combined with each corresponding position in every other List to actually make a WeatherReport… (The first entry of “humidities”, should be paired with the first entry of “temperatures” etc.)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eLet’s see what this means when we try to use the output of this function:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/c0596dc510b7e5f8a31583fe7a18ee86/href\"\u003ehttps://medium.com/media/c0596dc510b7e5f8a31583fe7a18ee86/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eI don’t know about you, but I’d feel quite uncomfortable at the thought of maintaining the code above. It’s verbose, error prone, brittle, annoying and it fails at the wrong spot if any mistakes are introduced (namely at the place of conversion, rather than the place of programming error). I wish the R function would just return a Set of WeatherForecast!\u003c/p\u003e\u003cp\u003eWhoops, hold on… Wait a minute…\u003c/p\u003e\u003cp\u003eWhy don’t we just \u003cstrong\u003e\u003cem\u003emake it do that?\u003c/em\u003e\u003c/strong\u003e\u003c/p\u003e\u003ch3\u003e\u003cstrong\u003eThe Solution: Bindings\u003c/strong\u003e\u003c/h3\u003e\u003cp\u003eGraalVM comes with an option that makes it possible to explicitly share instances of code across the language divide. It makes it possible to add symbols to bindings that are accessible to other languages. The Graal Context has two functions that can be used to do this in a very similar way:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Context.html#getPolyglotBindings--\"\u003egetPolyglotBindings()\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Context.html#getBindings-java.lang.String-\"\u003egetBindings(“nameOfLanguage\")\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eIn this article I will be using getBindings, because it doesn’t require an explicit import on the side of the using language and it allows you to limit which languages you are exposing each binding to. Using getPolyglotBindings() is almost identical from a coding perspective though, so pick the one you like best.\u003c/p\u003e\u003ch4\u003eUsing Domain objects on both sides of the language divide\u003c/h4\u003e\u003cp\u003eThis is what our Domain object looks like:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/49e56d665f505d7658635c3908f18293/href\"\u003ehttps://medium.com/media/49e56d665f505d7658635c3908f18293/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eDomain is basically a factory that can be used to spawn new instances of all the domain classes that we want to share. The classDomain itself is immutable! (As it happens, the spawned instances are too.)\u003c/p\u003e\u003cblockquote\u003e\u003cstrong\u003eWARNING\u003c/strong\u003e: You probably don’t want to put a mutable object into bindings. If you do, this object can be mutated \u003cstrong\u003efrom any language that can reach it\u003c/strong\u003e. Just as you don’t want multiple threads to tangle with the same mutable object, you don’t want multiple languages to access the same mutable state! (Really! Imagine having to debug race conditions across language boundaries...)\u003c/blockquote\u003e\u003cp\u003eAny instance of the Domain class provides methods to spawn new instances of the following domain case classes:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/7e5132cb958ccf0a06cd9e1c9f11781c/href\"\u003ehttps://medium.com/media/7e5132cb958ccf0a06cd9e1c9f11781c/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eLet’s put an instance of our Domain class into the bindings for R, so it can be accessed from the R guest language context:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/5393f68ce45968ecfb3227cf89c4f771/href\"\u003ehttps://medium.com/media/5393f68ce45968ecfb3227cf89c4f771/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eEasy peasy. From R, the new object will simply be known as Domain and its methods will be accessible like this: Domain$methodName(arguments)\u003c/p\u003e\u003cp\u003eWe turn a new R file, that uses this binding, into our newest Source:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/92c7888cae1e6b4a450d20944457369d/href\"\u003ehttps://medium.com/media/92c7888cae1e6b4a450d20944457369d/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eAnd then we define the function:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/fb46db7c7465f5e596e35b2a8d0bc399/href\"\u003ehttps://medium.com/media/fb46db7c7465f5e596e35b2a8d0bc399/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eNow that this is our return type, all we need to do to work with the returned WeatherForecasts is this:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/7f28f8cfe8bd2c744ec6326a1fb9417e/href\"\u003ehttps://medium.com/media/7f28f8cfe8bd2c744ec6326a1fb9417e/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eThat is one very happy Data Engineer! (Don’t forget to compare with the incomplete parsing above.)\u003c/p\u003e\u003cp\u003eNow, let’s see the impact on the DataScientist side:\u003c/p\u003e\u003ciframe src=\"\" width=\"0\" height=\"0\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/15fe0238001746bf073b808472cb29cc/href\"\u003ehttps://medium.com/media/15fe0238001746bf073b808472cb29cc/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eAs we can see, the code has become more verbose (although it’s actually quite efficient still, if you take out all the clarifying comments I put in), but not quite as bad as in the previous solution:\u003c/p\u003e\u003cp\u003eIn this R file, we now need to convert the data.frame to proper WeatherForecast instances to be added to the WeatherForecastList we also got from Domain. But rather than doing a Parse \u0026 Pray, as we had to do with the no-bindings solution, we can now use proper constructors that will fail with intelligible errors if we make a mistake. (Sadly still only at runtime, because this is still R.) Cleanly taking values out of the data.frame is also better supported by its native language and we could add more convenience methods to more succinctly create the domain classes if we wanted to. If we have direct control over the function that creates the weather forecasts, we can even skip the data.frame altogether and exclusively use WeatherForecastList, which eliminates the extra code seen above.\u003c/p\u003e\u003cp\u003eThe biggest advantage, though, is that we now have a very clearly defined interface. Any user can open up the Domain.scala file to see what methods are available, what parameters they take and what things they return.\u003c/p\u003e\u003ch3\u003e\u003cstrong\u003eConclusion\u003c/strong\u003e\u003c/h3\u003e\u003cp\u003eUsing Bindings to provide a clean shared domain between guest languages (like R or Python) and JVM languages (like Scala, Java or Kotlin) in GraalVM is pretty easy and gets rid of a lot of ugly and fault-sensitive parsing. It also provides a crucial stepping stone for further integration of functionalities across language boundaries.\u003c/p\u003e\u003cp\u003e\u003cstrong\u003ePS\u003c/strong\u003e: I could have added a factory for each separate domain class to the bindings, instead of giving them a shared factory. This can make the code on the R side a little shorter, but creates a less clean interface (at least to my taste).\u003c/p\u003e\u003ch3\u003e\u003cstrong\u003eSourcecode\u003c/strong\u003e\u003c/h3\u003e\u003cp\u003eI have reused the example project from my previous article on \u003ca href=\"https://medium.com/codestar-blog/in-search-of-the-holy-graalvm-putting-the-r-in-scala-or-java-or-b057494f77\"\u003eusing GraalVM to execute R files from Scala\u003c/a\u003e) and branched it for this article. The source code can be found \u003ca href=\"https://github.com/NRBPerdijk/example-graalvm-r-scala/tree/usingBindingsToShareDomain\"\u003ehere\u003c/a\u003e. The snippets above are taken from the linked project and altered to better fit the sizing of the article.\u003c/p\u003e\u003cimg src=\"https://medium.com/_/stat?event=post.clientViewed\u0026referrerSource=full_rss\u0026postId=b561e8cfbcfa\" width=\"1\" height=\"1\" alt=\"\"\u003e\u003chr\u003e\u003cp\u003e\u003ca href=\"https://medium.com/codestar-blog/sharing-is-caring-domain-objects-in-both-scala-and-r-with-graalvm-polyglot-bindings-b561e8cfbcfa\"\u003eSharing is Caring! Domain objects in BOTH Scala and R with GraalVM Polyglot bindings.\u003c/a\u003e was originally published in \u003ca href=\"https://medium.com/codestar-blog\"\u003eCodestar blog\u003c/a\u003e on Medium, where people are continuing the conversation by highlighting and responding to this story.\u003c/p\u003e"},{"id":"https://medium.com/p/cd7456268dc5","title":"Using generative art to create a pulsating SVG star","author":"Hamza Haiken","latestPublishedAt":"Fri, 12 Apr 2019 09:39:17 GMT","uniqueSlug":"https://medium.com/codestar-blog/using-generative-art-to-create-a-pulsating-svg-star-cd7456268dc5?source=rss----ea5cff13e3c9---4","paragraphs":"\u003ch4\u003ePart 1 — Intro\u003c/h4\u003e\u003cp\u003eI recently created a new design for our recruitment campaign at Codestar. It represents a burning star, with \u003ca href=\"https://www.ucl.ac.uk/news/sites/news/files/corona-web.jpg\"\u003ecorona-like features\u003c/a\u003e, represented in an abstract way, aiming to make it feel like a pulsating stream of data (The original artist for the star is \u003ca href=\"https://www.shutterstock.com/g/GarryKillian\"\u003eGarry Killian\u003c/a\u003e).\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/1024/1*lY5WPHYbCz_PDY-PaxTa0A.png\" /\u003e\u003cfigcaption\u003eWe’re very big on only hiring Latin speakers\u003c/figcaption\u003e\u003c/figure\u003e\u003cp\u003eThe rest of the team enjoyed it, and we nicknamed this design \u003cem\u003e“the code star”\u003c/em\u003e. It was then suggested that we could try and recreate this as an animation for our website, or to simply just to generate as many different static stars as we want: a teammate’s name could be used as a random seed, and they would be given their own special code star.\u003c/p\u003e\u003cp\u003eIn this series of blog posts, I will endeavor to explain my process in taking on this challenge, going through various subjects, in particular \u003cem\u003egenerative art\u003c/em\u003e and \u003cem\u003eSVG animation.\u003c/em\u003e\u003c/p\u003e\u003cp\u003eOur goal in this series will be to re-create the above visual in SVG, and animate it to make it slowly pulsate, like the sun’s corona.\u003c/p\u003e\u003ch3\u003eWhat is generative art?\u003c/h3\u003e\u003cp\u003eThe term \u003ca href=\"https://en.wikipedia.org/wiki/Generative_art\"\u003e“generative art”\u003c/a\u003e (or also “procedural art”) refers the making of art algorithmically, typically relying on fractals and randomness.\u003c/p\u003e\u003cp\u003eFamous examples of this include: \u003ca href=\"https://i.imgur.com/gV0cxPU.jpg\"\u003ethat one album cover that everybody wears on a t-shirt\u003c/a\u003e, \u003ca href=\"https://i.imgur.com/smNksSJ.jpg\"\u003eMinecraft’s infinitely expanding worlds\u003c/a\u003e, \u003ca href=\"https://www.rockpapershotgun.com/images/16/aug/nmsg8s.jpg\"\u003eNo Man’s Sky’s universe and planets\u003c/a\u003e, and many more.\u003c/p\u003e\u003cp\u003eFor further learning about getting started in generative art (after reading this of course!), I recommend as starting points \u003ca href=\"https://generativeartistry.com\"\u003eGenerative Artistry\u003c/a\u003e and \u003ca href=\"https://www.youtube.com/channel/UCvjgXvBlbQiydffZU7m1_aw\"\u003eThe Coding Train\u003c/a\u003e YouTube channel, which often takes on generative art challenges.\u003c/p\u003e\u003ch3\u003eNoise\u003c/h3\u003e\u003cp\u003eOne commonly used tool in the field of generative art is \u003cem\u003enoise\u003c/em\u003e — in particular, \u003ca href=\"https://en.wikipedia.org/wiki/Perlin_noise\"\u003ePerlin\u003c/a\u003e, or \u003ca href=\"https://en.wikipedia.org/wiki/Simplex_noise\"\u003eSimplex noise\u003c/a\u003e (which is more suited for animations since it has a lower overhead). It is used for a variety of results: terrain, smoke, clouds, textures.\u003c/p\u003e\u003cp\u003eThis kind of noise is obtained by overlaying noise at different frequencies on top of each other, forming a cloud-like texture that expands infinitely in any direction. The nice thing about this method of constructing noise is that it can be expanded to support any number of required dimensions (in our case, a 3D space).\u003c/p\u003e\u003cp\u003eIn a nutshell, Perlin noise is constructed by averaging noise rendered at several scales (bilinear interpolation is used to smooth out the lower frequencies):\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/801/1*upB28P_sCBlqPhXgWO15Zw.png\" /\u003e\u003cfigcaption\u003eImage source: \u003ca href=\"https://medium.com/100-days-of-algorithms/day-88-perlin-noise-96d23158a44c\"\u003ehttps://medium.com/100-days-of-algorithms/day-88-perlin-noise-96d23158a44c\u003c/a\u003e\u003c/figcaption\u003e\u003c/figure\u003e\u003cp\u003eWhen averaging all of these (using some kind of weighted distribution), the following natural, cloudy texture is obtained:\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/511/1*WHpL6IJd_gUROUmBUlXWnQ.png\" /\u003e\u003cfigcaption\u003eCould this image just be the “cloud” filter in Photoshop? Who knows\u003c/figcaption\u003e\u003c/figure\u003e\u003cp\u003eUsed creatively, this noise can be used to create impressive results, like this \u003ca href=\"https://skybase.wordpress.com/2012/01/26/how-to-creating-super-simple-procedural-wood-textures-in-filter-forge/\"\u003ewood texture\u003c/a\u003e for example (and again, given the nature of Perlin noise, this texture can expand seamlessly in any direction).\u003c/p\u003e\u003cfigure\u003e\u003cimg alt=\"\" src=\"https://cdn-images-1.medium.com/max/1024/1*zlgGPvL70VCc9cOf5VFBsA.jpeg\" /\u003e\u003cfigcaption\u003eSitting atop a mathematically generated hill is a big dream of mine\u003c/figcaption\u003e\u003c/figure\u003e\u003cp\u003e\u003ca href=\"https://i.redd.it/rq3ptj8i75b21.jpg\"\u003eAnd here\u003c/a\u003e is an example from the game “No Man’s Sky”. The mountains in such a landscape are created using low-frequency noise (big features), the smaller hills on top of that come from the middle range of noise frequencies, and if you zoom in even closer the small dirt bumps are added on top of the hills by adding in the values of a higher frequency (this is like a fractal). Additionally, the noise formula can also be (and was) manipulated in such a way as to seamlessly wrap around a sphere.\u003c/p\u003e\u003ch3\u003eUsing noise\u003c/h3\u003e\u003cp\u003eOne of the big advantages of Perlin noise: by traveling along its plane, the intensity values increase and decrease \u003cstrong\u003econtinuously\u003c/strong\u003e. This is not only very useful for terrain generation for creating hills and valleys, but also for \u003cem\u003eanimation\u003c/em\u003e, providing offsets that will smoothly increase or decrease randomly in a natural way.\u003c/p\u003e\u003cp\u003eWe will use \u003ca href=\"https://github.com/jwagner/simplex-noise.js\"\u003esimplex-noise.js\u003c/a\u003e for generating our noise. This is not Perlin but Simplex noise; it looks less detailed, and is faster to compute. The library provides a simple API: just instantiate a noise object with a \u003ca href=\"https://en.wikipedia.org/wiki/Random_seed\"\u003erandom seed\u003c/a\u003e, which you can then use for getting noise values in 2D, 3D or 4D:\u003c/p\u003e\u003cpre\u003elet simplex = new SimplexNoise(\"tutorial seed\");\u003cbr\u003elet value = simplex.noise2D(0.42, 13.37);\u003c/pre\u003e\u003cp\u003ePrecision can be as small as needed, effectively zooming in on the noise, and the whole 2D plane that can be represented with JavaScript numbers is available to us.\u003c/p\u003e\u003cp\u003eHere is a simple demo on how to use Simplex noise. Feel free to play around with the sliders, particularly with the z-axis (slowly).\u003c/p\u003e\u003ciframe src=\"https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fcodepen.io%2FTenchi2xh%2Fembed%2Fpreview%2FZVdLOo%3Fheight%3D600%26slug-hash%3DZVdLOo%26default-tabs%3Djs%2Cresult%26host%3Dhttps%3A%2F%2Fcodepen.io\u0026url=https%3A%2F%2Fcodepen.io%2FTenchi2xh%2Fpen%2FZVdLOo\u0026image=https%3A%2F%2Fscreenshot.codepen.io%2F273979.ZVdLOo.small.4ab4ffde-92ca-4056-abc1-9a1f71fb3192.png\u0026key=a19fcc184b9711e1b4764040d3dc5c07\u0026type=text%2Fhtml\u0026schema=codepen\" width=\"800\" height=\"600\" frameborder=\"0\" scrolling=\"no\"\u003e\u003ca href=\"https://medium.com/media/7d32cde0d50fcb456ebd1d75717334b2/href\"\u003ehttps://medium.com/media/7d32cde0d50fcb456ebd1d75717334b2/href\u003c/a\u003e\u003c/iframe\u003e\u003cp\u003eMoving along the X- and Y-axes feels natural to us humans — it just looks like standard translation — but it shows us that the noise is indeed continuous.\u003c/p\u003e\u003cp\u003eMoving along the Z-axis, however, gives a totally different feeling, exposing the vertical continuity of the noise by showing us slices of what seems to be an animation.\u003c/p\u003e\u003cp\u003eThe color values at a given pixel coordinates change continuously and smoothly while navigating along the Z direction.\u003c/p\u003e\u003cp\u003eThis is a big clue; by using the Z-axis to represent time, we can now animate things.\u003c/p\u003e\u003cp\u003eBut before we can animate, we will first need a drawing!\u003c/p\u003e\u003ch3\u003eComing up in this series\u003c/h3\u003e\u003cp\u003eStick around on the Codestar blog to catch the next parts in this series:\u003c/p\u003e\u003cul\u003e\u003cli\u003eDrawing the basis for the SVG star: basic \u003ca href=\"http://snapsvg.io/\"\u003eSnap.svg\u003c/a\u003e tutorial\u003c/li\u003e\u003cli\u003eMapping star element coordinates using the Simplex noise as a displacement map: some trigonometry and calculus\u003c/li\u003e\u003cli\u003eAnimation: bringing everything together, and using \u003ca href=\"https://cocopon.github.io/tweakpane\"\u003eTweakpane\u003c/a\u003e for playing around with the settings\u003c/li\u003e\u003cli\u003eMaking a tool for outputting static SVG images using a string seed for generating a random star\u003c/li\u003e\u003c/ul\u003e\u003cimg src=\"https://medium.com/_/stat?event=post.clientViewed\u0026referrerSource=full_rss\u0026postId=cd7456268dc5\" width=\"1\" height=\"1\" alt=\"\"\u003e\u003chr\u003e\u003cp\u003e\u003ca href=\"https://medium.com/codestar-blog/using-generative-art-to-create-a-pulsating-svg-star-cd7456268dc5\"\u003eUsing generative art to create a pulsating SVG star\u003c/a\u003e was originally published in \u003ca href=\"https://medium.com/codestar-blog\"\u003eCodestar blog\u003c/a\u003e on Medium, where people are continuing the conversation by highlighting and responding to this story.\u003c/p\u003e"}],"upcomingMeetups":[],"pastMeetups":[{"created":1697454939000,"duration":14400000,"id":"296766473","name":"Workshop Red Hat Ansible Lightspeed and other Ansible development tools","date_in_series_pattern":false,"status":"past","time":1701351000000,"local_date":"2023-11-30","local_time":"14:30","rsvp_open_offset":"PT24H","updated":1701371524000,"utc_offset":3600000,"waitlist_count":0,"yes_rsvp_count":1,"is_online_event":false,"eventType":"PHYSICAL","group":{"created":1465915067000,"name":"Codestar Night","id":20072875,"join_mode":"open","lat":52.099998474121094,"lon":5.110000133514404,"urlname":"Codestar-Night","who":"Codestars","localized_location":"Utrecht, Netherlands","state":"","country":"nl","region":"en_US","timezone":"Europe/Amsterdam"},"link":"https://www.meetup.com/codestar-night/events/296766473/","description":"\u003cp\u003eYou can sign up right now via this link: [\u003ca href=\"https://www.ordina.com/insights/events/red-hat-openshift-workshop-2/](https://www.ordina.com/insights/events/red-hat-openshift-workshop-2/\" class=\"linkified\"\u003ehttps://www.ordina.com/insights/events/red-hat-openshift-workshop-2/](https://www.ordina.com/insights/events/red-hat-openshift-workshop-2/\u003c/a\u003e)\u003c/p\u003e \u003cp\u003eRecently Ansible Lightspeed has been introduced by Red Hat as an addition to existing developer tools in Ansible. Ansible Lightspeed (including IBM Watson Code Assistant) is a generative AI tool which makes it easier for developers to automate tasks in Ansible playbooks and create Ansible content. This session led by a Red Hat instructor is themed around \"A day in the life of an (Ansible) software developer\" and is focusing on tools that can help developers to create and improve Ansible playbooks in an efficient way.\u003c/p\u003e \u003cp\u003e**Agenda**\u003c/p\u003e \u003cp\u003e* 14:30 - 15:00: Registration\u003cbr/\u003e* 15:00 - 16:00: A day in the life of an Ansible developer\u003cbr/\u003e* 16:00 - 18:15: Labs\u003cbr/\u003e* 18:15- 18:30: Closure\u003c/p\u003e \u003cp\u003e**When** : November 30th 2023 van 15:00-19:00\u003cbr/\u003e**Where** : Ringwade 1, Nieuwegein\u003cbr/\u003e**Who** : Software developers, Cloud Engineers and DevOps Engineers\u003cbr/\u003e**What** : Bring your own laptop.\u003c/p\u003e ","visibility":"public","member_pay_fee":false,"featured_photo":{"id":516608243,"highres_link":"https://secure.meetupstatic.com/photos/event/2/0/3/3/highres_516608243.jpeg","photo_link":"https://secure.meetupstatic.com/photos/event/2/0/3/3/600_516608243.jpeg","thumb_link":"https://secure.meetupstatic.com/photos/event/2/0/3/3/thumb_516608243.jpeg","type":"event","base_url":"https://secure.meetupstatic.com"}},{"created":1698310263000,"duration":10800000,"id":"296966454","name":"Codesmiths Unite ","date_in_series_pattern":false,"status":"past","time":1700755200000,"local_date":"2023-11-23","local_time":"17:00","updated":1700771768000,"utc_offset":3600000,"waitlist_count":0,"yes_rsvp_count":8,"venue":{"id":26404459,"name":"Ringwade 1","lat":52.057823181152344,"lon":5.111423015594482,"repinned":true,"address_1":"Ringwade 1","city":"Nieuwegein","country":"nl","localized_country_name":"Netherlands"},"is_online_event":false,"eventType":"PHYSICAL","group":{"created":1465915067000,"name":"Codestar Night","id":20072875,"join_mode":"open","lat":52.099998474121094,"lon":5.110000133514404,"urlname":"Codestar-Night","who":"Codestars","localized_location":"Utrecht, Netherlands","state":"","country":"nl","region":"en_US","timezone":"Europe/Amsterdam"},"link":"https://www.meetup.com/codestar-night/events/296966454/","description":"\u003cp\u003e**Details**\u003cbr/\u003eOrdina Codesmiths stand for a shared passion in Software Engineering and knowledge sharing.\u003cbr/\u003eJoin us on the 23rd of November and meet your peer developers and hear interesting learnings on topics as Cloud, Security, Frontend, Mobile and testing.\u003c/p\u003e \u003cp\u003e**Program:**\u003cbr/\u003e**Walk in 17:00**\u003cbr/\u003e**Buffet and drinks 17:15**\u003cbr/\u003e**Opening 18:00**\u003cbr/\u003e**Talk 1 18:10 - 18:35**\u003cbr/\u003eFrederieke Scheper - Kubernetes deployment done right\u003cbr/\u003e**Talk 2 18:40 - 19:05**\u003cbr/\u003eRick Hutten - Simplifying Concurrency\u003cbr/\u003e**Break**\u003cbr/\u003e**Talk 3 19:20 - 19:45**\u003cbr/\u003eKaya Weers - Design patterns\u003cbr/\u003e**Drinks 19:45**\u003c/p\u003e \u003cp\u003e**About the talks and presenters**\u003c/p\u003e \u003cp\u003e**Frederieke Scheper**\u003cbr/\u003e**Helm - Kubernetes deployments done right**\u003cbr/\u003eInstead of steering into the murky waters of unmaintainable copy-pasted Kubernetes YAML files, let’s take the Helm and let it manage all your Kubernetes deployments, from a simple Spring Boot microservice to the most complex Kubernetes application! In this presentation, I will show you how easy it is to create, version, share, and publish Helm Charts. So, start using Helm and stop the copy-and-pasting. Along the way, you will discover the real benefits that lay in the role it plays in streamlining your CI/CD pipelines. Helm automatically maintains a database of all the versions of your releases. So, whenever something goes wrong during deployment, rolling back to the previous version is just one command away. So, let’s take a deep dive into Helm charts, templates, and functions: Kubernetes deployments done right!\u003c/p\u003e \u003cp\u003e**Rick Hutten**\u003cbr/\u003e**Simplifying Concurrency with Project Loom: A Journey with Pizza-chef Fabio**\u003cbr/\u003eProject Loom, a groundbreaking feature within OpenJDK, introduces a lightweight and versatile concurrency model for Java. Understanding concurrency can be challenging, especially for non-technical individuals and novice developers. In this session, we embark on an adventure alongside Fabio, a passionate pizza-chef facing similar challenges in his upscale restaurant as those encountered in multithreading on a CPU. We delve into concepts such as CPU threads, virtual threads, and structured concurrency, making them accessible to listeners of all proficiency levels. Attendees will not only learn to recognize the use cases of these techniques but also gain insights into how and if Project Loom can enhance their application.\u003c/p\u003e \u003cp\u003e**Kaya Weers**\u003cbr/\u003e**A design pattern goes to the supermarket**\u003cbr/\u003eEverybody knows the term design patterns. Some know the patterns and correct implementation by heart. Others vaguely recognize the pattern names but don’t recall the details. This talk is intended for the latter group.\u003cbr/\u003eI’ll dive into a couple of design patterns using real-life examples. What would a design pattern look like in day-to-day life? We’ll follow Bobby and Billie and discover how a design pattern would behave in a non-digital environment: the supermarket! With the help of drawings, this talk will give you a solid understanding of design patterns, so you won't have to look them up ever again!\u003c/p\u003e ","visibility":"public","member_pay_fee":false,"featured_photo":{"id":516824538,"highres_link":"https://secure.meetupstatic.com/photos/event/a/d/f/a/highres_516824538.jpeg","photo_link":"https://secure.meetupstatic.com/photos/event/a/d/f/a/600_516824538.jpeg","thumb_link":"https://secure.meetupstatic.com/photos/event/a/d/f/a/thumb_516824538.jpeg","type":"event","base_url":"https://secure.meetupstatic.com"}},{"created":1698153898000,"duration":14400000,"id":"296928992","name":"Tech Women Connect","date_in_series_pattern":false,"status":"past","time":1700751600000,"local_date":"2023-11-23","local_time":"16:00","updated":1700771737000,"utc_offset":3600000,"waitlist_count":0,"yes_rsvp_count":17,"venue":{"id":24315864,"name":"Ordina HQ ","lat":52.05641174316406,"lon":5.110540866851807,"repinned":true,"address_1":"Ringwade 1","city":"Nieuwegein","country":"nl","localized_country_name":"Netherlands"},"is_online_event":false,"eventType":"PHYSICAL","group":{"created":1465915067000,"name":"Codestar Night","id":20072875,"join_mode":"open","lat":52.099998474121094,"lon":5.110000133514404,"urlname":"Codestar-Night","who":"Codestars","localized_location":"Utrecht, Netherlands","state":"","country":"nl","region":"en_US","timezone":"Europe/Amsterdam"},"link":"https://www.meetup.com/codestar-night/events/296928992/","description":"\u003cp\u003eOn the 23*rd* of November we are organizing the Tech Women Connect event at the Ordina office in Utrecht(Nieuwegein), it’s an inspiring gathering that celebrates and empowers women in the tech industry.\u003c/p\u003e \u003cp\u003eIn the last four decades, there has been increasingly more attention on the participation of women in male-dominated sectors, such as IT — another milestone to celebrate. However, women in male-dominated careers still face challenges today.\u003cbr/\u003eModern day workforces are moving in the right direction, yet many women are not experiencing the benefits. So how can individual women continue and accelerate to thrive in male-dominated industries?\u003cbr/\u003ePerhaps the best approach is to ask individual women who have done it…\u003c/p\u003e \u003cp\u003eHere’s what you can look forward to:\u003c/p\u003e \u003cp\u003e**Valuable Insights:** *Gain priceless insights from accomplished women in tech. Learn from their experiences, achievements, and challenges, and discover how you can succeed and thrive in the tech industry.*\u003cbr/\u003e**Networking Opportunities:** *Connect with remarkable tech women, industry leaders, and like-minded professionals. Forge new connections, exchange ideas.*\u003cbr/\u003e**Exciting Games and Activities!**\u003c/p\u003e \u003cp\u003e**Event Details:**\u003cbr/\u003eDate: November 23, 2023\u003cbr/\u003eTime: 16:00 – 20:00\u003cbr/\u003eVenue: A12.06 AUDITORIUM, Ringwade 1, Nieuwegein\u003c/p\u003e \u003cp\u003e**Program Schedule:**\u003c/p\u003e \u003cp\u003e* **16:00 – 16:40: Keynote Speaker (Stacy Cashmore – “My Journey into Speaking”)** *Join us as we kick off the evening with an engaging keynote address from a prominent tech women who will share her remarkable journey into the world of public speaking. Get ready to be inspired by her insights and experiences.*\u003cbr/\u003e* **17:00 – 18:00: Panel Discussion – “Tech Women in a Male-Dominated Culture”** *Our panel of women tech experts will engage in a discussion on the challenges and triumphs of women working in male-dominated environments.*\u003cbr/\u003e* **18:00 – 18:30: Keynote Speaker (Kaya Weers – “The Non-Typical Dev”)** *Our second keynote speaker will dive into the world of not fitting in the stereotypes and the importance of feeling like you belong.*\u003cbr/\u003e* **19:00 onwards: Dinner and Networking** – *it’s time to relax, connect, and enjoy small drinks and some snacks (vegetarian options included).*\u003c/p\u003e \u003cp\u003e**Note:** we have limited seats for external attendees. Please confirm and sign up as soon as possible to secure your seat. Once you receive a confirmation from our side you will be a confirmed guest to the event..\u003c/p\u003e \u003cp\u003e**How to get there?**\u003c/p\u003e \u003cp\u003e**Public transport**\u003cbr/\u003eAt Utrecht Centraal, take BUS 65/74/77 or Tram 60, both stop at Westraven, from there it’s a 5-10 min walk to the Ordina office.\u003c/p\u003e \u003cp\u003e**Car**\u003cbr/\u003eYou have free parking outside the Ordina office (Ringwade 1, Nieuwegein)\u003c/p\u003e ","visibility":"public","member_pay_fee":false,"featured_photo":{"id":516794606,"highres_link":"https://secure.meetupstatic.com/photos/event/3/9/0/e/highres_516794606.jpeg","photo_link":"https://secure.meetupstatic.com/photos/event/3/9/0/e/600_516794606.jpeg","thumb_link":"https://secure.meetupstatic.com/photos/event/3/9/0/e/thumb_516794606.jpeg","type":"event","base_url":"https://secure.meetupstatic.com"}},{"created":1696248935000,"duration":10800000,"id":"296486807","name":"Ordina Frontend Community presents: Back to basics panel discussion","rsvp_limit":15,"date_in_series_pattern":false,"status":"past","time":1697729400000,"local_date":"2023-10-19","local_time":"17:30","rsvp_close_offset":"PT72H30M","updated":1697749352000,"utc_offset":7200000,"waitlist_count":0,"yes_rsvp_count":5,"venue":{"id":26404459,"name":"Ringwade 1","lat":52.057823181152344,"lon":5.111423015594482,"repinned":true,"address_1":"Ringwade 1","city":"Nieuwegein","country":"nl","localized_country_name":"Netherlands"},"is_online_event":false,"eventType":"PHYSICAL","group":{"created":1465915067000,"name":"Codestar Night","id":20072875,"join_mode":"open","lat":52.099998474121094,"lon":5.110000133514404,"urlname":"Codestar-Night","who":"Codestars","localized_location":"Utrecht, Netherlands","state":"","country":"nl","region":"en_US","timezone":"Europe/Amsterdam"},"link":"https://www.meetup.com/codestar-night/events/296486807/","description":"\u003cp\u003e**Back to basics panel discusison**\u003cbr/\u003eOrdina's Frontend Community would like to present to you an open and interactive discussion about the world of frontend. We'll talk about *\"How we've gotten here and where it is going\".*\u003c/p\u003e \u003cp\u003eCome and join us to have a chat about how complex the world of modern front end development has become, trends we see returning from the past and how this all affects our daily jobs as frontend developers.\u003c/p\u003e \u003cp\u003eTopics like:\u003c/p\u003e \u003cp\u003e* **Have our tools** been focussed too much on **Developer Experience**, instead of the **User**?\u003cbr/\u003e\\- What **benefits** do our **modern stacks** have, and **for who** are these benefits?\u003c/p\u003e \u003cp\u003eAnd more, we're **taking** your **suggestions**!\u003c/p\u003e \u003cp\u003e\u003ca href=\"https://forms.office.com/e/dLK7MbgHm6\" class=\"linkified\"\u003ehttps://forms.office.com/e/dLK7MbgHm6\u003c/a\u003e\u003c/p\u003e \u003cp\u003e**Programme**\u003cbr/\u003e**17:30 Walk-in, dinner \u0026amp; drinks**\u003cbr/\u003eA diverse dinner will be served, any dietary preferences or restrictions can be mentioned in the signup form.\u003c/p\u003e \u003cp\u003e**18:45 Introductions of our panelists**\u003cbr/\u003eWe'll move to the main venue room and open with a short introduction of our panelists and their diverse experiences.\u003c/p\u003e \u003cp\u003e**19:00 Panel discussion**\u003cbr/\u003eKick off the panel discussion with some topics, suggested by **you**! Use the signup form to add your ideas/controversial topics or other suggestions to the discussion up front!\u003c/p\u003e \u003cp\u003e**20:00 Closing \u0026amp; Drinks**\u003cbr/\u003eAfter a good hour of chatting about a diverse range of prepared topics and questions, we'll close the main room. There'll be plenty of opportunity to continue any discussions or conversations with a drink and snack before we close the venue for the day.\u003c/p\u003e \u003cp\u003eThis event will be cross posted on Meetup.com and internally to Ordina colleagues. Therefore there will be a stricter limit on amount of registrations for this specific event.\u003c/p\u003e ","how_to_find_us":"By bicycle: Plenty of parking room for bicycles at the front door.\nBy public transport: Tramlines 20 \u0026 21 stop within a short walk's distance\nBy car: Free parking in front of the building","visibility":"public","member_pay_fee":false,"featured_photo":{"id":516309713,"highres_link":"https://secure.meetupstatic.com/photos/event/2/5/f/1/highres_516309713.jpeg","photo_link":"https://secure.meetupstatic.com/photos/event/2/5/f/1/600_516309713.jpeg","thumb_link":"https://secure.meetupstatic.com/photos/event/2/5/f/1/thumb_516309713.jpeg","type":"event","base_url":"https://secure.meetupstatic.com"}},{"created":1693462430000,"duration":14400000,"id":"295795991","name":"Creating UI libraries by utilizing Storybook, ReactJs, NPM and Azure.","date_in_series_pattern":false,"status":"past","time":1695913200000,"local_date":"2023-09-28","local_time":"17:00","updated":1695935924000,"utc_offset":7200000,"waitlist_count":0,"yes_rsvp_count":2,"venue":{"id":24315864,"name":"Ordina HQ ","lat":52.05641174316406,"lon":5.110540866851807,"repinned":true,"address_1":"Ringwade 1","city":"Nieuwegein","country":"nl","localized_country_name":"Netherlands"},"is_online_event":false,"eventType":"PHYSICAL","group":{"created":1465915067000,"name":"Codestar Night","id":20072875,"join_mode":"open","lat":52.099998474121094,"lon":5.110000133514404,"urlname":"Codestar-Night","who":"Codestars","localized_location":"Utrecht, Netherlands","state":"","country":"nl","region":"en_US","timezone":"Europe/Amsterdam"},"link":"https://www.meetup.com/codestar-night/events/295795991/","description":"\u003cp\u003eSign up for this event here: [\u003ca href=\"https://www.meetup.com/utrecht-frontend-meetup/events/295531915/](https://www.meetup.com/utrecht-frontend-meetup/events/295531915/\" class=\"linkified\"\u003ehttps://www.meetup.com/utrecht-frontend-meetup/events/295531915/](https://www.meetup.com/utrecht-frontend-meetup/events/295531915/\u003c/a\u003e)\u003c/p\u003e \u003cp\u003eIf you have ever attempted to extract your UI libraries into an abstract package which can be consumed just like any other NPM package. You’ll probably have encountered quite a few hurdles. For example:\u003c/p\u003e \u003cp\u003e1. How do I build the code, do I use CJS or ESM?\u003c/p\u003e \u003cp\u003e2. How do I ensure code quality?\u003c/p\u003e \u003cp\u003e3. How do I actually publish an NPM package?\u003c/p\u003e \u003cp\u003e4. Can the publishing of packages be automated by CI/CD?\u003c/p\u003e \u003cp\u003e5. How do I provide interactive documentation like Bootstrap or Material UI?\u003c/p\u003e \u003cp\u003eIf you have ever encountered or wondered about these questions this workshop is for you. We will set up a Storybook Application, unit test it, publish it via CI/CD, containerize it with Docker, publish our container to Azure Container Registry and finally publish the container to an Azure web app.\u003c/p\u003e \u003cp\u003eThe workshop will be hosted on the 28*th* of September 17:00 - 21:00, food and drinks are included!\u003c/p\u003e \u003cp\u003ePre-requisites: Some experience with JavaScript. Any CI/CD experience will help but is not necessary.\u003c/p\u003e \u003cp\u003eA github Repo will be available for reference.\u003c/p\u003e ","visibility":"public","member_pay_fee":false,"featured_photo":{"id":515525035,"highres_link":"https://secure.meetupstatic.com/photos/event/1/3/a/b/highres_515525035.jpeg","photo_link":"https://secure.meetupstatic.com/photos/event/1/3/a/b/600_515525035.jpeg","thumb_link":"https://secure.meetupstatic.com/photos/event/1/3/a/b/thumb_515525035.jpeg","type":"event","base_url":"https://secure.meetupstatic.com"}},{"created":1695301754000,"duration":21600000,"id":"296251627","name":"Workshop Red Hat OpenShift","date_in_series_pattern":false,"status":"past","time":1695812400000,"local_date":"2023-09-27","local_time":"13:00","updated":1695841163000,"utc_offset":7200000,"waitlist_count":0,"yes_rsvp_count":1,"venue":{"id":24315864,"name":"Ordina HQ ","lat":52.05641174316406,"lon":5.110540866851807,"repinned":false,"address_1":"Ringwade 1","city":"Nieuwegein","country":"nl","localized_country_name":"Netherlands"},"is_online_event":false,"eventType":"PHYSICAL","group":{"created":1465915067000,"name":"Codestar Night","id":20072875,"join_mode":"open","lat":52.099998474121094,"lon":5.110000133514404,"urlname":"Codestar-Night","who":"Codestars","localized_location":"Utrecht, Netherlands","state":"","country":"nl","region":"en_US","timezone":"Europe/Amsterdam"},"link":"https://www.meetup.com/codestar-night/events/296251627/","description":"\u003cp\u003eFree registration is open @ [\u003ca href=\"https://www.ordina.com/insights/events/red-hat-openshift-workshop/](https://www.ordina.com/insights/events/red-hat-openshift-workshop/\" class=\"linkified\"\u003ehttps://www.ordina.com/insights/events/red-hat-openshift-workshop/](https://www.ordina.com/insights/events/red-hat-openshift-workshop/\u003c/a\u003e)\u003cbr/\u003e***Note that the registration process goes via the website above as we need to setup a lab environment specifically for you. Please keep in mind that with a no-show you're potentially taking someone else's spot.***\u003cbr/\u003eParticipate in our journey into the world of cloud-native application development and deployment. Embrace the efficiency of cloud-native CI/CD pipelines with Openshift and learn how to streamline your application lifecycle management with OpenShift GitOps. With two dynamic workshops on 27 September led by an experienced Red Hat instructor focusing on OpenShift Pipelines and OpenShift GitOps, you can gain hands-on skills and insights that enable you to stay ahead in the rapidly evolving landscape of cloud-native technology.\u003cbr/\u003e**Program:**\u003cbr/\u003e**Walk in 14:30 - 15:00 hrs**\u003cbr/\u003e**Introduction Red Hat and OpenShift 15:00 - 16:00 hrs**\u003cbr/\u003e**Labs 16:00 - 18:30 hrs**\u003c/p\u003e \u003cp\u003e* *1- Introduction Openshift pipelines*\u003c/p\u003e \u003cp\u003eOpenShift Pipelines is a cloud-native, CI/CD delivery solution to build pipelines on OpenShift using Tekton.\u003cbr/\u003e* 2- *OpenShift GitOps*\u003c/p\u003e \u003cp\u003eStart using OpenShift GitOps and start deployments with Red Hat OpenShift GitOps (based on ArgoCD) and use Kustomize, sync waves, and hooks.\u003c/p\u003e \u003cp\u003e**Closure 18:30 - 19:00 hrs**\u003cbr/\u003eDon't miss this chance to elevate your technical expertise and reserve your spot now for our upcoming Red Hat OpenShift workshop on September 27th and get up to speed in the world of modern application development and operations.\u003cbr/\u003e***Don't forget to bring your own laptop!***\u003c/p\u003e ","visibility":"public","member_pay_fee":false},{"created":1681909979000,"duration":12600000,"id":"292995726","name":"AI Hackathon","date_in_series_pattern":false,"status":"past","time":1688052600000,"local_date":"2023-06-29","local_time":"17:30","updated":1688072986000,"utc_offset":7200000,"waitlist_count":0,"yes_rsvp_count":4,"venue":{"id":24315864,"name":"Ordina HQ ","lat":52.05641174316406,"lon":5.110540866851807,"repinned":true,"address_1":"Ringwade 1","city":"Nieuwegein","country":"nl","localized_country_name":"Netherlands"},"is_online_event":false,"eventType":"PHYSICAL","group":{"created":1465915067000,"name":"Codestar Night","id":20072875,"join_mode":"open","lat":52.099998474121094,"lon":5.110000133514404,"urlname":"Codestar-Night","who":"Codestars","localized_location":"Utrecht, Netherlands","state":"","country":"nl","region":"en_US","timezone":"Europe/Amsterdam"},"link":"https://www.meetup.com/codestar-night/events/292995726/","description":"\u003cp\u003e**AI Hackathon,** by Ordina's Frontend Guild\u003cbr/\u003e\"Attention developers and all AI enthusiasts! Are you looking for an exciting and spontaneous challenge that will put your coding skills to the test? Then join us for a ChatGPT hackathon where you'll have two hours to create a functional and practical application using ChatGPT's natural language processing capabilities. Whether you're a seasoned developer or new to AI, this is your chance to show off your skills and creativity in a fast-paced and dynamic environment. So come as you are and see what you can accomplish with ChatGPT by your side!.\"\u003c/p\u003e \u003cp\u003e**Program:**\u003cbr/\u003e**Walk in 17:30 hrs**\u003cbr/\u003e**Grab some food and drinks 18:00 hrs**\u003cbr/\u003eStart Hackathon 18:15 hrs\u003c/p\u003e ","visibility":"public","member_pay_fee":false}],"toots":{"data":[{"id":"109318878709762915","created_at":"2022-11-10T09:48:30.790Z","url":"https://mastodon.social/@codestar/109318878709762915","text":"Join us on the 24th of november for a Robotics workshop at the Ordina office!!!\n\nFREE registration through the link below and join us for an evening with a great developer community, lots of fun and challenging\nassignments. Looking forward to seeing you there!!\n\nhttps://docs.google.com/forms/d/e/1FAIpQLScausKDt8EA1TFds04ghHKXQ2cMeJHDt019nn1X0obOD3InvA/viewform\n\nSee the trailer here: https://www.linkedin.com/posts/rickyvanrijn_azure-ros2-cloud-activity-6996406427263082496-e1fX\n\n#azure #ros2 #cloud #robotics #ordina #workshop #ros #fun","replies_count":0,"reblogs_count":1,"favourites_count":1},{"id":"109312667568153179","created_at":"2022-11-09T07:28:56.284Z","url":"https://mastodon.social/@codestar/109312667568153179","text":"Join our meetup on 1 December with @StacyClouds about #Azure Web Apps with #Blazor!\nhttps://www.meetup.com/codestar-night/events/289022760/","replies_count":0,"reblogs_count":1,"favourites_count":1}],"author":{"username":"codestar","url":"https://mastodon.social/@codestar"}},"tweets":null,"playlist":[{"id":"v8rFXbLV03Q","publishedAt":"Fri May 20 2022 08:55:14 GMT+0000 (Coordinated Universal Time)","title":"Met moderne technologie bouwen aan een duurzame software-oplossing","description":["Vandebron heeft in samenwerking met Ordina en KPN,een oplossing bedacht, waarbij de drie partijen hun kennis en expertise op het gebied van zonne-energie, software-ontwikkeling, data-connectiviteit en Internet of Things met elkaar hebben gedeeld.","","Wil jij ook ‘ahead of change’ zijn? Ga naar https://www.ordina.com voor meer informatie. ","","Meer te weten komen over Ordina? Volg dan onze socials!","LinkedIn: https://nl.linkedin.com/company/ordina ","Instagram: https://www.instagram.com/ordinabenelux/"],"thumbnails":{"default":{"url":"https://i.ytimg.com/vi/v8rFXbLV03Q/default.jpg","width":120,"height":90},"medium":{"url":"https://i.ytimg.com/vi/v8rFXbLV03Q/mqdefault.jpg","width":320,"height":180},"high":{"url":"https://i.ytimg.com/vi/v8rFXbLV03Q/hqdefault.jpg","width":480,"height":360},"standard":{"url":"https://i.ytimg.com/vi/v8rFXbLV03Q/sddefault.jpg","width":640,"height":480},"maxres":{"url":"https://i.ytimg.com/vi/v8rFXbLV03Q/maxresdefault.jpg","width":1280,"height":720}}},{"id":"yWV1eOozlOQ","publishedAt":"Tue Nov 09 2021 10:12:14 GMT+0000 (Coordinated Universal Time)","title":"Ordina Codestar at Port Of Rotterdam","description":["Our Ordina Codestar colleagues talk about their experience at the PortXchange project at the Port of Rotterdam"],"thumbnails":{"default":{"url":"https://i.ytimg.com/vi/yWV1eOozlOQ/default.jpg","width":120,"height":90},"medium":{"url":"https://i.ytimg.com/vi/yWV1eOozlOQ/mqdefault.jpg","width":320,"height":180},"high":{"url":"https://i.ytimg.com/vi/yWV1eOozlOQ/hqdefault.jpg","width":480,"height":360},"standard":{"url":"https://i.ytimg.com/vi/yWV1eOozlOQ/sddefault.jpg","width":640,"height":480},"maxres":{"url":"https://i.ytimg.com/vi/yWV1eOozlOQ/maxresdefault.jpg","width":1280,"height":720}}},{"id":"tSesmVPwKZk","publishedAt":"Wed Oct 27 2021 09:01:42 GMT+0000 (Coordinated Universal Time)","title":"Ordina's draagt bij aan duurzame doelen van Havenbedrijf Rotterdam","description":["Maatschappelijke verantwoordelijkheid en duurzaamheid wordt steeds belangrijker bij onze klanten. Wij dragen hieraan bij door versnelling te brengen in transformatieprocessen. Een voorbeeld hiervan is het project voor het Havenbedrijf Rotterdam. ","","Een duurzame oplossing voor jouw bedrijf? Ga naar https://www.ordina.com voor alle mogelijkheden.","","Meer te weten komen over Ordina? Volg dan onze socials!","LinkedIn: https://nl.linkedin.com/company/ordina ","Instagram: https://www.instagram.com/ordinabenelux/"],"thumbnails":{"default":{"url":"https://i.ytimg.com/vi/tSesmVPwKZk/default.jpg","width":120,"height":90},"medium":{"url":"https://i.ytimg.com/vi/tSesmVPwKZk/mqdefault.jpg","width":320,"height":180},"high":{"url":"https://i.ytimg.com/vi/tSesmVPwKZk/hqdefault.jpg","width":480,"height":360},"standard":{"url":"https://i.ytimg.com/vi/tSesmVPwKZk/sddefault.jpg","width":640,"height":480},"maxres":{"url":"https://i.ytimg.com/vi/tSesmVPwKZk/maxresdefault.jpg","width":1280,"height":720}}},{"id":"EaQt031BByw","publishedAt":"Tue Jun 01 2021 06:49:14 GMT+0000 (Coordinated Universal Time)","title":"Martin van Es - GraphQL for the Lazy Developer","description":["Codestar Night @ Home \"generate code.*\" from 27 May 2021","Also see https://www.meetup.com/Codestar-Night/events/277737066/","","Example application mentioned at the end: https://github.com/mdvanes/7sgraph"],"thumbnails":{"default":{"url":"https://i.ytimg.com/vi/EaQt031BByw/default.jpg","width":120,"height":90},"medium":{"url":"https://i.ytimg.com/vi/EaQt031BByw/mqdefault.jpg","width":320,"height":180},"high":{"url":"https://i.ytimg.com/vi/EaQt031BByw/hqdefault.jpg","width":480,"height":360}}},{"id":"Uq5Y080Por0","publishedAt":"Tue Jun 01 2021 06:46:30 GMT+0000 (Coordinated Universal Time)","title":"Bart Kuijper - The Power of Demystifying Your Stack","description":["Codestar Night @ Home \"generate code.*\" from 27 May 2021","Also see https://www.meetup.com/Codestar-Night/events/277737066/"],"thumbnails":{"default":{"url":"https://i.ytimg.com/vi/Uq5Y080Por0/default.jpg","width":120,"height":90},"medium":{"url":"https://i.ytimg.com/vi/Uq5Y080Por0/mqdefault.jpg","width":320,"height":180},"high":{"url":"https://i.ytimg.com/vi/Uq5Y080Por0/hqdefault.jpg","width":480,"height":360},"standard":{"url":"https://i.ytimg.com/vi/Uq5Y080Por0/sddefault.jpg","width":640,"height":480},"maxres":{"url":"https://i.ytimg.com/vi/Uq5Y080Por0/maxresdefault.jpg","width":1280,"height":720}}}]},"__N_SSG":true},"page":"/","query":{},"buildId":"UsvdpHIkUDDJ6_nTxVjoP","isFallback":false,"gsp":true,"scriptLoader":[]}</script></body></html>