<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="en">
	<title>memo.forof</title>
	<subtitle>Not longform, neither short.</subtitle>
	<link href="https://memo.forof.dev/feed/feed.xml" rel="self"/>
	<link href="https://memo.forof.dev/"/>
	<updated>2026-01-06T00:00:00Z</updated>
	<id>https://memo.forof.dev/</id>
	<author>
		<name>g</name>
		<email>g@forof.dev</email>
	</author>
	
	<entry>
		<title>So that was cool.</title>
		<link href="https://memo.forof.dev/blog/20260106/"/>
		<updated>2026-01-06T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20260106/</id>
		<content type="html">&lt;p&gt;I realized yesterday that GoodReads was spilling my therapy-assigned reading list,
SO THAT WAS GREAT! A bit of heat in my face, then deleted my 15 year old
account.&lt;/p&gt;
&lt;p&gt;Good article of the week -&amp;gt;
&lt;a href=&quot;https://lux-magazine.com/article/privacy-eroticism/&quot;&gt;https://lux-magazine.com/article/privacy-eroticism&lt;/a&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Who is attending these conferences???</title>
		<link href="https://memo.forof.dev/blog/20250927/"/>
		<updated>2025-09-27T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20250927/</id>
		<content type="html">&lt;p&gt;In this environment of tech-labor melancholy, is anybody &lt;em&gt;actually&lt;/em&gt; excited to
attend a conference centered on a SaaS? Github Universe,
Cloudfare-whatever-their-thing-is-called, etc.&lt;/p&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;Links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20250927/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://pluralistic.net/2025/08/06/unmerchantable-substitute-goods/&quot;&gt;a very nice read&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>UX vs. good sense</title>
		<link href="https://memo.forof.dev/blog/20250808/"/>
		<updated>2025-08-08T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20250808/</id>
		<content type="html">&lt;p&gt;Just a quick note. I&#39;ve been living and breathing a lot of UX ideation, and it
occurs to me that as apps infiltrate our lives (in both good ways and bad), the
UX for apps is increasingly infected by the org-chart.&lt;/p&gt;
&lt;p&gt;While doom-scrolling this morning, I saw a rare ad that interested me enough
that I clicked on it. The ad was for an audio app designed to help people focus,
somehow with &amp;quot;science&amp;quot;.&lt;/p&gt;
&lt;p&gt;I&#39;ve tried apps like it before; decent white noise.&lt;/p&gt;
&lt;p&gt;During on-boarding, I was confronted with a multiple choice quiz. Later on, when
I wanted to try out the &amp;quot;autoplay&amp;quot; feature, &lt;em&gt;another quiz&lt;/em&gt;. For an app
purportedly designed to help salve a drifting attention span, to inject these
quizes before any engagement is a fucking &lt;em&gt;insane&lt;/em&gt; UX choice. I can almost
imagine the disparate teams making these decisions without ever talking to one
another, or considering the overall impression this might make.&lt;/p&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;Links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20250808/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://pluralistic.net/2025/08/06/unmerchantable-substitute-goods/&quot;&gt;a very nice read&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>loader v. clientLoader</title>
		<link href="https://memo.forof.dev/blog/20250625/"/>
		<updated>2025-06-25T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20250625/</id>
		<content type="html">&lt;p&gt;Scenario: I want to use &lt;code&gt;clientLoader&lt;/code&gt; for &amp;quot;snappier&amp;quot; navigation in a &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/reactrouter&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;reactrouter&lt;/span&gt;&lt;/a&gt;
application, but still need to check authentication at the route. If
authentication is persisted by an HTTP-only cookie, then we can&#39;t check it from
&lt;code&gt;Request&lt;/code&gt; in a &lt;code&gt;clientLoader&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So we&#39;ll just call &lt;code&gt;serverLoader&lt;/code&gt; from &lt;code&gt;clientLoader&lt;/code&gt;, and trust that
&lt;code&gt;react-router&lt;/code&gt; will take care to reduce the number of &lt;code&gt;fetches&lt;/code&gt; per-page-load.&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; request &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Route&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;LoaderArgs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cookie &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;cookie&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; isAuthenticated &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;checkAuthentication&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// checks a cookie&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;isAuthenticated&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;User is not authenticated&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// we can call the server-side loader like so.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;clientLoader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; serverLoader &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Route&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ClientLoaderArgs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;serverLoader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;P.S.
It&#39;s best-practice to check authentication &lt;em&gt;at every route&lt;/em&gt;, rather than rely on
a wrapper route/layout.&lt;/p&gt;
&lt;p&gt;P.S.P.S&lt;/p&gt;
&lt;p&gt;Per &lt;code&gt;react-router&lt;/code&gt; documentation, you don&#39;t actually &lt;em&gt;need&lt;/em&gt; to call
&lt;code&gt;serverLoader&lt;/code&gt; unless you intend to fetch additional data &lt;em&gt;beyond&lt;/em&gt; what &lt;code&gt;loader&lt;/code&gt;
is already doing, since the framework will automatically dispatch a fetch to the
&lt;code&gt;loader&lt;/code&gt; on client navigation.&lt;/p&gt;
&lt;pre class=&quot;language-markdown&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-markdown&quot;&gt;When server rendering, loader is used for both initial page loads and client
navigations. Client navigations call the loader through an automatic fetch by
React Router from the browser to your server.&lt;/code&gt;&lt;/pre&gt;
</content>
	</entry>
	
	<entry>
		<title>1password wrecking ball</title>
		<link href="https://memo.forof.dev/blog/20250330/"/>
		<updated>2025-03-30T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20250330/</id>
		<content type="html">&lt;p&gt;An app I recently built has a degraded UX due to 1password&#39;s browser extension.
The extension is very aggressive in auto-filling any form field by rendering a
dropdown menu where the user can select a relevant auto-complete. This renders
over the top of &lt;em&gt;my&lt;/em&gt; auto-complete box.&lt;/p&gt;
&lt;div class=&quot;post-img-border&quot;&gt;
&lt;picture class=&quot;image&quot;&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://memo.forof.dev/img/b7w9kAn54l-1162.avif 1162w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://memo.forof.dev/img/b7w9kAn54l-1162.webp 1162w&quot;&gt;&lt;img src=&quot;https://memo.forof.dev/img/b7w9kAn54l-1162.png&quot; alt=&quot;an example of 1password obscuring a dropdown with its own.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1162&quot; height=&quot;440&quot;&gt;&lt;/picture&gt;
&lt;/div&gt;
&lt;p&gt;I&#39;ve punted on fixing this issue until realizing this make form UX very
difficult on small screens.&lt;/p&gt;
&lt;p&gt;The fix is to add a data-attr to &lt;code&gt;&amp;lt;input /&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;data-1p-ignore&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;post-img-border&quot;&gt;
&lt;picture class=&quot;image&quot;&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://memo.forof.dev/img/-4xD1JVSur-700.avif 700w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://memo.forof.dev/img/-4xD1JVSur-700.webp 700w&quot;&gt;&lt;img src=&quot;https://memo.forof.dev/img/-4xD1JVSur-700.png&quot; alt=&quot;After the fix, the form looks right.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;700&quot; height=&quot;422&quot;&gt;&lt;/picture&gt;
&lt;/div&gt;
&lt;p&gt;I&#39;ll likely need to extend similar fixes for other password managers as well,
but 1password&#39;s subversion of intended UX is particularly egregious.&lt;/p&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;Links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20250330/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.1password.com/docs/web/compatible-website-design/&quot;&gt;https://developer.1password.com/docs/web/compatible-website-design/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>notes from underground</title>
		<link href="https://memo.forof.dev/blog/20250120/"/>
		<updated>2025-01-20T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20250120/</id>
		<content type="html">&lt;h1 id=&quot;vite&quot; tabindex=&quot;-1&quot;&gt;vite &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20250120/#vite&quot;&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/vite&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;vite&lt;/span&gt;&lt;/a&gt; is the defacto JS bundler now. It contains a useful feature for build-time
configuration using environment variables via &lt;code&gt;import.meta.env&lt;/code&gt;, by which you
can serialize variables that begin with &lt;code&gt;VITE_&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;An obvious outcome is that this is &lt;em&gt;build time only&lt;/em&gt;, which means that accessing
runtime configuration via &lt;code&gt;VITE_&lt;/code&gt; variables is useless if you&#39;re building
&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/docker&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;docker&lt;/span&gt;&lt;/a&gt; containers to deploy to multiple environments. e.g. a variable called
&lt;code&gt;VITE_API&lt;/code&gt;, where one might set &lt;code&gt;localhost:123&lt;/code&gt; vs. &lt;code&gt;api.domain.com&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This completely makes sense, but it is a bit of a drag. Call me old-school, but
I still think the same artifacts should be deployed across environments,
modified by runtime configuration.&lt;/p&gt;
&lt;h1 id=&quot;trump&quot; tabindex=&quot;-1&quot;&gt;trump &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20250120/#trump&quot;&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;My well of surprise/disappointment/etc is dry-as-a-bone, but I&#39;m still mildly
surprised to see the posting optimism about the incoming administration. My
primary memory of the last Trump administration is that it ended with Covid, and
that Trump
&lt;a href=&quot;https://apnews.com/article/donald-trump-ap-top-news-virus-outbreak-barack-obama-public-health-ce014d94b64e98b7203b873e56f80e9a&quot;&gt;dissolved&lt;/a&gt;
a government function to combat pandemics.&lt;/p&gt;
&lt;p&gt;&lt;picture class=&quot;image&quot;&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://memo.forof.dev/img/HjTEZOrfPD-773.avif 773w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://memo.forof.dev/img/HjTEZOrfPD-773.webp 773w&quot;&gt;&lt;img src=&quot;https://memo.forof.dev/img/HjTEZOrfPD-773.jpeg&quot; alt=&quot;color blind? try being regular blind.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;773&quot; height=&quot;1105&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>a few snaps</title>
		<link href="https://memo.forof.dev/blog/20241230/"/>
		<updated>2024-12-30T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241230/</id>
		<content type="html">&lt;p&gt;&lt;picture class=&quot;image&quot;&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://memo.forof.dev/img/nhOAMEfcT5-4032.avif 4032w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://memo.forof.dev/img/nhOAMEfcT5-4032.webp 4032w&quot;&gt;&lt;img src=&quot;https://memo.forof.dev/img/nhOAMEfcT5-4032.jpeg&quot; alt=&quot;someone killed this crow, and it made me sad.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;4032&quot; height=&quot;3024&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;I found this dead crow. The blood-from-the-beak indicates poisoning by
rodenticide. A coward&#39;s solution.&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;picture class=&quot;image&quot;&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://memo.forof.dev/img/-mtsjXnZUP-4032.avif 4032w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://memo.forof.dev/img/-mtsjXnZUP-4032.webp 4032w&quot;&gt;&lt;img src=&quot;https://memo.forof.dev/img/-mtsjXnZUP-4032.jpeg&quot; alt=&quot;deer congregating near a grave-site.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;4032&quot; height=&quot;3024&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;I saw these while visiting my step-father&#39;s grave.&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;picture class=&quot;image&quot;&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://memo.forof.dev/img/d0p3ajVlZL-3755.avif 3755w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://memo.forof.dev/img/d0p3ajVlZL-3755.webp 3755w&quot;&gt;&lt;img src=&quot;https://memo.forof.dev/img/d0p3ajVlZL-3755.jpeg&quot; alt=&quot;oliver sunning himself.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;3755&quot; height=&quot;2816&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;My blind cat, sunning himself.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>eslint vs. react-router</title>
		<link href="https://memo.forof.dev/blog/20241222/"/>
		<updated>2024-12-22T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241222/</id>
		<content type="html">&lt;p&gt;Mildly embarrassed thinking about how long I thrashed on this...&lt;/p&gt;
&lt;p&gt;After creating a bee-u-tiful &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/eslint&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;eslint&lt;/span&gt;&lt;/a&gt; configuration, running it on my project,
ensuring it hooked up to my editor etc.&lt;/p&gt;
&lt;p&gt;Lint began failing when executed in CI. This left me so completely vexed that I
dusted off my Fedora laptop to see if it was some arcane difference between
MacOS and Linux.&lt;/p&gt;
&lt;p&gt;It wasn&#39;t.&lt;/p&gt;
&lt;p&gt;I realized that &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/rr7&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;rr7&lt;/span&gt;&lt;/a&gt; needs to generate types &lt;em&gt;before&lt;/em&gt; lint runs, or it
rightfully explodes.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// package.json
{
  ...

  &amp;quot;scripts&amp;quot;: {
    &amp;quot;check:lint&amp;quot;: &amp;quot;react-router typegen &amp;amp;&amp;amp; eslint .&amp;quot;,
  }
}

&lt;/code&gt;&lt;/pre&gt;
</content>
	</entry>
	
	<entry>
		<title>React Router v7 and Vitest</title>
		<link href="https://memo.forof.dev/blog/20241216-1/"/>
		<updated>2024-12-16T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241216-1/</id>
		<content type="html">&lt;p&gt;Wiring up &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/vitest&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;vitest&lt;/span&gt;&lt;/a&gt; and &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/rr7&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;rr7&lt;/span&gt;&lt;/a&gt; for tests is not obvious.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Requires a separate &lt;code&gt;vitest.config.ts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Requires &lt;code&gt;createRoutesStub&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://discord.com/channels/770287896669978684/1317279587603845153/1317279587603845153&quot;&gt;discord&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;vitest-config-ts&quot; tabindex=&quot;-1&quot;&gt;vitest.config.ts: &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241216-1/#vitest-config-ts&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We need a separate &lt;code&gt;vite.config&lt;/code&gt; that omits &lt;code&gt;@react-router/dev/vite&lt;/code&gt;, and then
configures the typical &lt;code&gt;test&lt;/code&gt; features.&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; react &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@vitejs/plugin-react&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; autoprefixer &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;autoprefixer&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; tailwindcss &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;tailwindcss&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; defineConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; loadEnv &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;vite&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; tsconfigPaths &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;vite-tsconfig-paths&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// -----------------------------------------------------------------------------&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;defineConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  css&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    postcss&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      plugins&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;tailwindcss&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; autoprefixer&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// using `@vitejs/plugin-react` instead of `@react-router/dev/vite`&lt;/span&gt;
  plugins&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;react&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;tsconfigPaths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  test&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    env&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loadEnv&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cwd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    environment&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;happy-dom&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// @NOTE: https://testing-library.com/docs/react-testing-library/setup#auto-cleanup-in-vitest&lt;/span&gt;
    setupFiles&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;./vite.cleanup.ts&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;a-test&quot; tabindex=&quot;-1&quot;&gt;A test: &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241216-1/#a-test&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now, we need to use &lt;code&gt;createRoutesStub&lt;/code&gt; anywhere a component renders anything to
do with &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/reactrouter&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;reactrouter&lt;/span&gt;&lt;/a&gt;. Alternatively, we could build a &amp;quot;wrapper&amp;quot; utility,
similar to mocking a &lt;code&gt;redux&lt;/code&gt; provider, but in practice we&#39;ll be passing
&lt;code&gt;createRoutesStub&lt;/code&gt; to a wrapper utility anyways.&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; userEvent &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@testing-library/user-event&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Link &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;react-router&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; createRoutesStub &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;react-router&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; render&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; screen&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; waitFor &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@testing-library/react&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; test &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;vitest&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// -----------------------------------------------------------------------------&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Welcome&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Link to&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/login&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Log In&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Link&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Success&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;you did it&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Welcome screen navigates to /login&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Stub &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createRoutesStub&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Component&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Welcome&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; path&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Component&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Success&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; path&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/login&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Stub &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; userEvent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;screen&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getByText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Log In&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;waitFor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; screen&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findByText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;you did it!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
</content>
	</entry>
	
	<entry>
		<title>React Router v7 actions()</title>
		<link href="https://memo.forof.dev/blog/20241213-1/"/>
		<updated>2024-12-13T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241213-1/</id>
		<content type="html">&lt;p&gt;Also known as &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/remix&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;remix&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;throw&lt;/code&gt; from actions will naturally be caught by the nearest &lt;code&gt;ErrorBoundary&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Route.ComponentProps[&#39;actionData&#39;]&lt;/code&gt; is only useful client-side. Don&#39;t spend
x-minutes wondering why your console.log insists on being undefined.&lt;/li&gt;
&lt;li&gt;Instead of throwing from an action, you can &lt;code&gt;try/catch&lt;/code&gt; and return &lt;code&gt;data()&lt;/code&gt;
with a &lt;code&gt;status: 400&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-javascript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; request &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Route&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ActionArgs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; formData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;formData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; emailAddress &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; formData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;email_address&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; emailAddress &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Expected a string value, but received a File.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; validEmailAddress &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; z&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;emailAddress&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;someSideEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;validEmailAddress&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// like authentication&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; emailAddress &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error &lt;span class=&quot;token keyword&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ZodError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; emailAddress&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;validation&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;400&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; emailAddress&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;unknown&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;400&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Route&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  loaderData&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  actionData&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Route&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ComponentProps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// @NOTE: actionData only exists client-side&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;actionData&lt;span class=&quot;token operator&quot;&gt;?.&lt;/span&gt;ok &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;hooray&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Form method&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;post&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input
          name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;email_address&quot;&lt;/span&gt;
          placeholder&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Email address&quot;&lt;/span&gt;
          required type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;email&quot;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;submit&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;button&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Form&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;notes&quot; tabindex=&quot;-1&quot;&gt;Notes &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241213-1/#notes&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;I think it is &lt;em&gt;bizarre&lt;/em&gt; that &lt;code&gt;react-router&lt;/code&gt; documentation uses &lt;code&gt;let&lt;/code&gt;
everywhere.&lt;/li&gt;
&lt;li&gt;It&#39;s also weird to &lt;code&gt;throw&lt;/code&gt; their &lt;code&gt;redirect&lt;/code&gt; from actions. That ain&#39;t an error.&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>mat missive.</title>
		<link href="https://memo.forof.dev/blog/20241212-1/"/>
		<updated>2024-12-12T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241212-1/</id>
		<content type="html">&lt;h2 id=&quot;a-checkpoint&quot; tabindex=&quot;-1&quot;&gt;a checkpoint &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241212-1/#a-checkpoint&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I received my BJJ brown belt last night.&lt;/p&gt;
&lt;p&gt;&lt;picture class=&quot;image&quot;&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://memo.forof.dev/img/0KYam5z2IC-960.avif 960w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://memo.forof.dev/img/0KYam5z2IC-960.webp 960w&quot;&gt;&lt;img src=&quot;https://memo.forof.dev/img/0KYam5z2IC-960.jpeg&quot; alt=&quot;a brown belt&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;960&quot; height=&quot;1280&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;h2 id=&quot;aside&quot; tabindex=&quot;-1&quot;&gt;aside &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241212-1/#aside&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;ve nothing particularly caffeinated to add to the &amp;quot;discourse&amp;quot; on the subject
of measuring the productive output of a software engineer, but I continue to be
bemused by the various attempts maximizevalueextraction.biz like &lt;code&gt;DORA&lt;/code&gt;, &lt;code&gt;SPACE&lt;/code&gt;,
&lt;code&gt;DEVEX&lt;/code&gt; et al.&lt;/p&gt;
&lt;p&gt;Imagine a framework for measuring the delusions of these biz-analysis freaks.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>tmux etc.</title>
		<link href="https://memo.forof.dev/blog/20241211/"/>
		<updated>2024-12-11T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241211/</id>
		<content type="html">&lt;h2 id=&quot;tmux&quot; tabindex=&quot;-1&quot;&gt;tmux &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241211/#tmux&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I get weird about multiple tabs and splits in my workflow, and I &lt;em&gt;really&lt;/em&gt; like
to have the same layout across &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/tmux&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;tmux&lt;/span&gt;&lt;/a&gt; sessions.&lt;/p&gt;
&lt;p&gt;In the distant-in-dog-years past, I spend too many hours building custom layout
templates, etc, but have since given up &lt;code&gt;tmux&lt;/code&gt; as a hobby. Now, I just hit
&lt;code&gt;prefix&lt;/code&gt; and then smash &lt;code&gt;&amp;lt;SPACE&amp;gt;&lt;/code&gt; until the layout looks nice enough.&lt;/p&gt;
&lt;p&gt;However... When I have a giant screen, e.g. &lt;code&gt;3840 x 2160&lt;/code&gt;, the layouts look
weird to me. So, back to scripting:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# $HOME/.config/tmux/big-split.sh&lt;/span&gt;

&lt;span class=&quot;token assign-left variable&quot;&gt;TERMINAL_WIDTH&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;tmux display-message &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#{window_width}&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;TERMINAL_HEIGHT&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;tmux display-message &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#{window_height}&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;PERCENTAGE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;70&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;OFFSET&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;PANE_WIDTH&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;TERMINAL_WIDTH &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; PERCENTAGE &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; OFFSET&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt;

tmux split-window &lt;span class=&quot;token parameter variable&quot;&gt;-h&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-l&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$PANE_WIDTH&lt;/span&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then a small amendment to &lt;code&gt;tmux.conf&lt;/code&gt; so that I can set the layout with
&lt;code&gt;:bigsplit&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# $HOME/.config/tmux/tmux.conf

set -g command-alias[0] bigsplit=&amp;quot;run-shell &#39;$HOME/.config/tmux/big-split.sh&#39;&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;picture class=&quot;image&quot;&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://memo.forof.dev/img/qgLqA1F8MR-3820.avif 3820w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://memo.forof.dev/img/qgLqA1F8MR-3820.webp 3820w&quot;&gt;&lt;img src=&quot;https://memo.forof.dev/img/qgLqA1F8MR-3820.png&quot; alt=&quot;this is my terminal&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;3820&quot; height=&quot;2082&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>The c9 fiasco</title>
		<link href="https://memo.forof.dev/blog/20241126-2/"/>
		<updated>2024-11-26T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241126-2/</id>
		<content type="html">&lt;p&gt;&lt;a href=&quot;https://tru-tone.com/&quot;&gt;These&lt;/a&gt; look good, but putting them up sucks.&lt;/p&gt;
&lt;p&gt;&lt;picture class=&quot;image&quot;&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://memo.forof.dev/img/oSnhdimRan-960.avif 960w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://memo.forof.dev/img/oSnhdimRan-960.webp 960w&quot;&gt;&lt;img src=&quot;https://memo.forof.dev/img/oSnhdimRan-960.jpeg&quot; alt=&quot;these fuckers...&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;960&quot; height=&quot;1280&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>NextJS, but probably not</title>
		<link href="https://memo.forof.dev/blog/20241126-1/"/>
		<updated>2024-11-26T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241126-1/</id>
		<content type="html">&lt;p&gt;Wading back into the JS framework pool. Though I&#39;ve been building quite a few
side-projects recently using a variety of approaches (Deno, Hono, Fresh, etc.),
those projects are &lt;em&gt;all&lt;/em&gt; to my own peculiar taste.&lt;/p&gt;
&lt;p&gt;The calculations change when building an application that someone else is paying
for, and particularly if that application needs to be supported long-term by a
team of varied skill-sets and expertises. &lt;a href=&quot;https://www.youtube.com/watch?v=kLQaJUMtma8&quot;&gt;Peril
avoided&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The framework du jour is inarguably &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/nextjs&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;nextjs&lt;/span&gt;&lt;/a&gt;. It&#39;s an unavoidable &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/react&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;react&lt;/span&gt;&lt;/a&gt;-ism, and &lt;em&gt;has&lt;/em&gt; to be
considered.&lt;/p&gt;
&lt;p&gt;But, context. &lt;code&gt;gcp&lt;/code&gt; and &lt;code&gt;cloudrun&lt;/code&gt; is where this application will be deployed,
which is, evidently, &lt;em&gt;hard&lt;/em&gt; with NextJS. While there will always be an &amp;quot;ahem,
actually&amp;quot;, anecdote, blog post, and conversation seem to converge on the point
that NextJS just &lt;em&gt;doesn&#39;t&lt;/em&gt; work as well unless you&#39;re deploying to Vercel. This
seems doubly reinforced by the existence of
&lt;a href=&quot;https://opennext.js.org/&quot;&gt;shim-projects&lt;/a&gt; to leverage bespoke features of NextJS
in non-Vercel clouds.&lt;/p&gt;
&lt;p&gt;My hesitation also relates to &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/wordpress&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;wordpress&lt;/span&gt;&lt;/a&gt;, and chaos currently visible in &lt;em&gt;that&lt;/em&gt;
developer community, due to commercial strong-arming by wordpress.com.&lt;/p&gt;
&lt;p&gt;Then there&#39;s &lt;a href=&quot;https://www.epicweb.dev/why-i-wont-use-nextjs&quot;&gt;this&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So I&#39;ll be looking pretty hard at &lt;code&gt;react-router&lt;/code&gt; v7 instead...
&lt;a href=&quot;https://leejjon.medium.com/streaming-with-remix-on-google-cloud-platform-app-engine-flex-cloud-run-4e3e16b8c68d&quot;&gt;Signs&lt;/a&gt;
point to it working well from &lt;code&gt;gcp&lt;/code&gt;.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Chapter, end.</title>
		<link href="https://memo.forof.dev/blog/20241114/"/>
		<updated>2024-11-14T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241114/</id>
		<content type="html">&lt;p&gt;Tomorrow is my last day with my current company. I just want to note that, here.&lt;/p&gt;
&lt;p&gt;Late-winter, 2018, only so many people that you could count us with a single
hand. Up to much larger headcount, acquisition, and sun-setting.&lt;/p&gt;
&lt;p&gt;A job is a job is a job, but I&#39;ve been in this one chair for long enough that it
just has me feeling nostalgic.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>postgres.app</title>
		<link href="https://memo.forof.dev/blog/20241110/"/>
		<updated>2024-11-10T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241110/</id>
		<content type="html">&lt;p&gt;If you&#39;re using macOS, just use &lt;a href=&quot;https://postgres.app/&quot;&gt;postgres.app&lt;/a&gt; -
&lt;code&gt;homebrew&lt;/code&gt; installations of &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/postgres&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;postgres&lt;/span&gt;&lt;/a&gt; are too much heartache.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(or use a containerized postgres)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Be sure to add &lt;code&gt;psql&lt;/code&gt; to &lt;code&gt;$PATH&lt;/code&gt; in &lt;code&gt;.zshrc&lt;/code&gt; or whichever flavor you&#39;re using:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PATH=&amp;quot;/Applications/Postgres.app/Contents/Versions/latest/bin:$PATH&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
</content>
	</entry>
	
	<entry>
		<title>hono ohno</title>
		<link href="https://memo.forof.dev/blog/20241106/"/>
		<updated>2024-11-06T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241106/</id>
		<content type="html">&lt;p&gt;A few notes on &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/hono&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;hono&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you install &lt;a href=&quot;https://hono.dev/&quot;&gt;&lt;code&gt;hono&lt;/code&gt;&lt;/a&gt; from &lt;a href=&quot;https://jsr.io/&quot;&gt;&lt;code&gt;jsr&lt;/code&gt;&lt;/a&gt;, using
hono extensions from &lt;code&gt;npm&lt;/code&gt; will not work, e.g.
&lt;a href=&quot;https://www.npmjs.com/package/@hono/zod-validator&quot;&gt;&lt;code&gt;@hono/zod-validator&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you&#39;re &lt;code&gt;curl&lt;/code&gt;ing and stuff is weird (&lt;code&gt;validator(&amp;quot;json&amp;quot;, ...)&lt;/code&gt;), probably
forgot to add &lt;code&gt;-H &amp;quot;Content-Type: application/json&amp;quot;&lt;/code&gt;.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Dang, it&#39;s already November</title>
		<link href="https://memo.forof.dev/blog/20241104/"/>
		<updated>2024-11-04T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241104/</id>
		<content type="html">&lt;p&gt;...And it&#39;s this kind of November. America, an anxiety disorder. Violent
backlash almost certain, varietals both comic and tragic.&lt;/p&gt;
&lt;p&gt;&lt;picture class=&quot;gif&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://memo.forof.dev/img/Xgk9Vtq34s-448.webp 448w&quot;&gt;&lt;img src=&quot;https://memo.forof.dev/img/Xgk9Vtq34s-448.gif&quot; alt=&quot;gag&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;448&quot; height=&quot;354&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;Something entirely unrelated. &lt;code&gt;eslint&lt;/code&gt; version 9.&lt;/p&gt;
&lt;h2 id=&quot;upgrading-eslint-or-make-work&quot; tabindex=&quot;-1&quot;&gt;Upgrading &lt;code&gt;eslint&lt;/code&gt;, or &amp;quot;make-work&amp;quot; &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241104/#upgrading-eslint-or-make-work&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I love tooling. &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/eslint&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;eslint&lt;/span&gt;&lt;/a&gt; has been ubiquitous for so long, the standard and the
standard. But OSS is evolve or die, and sometimes both.&lt;/p&gt;
&lt;p&gt;The upgrade path between &lt;code&gt;eslint&lt;/code&gt; 8 -&amp;gt; 9 is rocky enough that it simply doesn&#39;t
look worth the squeeze, to me. For a new project, the choice is obvious (9), but
I&#39;ve had little success using the migration tools.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npx @eslint/migrate-config .eslintrc.json&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;attempts&quot; tabindex=&quot;-1&quot;&gt;Attempts &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241104/#attempts&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Given the scope of linting configuration, I&#39;m probably better off declaring
linter bankruptcy and simply starting over. Yeah, that&#39;s it, this is make-work.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// @ts-check&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; eslint &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;@eslint/js&#39;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; tseslint &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;typescript-eslint&#39;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; tseslint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  eslint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;configs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;recommended&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;tseslint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;configs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;recommended&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;tseslint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;configs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;recommendedTypeChecked&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;rules&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&#39;@typescript-eslint/no-unsafe-assignment&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;warn&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string-property property&quot;&gt;&#39;@typescript-eslint/no-unused-vars&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&#39;warn&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;argsIgnorePattern&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;^_&#39;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;languageOptions&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;parserOptions&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;projectService&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;tsconfigRootDir&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dirname&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;**/*.js&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;**/*.mjs&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;tseslint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;configs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;disableTypeChecked&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;text-editing&quot; tabindex=&quot;-1&quot;&gt;Text editing &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241104/#text-editing&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Given the advent of &lt;code&gt;mjs&lt;/code&gt; and &lt;code&gt;cjs&lt;/code&gt;, make sure your tooling recognizes those
file extensions when looking for configuration files.&lt;/p&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;Links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241104/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@eslint/migrate-config&quot;&gt;@eslint/migrate-config&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://typescript-eslint.io/&quot;&gt;typescript-eslint&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>Beefed-up 5-alarm chili beans, and quick</title>
		<link href="https://memo.forof.dev/blog/20241028-2/"/>
		<updated>2024-10-28T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241028-2/</id>
		<content type="html">&lt;p&gt;Wanted cornbread, needed chili. A &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/recipe&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;recipe&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Convey thyself to the supermarket.&lt;/li&gt;
&lt;li&gt;Grab 1 lbs meat, likely beef.&lt;/li&gt;
&lt;li&gt;2 cans beans, likely pinto.&lt;/li&gt;
&lt;li&gt;4 cans hatch chile. The little yellow cans.&lt;/li&gt;
&lt;li&gt;You know what you like. Grab some other chili adjacent ingredients. Probably
a white onion for dicing. Tomato paste. You have chili powder at home, yeah?
Shredded cheese. Crushed tomatoes or diced, even sauce? No sauce, but get a can
anyways. Garlic... A red pepper. So strange that they lock the laundry detergent
up now. There&#39;s not many people here, this time of night. Get followed around by
3 security guards, conspicuous in their plate carriers.&lt;/li&gt;
&lt;li&gt;Allons-y, and mise en place. This is quick chili.&lt;/li&gt;
&lt;li&gt;Brown the meat. Freestyle a bit. Various powders and spices.&lt;/li&gt;
&lt;li&gt;Tomato paste, into the stew.&lt;/li&gt;
&lt;li&gt;Etc. This isn&#39;t a soup. Use the too-expensive salt to season.&lt;/li&gt;
&lt;li&gt;Forget to prepare the cornbread. This is less-than-quick chili now.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;picture class=&quot;image&quot;&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://memo.forof.dev/img/heebjEzBpC-3647.avif 3647w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://memo.forof.dev/img/heebjEzBpC-3647.webp 3647w&quot;&gt;&lt;img src=&quot;https://memo.forof.dev/img/heebjEzBpC-3647.jpeg&quot; alt=&quot;mostly-canned ingredients&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;3647&quot; height=&quot;2051&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>SentryBoy</title>
		<link href="https://memo.forof.dev/blog/20241028-1/"/>
		<updated>2024-10-28T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241028-1/</id>
		<content type="html">&lt;p&gt;I&#39;ve been wondering why my fly machines weren&#39;t auto-suspending after I added
&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/sentry&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;sentry&lt;/span&gt;&lt;/a&gt; to a project. From the logs, I could see &lt;code&gt;/&lt;/code&gt; was being requested every
second... Smells like a bot.&lt;/p&gt;
&lt;p&gt;So I added more logging to catch the user-agent from request headers, and was
surprised to see the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;user-agent: SentryUptimeBot/1.0 (+http://docs.sentry.io/product/alerts/uptime-monitoring/)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I guess &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/sentry&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;sentry&lt;/span&gt;&lt;/a&gt; has a new feature (beta) that does a healthcheck on URLs that
have thrown exceptions. I need to read the docs more closely, but a &lt;code&gt;GET&lt;/code&gt; every
second seems a bit excessive. To disable it, I just revised my robots.txt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;User-agent: SentryUptimeBot
Disallow: *
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;Links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241028-1/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.sentry.io/product/alerts/uptime-monitoring/&quot;&gt;https://docs.sentry.io/product/alerts/uptime-monitoring&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>GenServers and Phoenix.PubSubs and Task.Supervisors</title>
		<link href="https://memo.forof.dev/blog/20241026/"/>
		<updated>2024-10-26T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241026/</id>
		<content type="html">&lt;p&gt;I&#39;ve been looking for an &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/elixir&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;elixir&lt;/span&gt;&lt;/a&gt; &lt;code&gt;redux&lt;/code&gt;-alike (primarly the event-bus stuff),
and have found that &lt;code&gt;Phoenix.PubSub&lt;/code&gt; paired with a &lt;code&gt;GenServer&lt;/code&gt; and a &lt;code&gt;Task&lt;/code&gt;
supervisor seems to get the job done.&lt;/p&gt;
&lt;p&gt;I did chase a few different constructions, like using &lt;code&gt;Task.start&lt;/code&gt; with
callbacks, but found that &lt;code&gt;GenServer&lt;/code&gt; doesn&#39;t have a predicable state when
callbacks are executed.&lt;/p&gt;
&lt;p&gt;The following is scratched out, as there&#39;s opportunity to make it a bit more
generic, like sending messages back to the original caller, etc.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;objective&lt;/em&gt;: Schedule async work that can crash.&lt;/p&gt;
&lt;pre class=&quot;language-elixir&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;token module class-name&quot;&gt;MyApp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;Dispatcher&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token module class-name&quot;&gt;GenServer&lt;/span&gt;

  &lt;span class=&quot;token attribute variable&quot;&gt;@topic&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;MY_TOPIC&quot;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;start_link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token module class-name&quot;&gt;GenServer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;start_link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__MODULE__&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name:&lt;/span&gt; __MODULE__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;&#92;&#92;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# subscribe to events emitted elsewhere&lt;/span&gt;
    &lt;span class=&quot;token module class-name&quot;&gt;Phoenix&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;PubSub&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;MyApp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;PubSub&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attribute variable&quot;&gt;@topic&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Start a Task.Supervisor&lt;/span&gt;
    &lt;span class=&quot;token module class-name&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;Supervisor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;start_link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;token module class-name&quot;&gt;MyApp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;Dispatcher&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;TaskSupervisor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# handle messages sent from dispatched tasks&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handle_info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:DOWN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _ref&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:process&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pid&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _reason&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    next &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token module class-name&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pid&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# broadcast that a task is complete&lt;/span&gt;
    &lt;span class=&quot;token module class-name&quot;&gt;PubSub&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;broadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;MyApp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;PubSub&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attribute variable&quot;&gt;@topic&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:tasks&lt;/span&gt;?&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:noreply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handle_info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;_event&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;id:&lt;/span&gt; _id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; msg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    task &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
      &lt;span class=&quot;token module class-name&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;Supervisor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;async_nolink&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;MyApp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;Dispatcher&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;TaskSupervisor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# doing something async. It may or may not crash&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# For instance, maybe this does a database write&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:noreply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token module class-name&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; task&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pid&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; task&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handle_info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:noreply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
</content>
	</entry>
	
	<entry>
		<title>Reader modes are insane</title>
		<link href="https://memo.forof.dev/blog/20241025/"/>
		<updated>2024-10-25T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241025/</id>
		<content type="html">&lt;p&gt;I&#39;ve been fiddling with content extraction using
&lt;a href=&quot;https://github.com/mozilla/readability/&quot;&gt;@mozilla/readability&lt;/a&gt;. As a
data-source, what better candidate than this very-here website, so I made some
revisions.&lt;/p&gt;
&lt;p&gt;The basic question is &amp;quot;what components must my webpage have in order to trigger
reader mode&amp;quot;. Surely, this is standardized.&lt;/p&gt;
&lt;p&gt;Well... extremely no, it seems. Having done some reading, the best I&#39;ve come up
with is that adding schema attributes won&#39;t &lt;em&gt;hurt&lt;/em&gt; anything, but the ways in
which browser reader modes parse content is highly eccentric. For instance, the
following qualifies for reader mode using Firefox, but &lt;code&gt;@mozilla/readability&lt;/code&gt;
fails to extract a &lt;code&gt;publishedTime&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;article&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;itemscope&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;itemtype&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://schema.org/Article&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;post-title&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;itemprop&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;headline&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Reader modes are insane&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;time&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;2024-10-25&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;itemprop&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;datePublished&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      2024-10-25
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;section&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;post-content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;itemprop&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;articleBody&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;...&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;section&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;article&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;Links: &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241025/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ctrl.blog/entry/browser-reading-mode-parsers.html&quot;&gt;https://www.ctrl.blog/entry/browser-reading-mode-parsers.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://schema.org/Article&quot;&gt;https://schema.org/Article&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>component libraries</title>
		<link href="https://memo.forof.dev/blog/20241023/"/>
		<updated>2024-10-23T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241023/</id>
		<content type="html">&lt;p&gt;A non-comprehensive list of &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/component&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;component&lt;/span&gt;&lt;/a&gt; libraries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.chakra-ui.com/&quot;&gt;Chakra&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://daisyui.com/&quot;&gt;DaisyUI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://flowbite.com/&quot;&gt;Flowbite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kuma-ui.com/&quot;&gt;Kuma UI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mui.com/material-ui/&quot;&gt;MUI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mantine.dev/&quot;&gt;Mantine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nextui.org/&quot;&gt;NextUI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://semantic-ui.com/&quot;&gt;Semantic UI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ui.shadcn.com/&quot;&gt;Shadcn/ui&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://shoelace.style/&quot;&gt;Shoelace&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>elixir-ls bozo-mode</title>
		<link href="https://memo.forof.dev/blog/20241022/"/>
		<updated>2024-10-22T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241022/</id>
		<content type="html">&lt;p&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/neovim&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;neovim&lt;/span&gt;&lt;/a&gt; &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/elixir&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;elixir&lt;/span&gt;&lt;/a&gt; formatter got you down? As in, not working no-sir?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Unable to find formatter for /path/to/file.exs:
** (Mix.Error) Formatter plugin Phoenix.LiveView.HTMLFormatter cannot be found
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fix:&lt;/p&gt;
&lt;pre class=&quot;language-zsh&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-zsh&quot;&gt;$ rm .elixir-ls/build&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;Links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241022/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://elixirforum.com/t/elixirls-stopped-working-unable-to-find-formatter/59412/23&quot;&gt;https://elixirforum.com/t/elixirls-stopped-working-unable-to-find-formatter/59412/23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/elixir-lsp/elixir-ls/issues/1110&quot;&gt;https://github.com/elixir-lsp/elixir-ls/issues/1110&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>neovim messages</title>
		<link href="https://memo.forof.dev/blog/20241021/"/>
		<updated>2024-10-21T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241021/</id>
		<content type="html">&lt;p&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/neovim&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;neovim&lt;/span&gt;&lt;/a&gt; messages are often hard to grab. If you see an error near the
status-line, print it out with &lt;code&gt;:messages&lt;/code&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>docker, nginx, and root</title>
		<link href="https://memo.forof.dev/blog/20241018/"/>
		<updated>2024-10-18T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241018/</id>
		<content type="html">&lt;p&gt;Need &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/nginx&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;nginx&lt;/span&gt;&lt;/a&gt; to run as non-root? Just use the unprivileged &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/docker&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;docker&lt;/span&gt;&lt;/a&gt; image.&lt;/p&gt;
&lt;pre class=&quot;language-dockerfile&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; nginxinc/nginx-unprivileged:1.27.2-alpine&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; ./my-html    /usr/share/nginx/html/&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; ./nginx.conf /etc/nginx/nginx.conf&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since non-root can&#39;t use &lt;code&gt;:80&lt;/code&gt;, the above image defaults to &lt;code&gt;:8080&lt;/code&gt;, so any
&lt;code&gt;nginx&lt;/code&gt; configuration will need to reflect that, as well as any other
infrastructure, like &lt;code&gt;istio&lt;/code&gt; or &lt;code&gt;kubernetes&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-nginx&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-nginx&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# nginx.conf&lt;/span&gt;

&lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;worker_processes&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;pid&lt;/span&gt;               /tmp/nginx.pid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;events&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;worker_connections&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;http&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;Links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241018/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/nginxinc/nginx-unprivileged&quot;&gt;https://hub.docker.com/r/nginxinc/nginx-unprivileged&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/@Kfir-G/securing-docker-non-root-user-best-practices-5784ac25e755&quot;&gt;https://medium.com/@Kfir-G/securing-docker-non-root-user-best-practices-5784ac25e755&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html&quot;&gt;https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>GenServer and concurrency</title>
		<link href="https://memo.forof.dev/blog/20241017/"/>
		<updated>2024-10-17T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241017/</id>
		<content type="html">&lt;p&gt;I&#39;ve built a &lt;code&gt;GenServer&lt;/code&gt; pub/sub to handle async effects from my &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/phoenix&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;phoenix&lt;/span&gt;&lt;/a&gt;
application, but have been wondering how it handles multiple broadcasts. Given
that a &lt;code&gt;GenServer&lt;/code&gt; processes messages from a queue, how can I concurrently handle
those messages.&lt;/p&gt;
&lt;p&gt;Answer: by dispatching to &lt;code&gt;Task&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;language-elixir&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;token module class-name&quot;&gt;Subscriber&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;token module class-name&quot;&gt;GenServer&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token module class-name&quot;&gt;Handler&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;start_link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_opts&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token module class-name&quot;&gt;GenServer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;start_link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__MODULE__&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name:&lt;/span&gt; __MODULE__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token attribute variable&quot;&gt;@impl&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token module class-name&quot;&gt;Phoenix&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;PubSub&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;MyPubSub&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;my-topic&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token attribute variable&quot;&gt;@impl&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handle_info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;msg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Task.start for fire-and-forget&lt;/span&gt;
    &lt;span class=&quot;token module class-name&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token module class-name&quot;&gt;Handler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:handle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;msg&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:noreply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;token module class-name&quot;&gt;Handler&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;url:&lt;/span&gt; url &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Maybe this is an API request to another service&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;url:&lt;/span&gt; url &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;Links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241017/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://elixirforum.com/t/whats-the-best-pattern-for-a-pubsub-event-listener-genserver-seems-like-the-wrong-choice/35703&quot;&gt;https://elixirforum.com/t/whats-the-best-pattern-for-a-pubsub-event-listener-genserver-seems-like-the-wrong-choice/35703&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>robots.txt and AI crawlers</title>
		<link href="https://memo.forof.dev/blog/20241016/"/>
		<updated>2024-10-16T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241016/</id>
		<content type="html">&lt;h2 id=&quot;staaaaahp&quot; tabindex=&quot;-1&quot;&gt;staaaaahp &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241016/#staaaaahp&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Trying a variety of incantations to block the &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/ai&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;ai&lt;/span&gt;&lt;/a&gt; crawlers, though it&#39;ll take
constant revision. May build a lil&#39; generator for it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;User-agent: GPTBot
Disallow: /
User-agent: ChatGPT-User
Disallow: /
User-agent: Google-Extended
Disallow: /
User-agent: PerplexityBot
Disallow: /
User-agent: Amazonbot
Disallow: /
User-agent: ClaudeBot
Disallow: /
User-agent: Omgilibot
Disallow: /
User-Agent: FacebookBot
Disallow: /
User-Agent: Applebot
Disallow: /
User-agent: anthropic-ai
Disallow: /
User-agent: Bytespider
Disallow: /
User-agent: Claude-Web
Disallow: /
User-agent: Diffbot
Disallow: /
User-agent: ImagesiftBot
Disallow: /
User-agent: Omgilibot
Disallow: /
User-agent: Omgili
Disallow: /
User-agent: YouBot
Disallow: /
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;install&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/deno&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;deno&lt;/span&gt;&lt;/a&gt; install &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241016/#install&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Seems deno continues to converge towards v2 &lt;code&gt;node&lt;/code&gt; - there&#39;s an install command
in v2. Will revise some &lt;code&gt;deno.json&lt;/code&gt; to see how the lockfiles work in CI.&lt;/p&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;Links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241016/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cyberciti.biz/web-developer/block-openai-bard-bing-ai-crawler-bots-using-robots-txt-file/&quot;&gt;https://www.cyberciti.biz/web-developer/block-openai-bard-bing-ai-crawler-bots-using-robots-txt-file/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ai-robots-txt/ai.robots.txt&quot;&gt;https://github.com/ai-robots-txt/ai.robots.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.404media.co/websites-are-blocking-the-wrong-ai-scrapers-because-ai-companies-keep-making-new-ones/&quot;&gt;https://www.404media.co/websites-are-blocking-the-wrong-ai-scrapers-because-ai-companies-keep-making-new-ones/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.deno.com/runtime/fundamentals/modules/#integrity-checking-and-lock-files&quot;&gt;https://docs.deno.com/runtime/fundamentals/modules/#integrity-checking-and-lock-files&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>On parsing, and also private networks</title>
		<link href="https://memo.forof.dev/blog/20241015/"/>
		<updated>2024-10-15T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241015/</id>
		<content type="html">&lt;h2 id=&quot;io-and-flycast&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/fly&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;fly&lt;/span&gt;&lt;/a&gt;.io and flycast &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241015/#io-and-flycast&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;ve been working on some html -&amp;gt; markdown conversions with &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/elixir&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;elixir&lt;/span&gt;&lt;/a&gt;. It&#39;s been
quite tricky to build a general-purpose utility for this, and so I&#39;ve despaired
by deciding to just do it with &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/deno&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;deno&lt;/span&gt;&lt;/a&gt;. This means deploying a small deno app that
accepts API requests from an elixir app. I don&#39;t want it on the public internet,
and fly.io has a pretty simple way to support non-public facing apps that still
benefit from fly proxy features, like auto-starting machines.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fly ips allocate-v6 --private
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, from my &lt;em&gt;other&lt;/em&gt; fly machines, I can simply make requests to
&lt;code&gt;http://my-fly-app.flycast&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;vs-ipv6&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/finch&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;finch&lt;/span&gt;&lt;/a&gt; vs ipv6 &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241015/#vs-ipv6&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Blurgh, because these requests are on an &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/ipv6&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;ipv6&lt;/span&gt;&lt;/a&gt; private network, I had to swap out
&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/finch&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;finch&lt;/span&gt;&lt;/a&gt; for &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/req&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;req&lt;/span&gt;&lt;/a&gt;, as there&#39;s no obvious way (to me) by which I can set finch&#39;s
connection options. I also had to revise the deno app to use &lt;code&gt;::&lt;/code&gt; as a host.&lt;/p&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;Links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241015/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://fly.io/docs/blueprints/private-applications-flycast&quot;&gt;https://fly.io/docs/blueprints/private-applications-flycast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://community.fly.io/t/trouble-connecting-to-private-app/10698/3&quot;&gt;https://community.fly.io/t/trouble-connecting-to-private-app/10698/3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://danschultzer.com/posts/ipv6-only-network-in-elixir&quot;&gt;https://danschultzer.com/posts/ipv6-only-network-in-elixir&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>An Ollama cheatsheet</title>
		<link href="https://memo.forof.dev/blog/20241014/"/>
		<updated>2024-10-14T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241014/</id>
		<content type="html">&lt;p&gt;An &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/ollama&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;ollama&lt;/span&gt;&lt;/a&gt; cheatsheet...&lt;/p&gt;
&lt;p&gt;Also, I saw a hero trailer on netflix that had obviously been AI dubbed... sounded totally demented.&lt;/p&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241014/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://secretdatascientist.com/ollama-cheatsheet/&quot;&gt;https://secretdatascientist.com/ollama-cheatsheet/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>It&#39;s pronounced `queue_target`</title>
		<link href="https://memo.forof.dev/blog/20241010/"/>
		<updated>2024-10-10T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241010/</id>
		<content type="html">&lt;p&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/til&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;til&lt;/span&gt;&lt;/a&gt; I mixed up &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/ecto&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;ecto&lt;/span&gt;&lt;/a&gt; &lt;code&gt;queue_target&lt;/code&gt; for &lt;code&gt;queue_interval&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241010/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hexdocs.pm/db_connection/DBConnection.html#start_link/2-queue-config&quot;&gt;https://hexdocs.pm/db_connection/DBConnection.html#start_link/2-queue-config&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://elixirforum.com/t/ecto-query-timeout/27946/6&quot;&gt;https://elixirforum.com/t/ecto-query-timeout/27946/6&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>CAPSLOCK IS STUCCCCCCCK</title>
		<link href="https://memo.forof.dev/blog/20241009/"/>
		<updated>2024-10-09T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241009/</id>
		<content type="html">&lt;p&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/til&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;til&lt;/span&gt;&lt;/a&gt; how to turn capslock off when I magically get it stuck under &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/windows&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;windows&lt;/span&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Ctrl + ALT then Ctrl + k
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I am occasionally mired in using an Ubuntu guest with a Windows host. I swap
back and forth quickly, and something about the way I type yields a state where
capslock is just... stuck... worth mentioning that I remap capslock to ctrl
anywhere that I can, so when I get into this state, I can&#39;t simply hit capslock.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>bigfiles</title>
		<link href="https://memo.forof.dev/blog/20241008/"/>
		<updated>2024-10-08T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241008/</id>
		<content type="html">&lt;h2 id=&quot;bigfiles&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/vim&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;vim&lt;/span&gt;&lt;/a&gt; bigfiles &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241008/#bigfiles&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/til&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;til&lt;/span&gt;&lt;/a&gt; a sweet lil&#39; hack to disable &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/neovim&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;neovim&lt;/span&gt;&lt;/a&gt; plugins and features that might make
things sluggish... this has definitely not happened to me 100 times before.&lt;/p&gt;
&lt;pre class=&quot;language-lua&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-lua&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; bigfile &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;api&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nvim_create_augroup&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;bigfile&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; clear &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;g&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bigfile_size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.5&lt;/span&gt;

vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;filetype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  pattern &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.*&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; buf&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bo&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;buf&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;filetype &lt;span class=&quot;token operator&quot;&gt;~=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bigfile&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; path &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getfsize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;g&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bigfile_size &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bigfile&quot;&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;nil&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;api&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;FileType&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  group &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; bigfile&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  pattern &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bigfile&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  callback &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ev&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;b&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;minianimate_disable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt;
    vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;schedule&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bo&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ev&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;buf&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;syntax &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;filetype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; buf &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ev&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;buf &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;trigger-actions-on-events-with-vim-api-nvim-create-autocommand&quot; tabindex=&quot;-1&quot;&gt;trigger actions on events with &lt;code&gt;vim.api.nvim_create_autocommand&lt;/code&gt; &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241008/#trigger-actions-on-events-with-vim-api-nvim-create-autocommand&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-lua&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-lua&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;-- vim.api.nvim_create_autocmd({event}, {opts})&lt;/span&gt;

vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;api&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;-- the event&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;BufWritePost&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;-- the effect&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    pattern &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;*.js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    command &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;silent! !prettier --write %&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;organizing-autocommands-with-vim-api-nvim-create-augroup&quot; tabindex=&quot;-1&quot;&gt;organizing autocommands with &lt;code&gt;vim.api.nvim_create_augroup&lt;/code&gt; &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241008/#organizing-autocommands-with-vim-api-nvim-create-augroup&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;language-lua&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-lua&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; myGroup &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;api&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nvim_create_augroup&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MyAutoGroup&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; clear &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

vim&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;api&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;BufWritePost&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;-- the group&lt;/span&gt;
    group &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; myGroup&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    pattern &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;*.js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    command &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;silent! !prettier --write %&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241008/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/LazyVim/LazyVim/commit/938a6718c6f0d5c6716a34bd3383758907820c52&quot;&gt;https://github.com/LazyVim/LazyVim/commit/938a6718c6f0d5c6716a34bd3383758907820c52&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>head in hand, vmware carnage</title>
		<link href="https://memo.forof.dev/blog/20241007/"/>
		<updated>2024-10-07T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241007/</id>
		<content type="html">&lt;h2 id=&quot;disk-going-berserker-mode&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/vmware&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;vmware&lt;/span&gt;&lt;/a&gt; disk going berserker-mode &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241007/#disk-going-berserker-mode&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Had to tear down my long-lived guest VM today. After bumping to Ubuntu 24 LTS,
the disk inexplicably grew to 390gb...&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;i&#39;d set a disk size... way smaller than 390gb&lt;/li&gt;
&lt;li&gt;no snapshots...&lt;/li&gt;
&lt;li&gt;no space to triage&lt;/li&gt;
&lt;li&gt;corporate security that kills usb&lt;/li&gt;
&lt;li&gt;having to virtualize my daily-dev env is, uh... productive&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;io-and-queue-interval&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/fly&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;fly&lt;/span&gt;&lt;/a&gt;.io, &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/phoenix&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;phoenix&lt;/span&gt;&lt;/a&gt; &amp;amp; &lt;code&gt;queue_interval&lt;/code&gt; &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241007/#io-and-queue-interval&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Found a &lt;a href=&quot;https://elixirforum.com/t/ecto-query-timeout/27946/5&quot;&gt;helpful thread&lt;/a&gt;
for tuning how &lt;code&gt;phoenix&lt;/code&gt; will talk to the db, in my case &lt;code&gt;supabase&lt;/code&gt;.
&lt;code&gt;queue_interval: 500&lt;/code&gt; is pretty long, but seems to help with the machine resume
thing...&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Emojis</title>
		<link href="https://memo.forof.dev/blog/20241004/"/>
		<updated>2024-10-04T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241004/</id>
		<content type="html">&lt;h2 id=&quot;emoji-keyboard&quot; tabindex=&quot;-1&quot;&gt;emoji keyboard &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/macos&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;macos&lt;/span&gt;&lt;/a&gt; &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241004/#emoji-keyboard&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;beep beep: &lt;code&gt;Control (⌃) + Command (⌘) + Space&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;minus&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/phoenix&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;phoenix&lt;/span&gt;&lt;/a&gt; minus &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/tailwind&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;tailwind&lt;/span&gt;&lt;/a&gt; &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241004/#minus&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;ve been deleting most of the default tailwind classes attached to the core
components that Phoenix generates. Think I&#39;ll start my next &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/phoenix&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;phoenix&lt;/span&gt;&lt;/a&gt; project
with &lt;code&gt;--no-tailwind&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;Links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241004/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://elixirforum.com/t/how-to-remove-tailwind-from-phoenix-completely-i-only-want-vanilla-css/54551/3&quot;&gt;elixir forums&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/phoenixframework/phoenix/blob/main/CHANGELOG.md#phxnew-revamp&quot;&gt;Changelog for v1.7&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-describedby&quot;&gt;aria-describedby&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>While parsing markdown...</title>
		<link href="https://memo.forof.dev/blog/20241003/"/>
		<updated>2024-10-03T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241003/</id>
		<content type="html">&lt;h2 id=&quot;vim-test&quot; tabindex=&quot;-1&quot;&gt;vim-test &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241003/#vim-test&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Using &lt;a href=&quot;https://github.com/vim-test/vim-test&quot;&gt;vim-test&lt;/a&gt; with &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/vim&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;vim&lt;/span&gt;&lt;/a&gt;, &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/til&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;til&lt;/span&gt;&lt;/a&gt; how to
scroll the &lt;code&gt;:terminal&lt;/code&gt;. Just hit &lt;code&gt;&amp;lt;C-o&amp;gt;&lt;/code&gt;. Scroll a bit. Then &lt;code&gt;i&lt;/code&gt; to get back
into insert mode.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;On Neovim the &amp;quot;basic&amp;quot; and &amp;quot;neovim&amp;quot; strategies will run test commands using
Neovim&#39;s terminal, and leave you in insert mode, so that you can just press
&amp;quot;Enter&amp;quot; to close the terminal session and go back to editing. If you want to
scroll through the test command output, you&#39;ll have to first switch to normal
mode. The built-in mapping for exiting terminal insert mode is CTRL-&#92; CTRL-n,
which is difficult to press, so I recommend mapping it to CTRL-o:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;enum-find-enum-into&quot; tabindex=&quot;-1&quot;&gt;Enum.find |&amp;gt; Enum.into &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241003/#enum-find-enum-into&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Instead of doing a series of
&lt;a href=&quot;https://hexdocs.pm/elixir/1.12/Enum.html#find/3&quot;&gt;&lt;code&gt;Enum.find&lt;/code&gt;&lt;/a&gt; across an &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/elixir&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;elixir&lt;/span&gt;&lt;/a&gt;
list, pipe the contents of the &lt;code&gt;find&lt;/code&gt; straight
into &lt;a href=&quot;https://hexdocs.pm/elixir/1.12/Enum.html#into/2&quot;&gt;&lt;code&gt;Enum.into&lt;/code&gt;&lt;/a&gt; to produce a
&lt;code&gt;%{}&lt;/code&gt; that&#39;s easier to pluck values out of.&lt;/p&gt;
&lt;pre class=&quot;language-elixir&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;list &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;img&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;alt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;a shadow&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;...&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;width&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;792&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;height&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;528&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

with &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;img&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; attrs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token module class-name&quot;&gt;Enum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;list&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tag&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; tag &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;img&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
     &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;alt&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; alt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;src&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; src&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;token module class-name&quot;&gt;Enum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;into&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;attrs&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;![&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;#{&lt;/span&gt;alt&lt;span class=&quot;token delimiter punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;](&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;#{&lt;/span&gt;src&lt;span class=&quot;token delimiter punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;)&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
</content>
	</entry>
	
	<entry>
		<title>supabase and fly.io</title>
		<link href="https://memo.forof.dev/blog/20241002/"/>
		<updated>2024-10-02T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241002/</id>
		<content type="html">&lt;h2 id=&quot;vs&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/supabase&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;supabase&lt;/span&gt;&lt;/a&gt; vs. &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/fly&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;fly&lt;/span&gt;&lt;/a&gt; &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241002/#vs&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Kicking out some toy apps, and fiddling with a &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/phoenix&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;phoenix&lt;/span&gt;&lt;/a&gt; app deployed to &lt;code&gt;fly.io&lt;/code&gt;
— they have an alpha integration back to &lt;code&gt;supabase&lt;/code&gt;, nice. I don&#39;t want to
manage &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/postgres&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;postgres&lt;/span&gt;&lt;/a&gt;. &lt;em&gt;BUT&lt;/em&gt; when my fly machines are suspended, I&#39;ll frequently hit
an &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/ecto&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;ecto&lt;/span&gt;&lt;/a&gt; issue whereby the database times out, and the user is presented with a
disappointing &amp;quot;internal server error&amp;quot; screen. Refresh the page, everything is
fine...&lt;/p&gt;
&lt;p&gt;The internet is a series of tubes. The tubes are clogged when my fly machines
are stopped. Guess I&#39;ll set &lt;code&gt;fly.toml&lt;/code&gt; to always have one machine up. &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/til&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;til&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;language-toml&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-toml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token table class-name&quot;&gt;http_service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;token key property&quot;&gt;min_machines_running&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;pending... fly.io may have a more bespoke approach for managed postgres soon.
Surely there&#39;s a way to have these cold-boot machines more quickly connect to
supabase.&lt;/p&gt;
&lt;h2 id=&quot;remembering-that-i-ve-forgotten-how-to-type-an-em-dash&quot; tabindex=&quot;-1&quot;&gt;Remembering that I&#39;ve forgotten how to type an em—dash &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241002/#remembering-that-i-ve-forgotten-how-to-type-an-em-dash&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Option + Shift + Hyphen = lol&lt;/p&gt;
&lt;h2 id=&quot;etc&quot; tabindex=&quot;-1&quot;&gt;etc. &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241002/#etc&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;hamhock/hipbone hambone/legbone&lt;/p&gt;
&lt;h2 id=&quot;links&quot; tabindex=&quot;-1&quot;&gt;Links &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241002/#links&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://fly.io/docs/elixir/the-basics/clustering/&quot;&gt;https://fly.io/docs/elixir/the-basics/clustering/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hexdocs.pm/ecto_sql/Ecto.Adapters.Postgres.html#module-connection-options&quot;&gt;https://hexdocs.pm/ecto_sql/Ecto.Adapters.Postgres.html#module-connection-options&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fly.io/docs/supabase/#main-content-start&quot;&gt;https://fly.io/docs/supabase/#main-content-start&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fly.io/docs/launch/autostop-autostart/#apps-that-shut-down-when-idle&quot;&gt;https://fly.io/docs/launch/autostop-autostart/#apps-that-shut-down-when-idle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fly.io/phoenix-files/shut-down-idle-phoenix-app/&quot;&gt;https://fly.io/phoenix-files/shut-down-idle-phoenix-app/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
	</entry>
	
	<entry>
		<title>October, unsurprisingly.</title>
		<link href="https://memo.forof.dev/blog/20241001/"/>
		<updated>2024-10-01T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20241001/</id>
		<content type="html">&lt;h2 id=&quot;images&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/11ty&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;11ty&lt;/span&gt;&lt;/a&gt; images &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241001/#images&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/til&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;til&lt;/span&gt;&lt;/a&gt; how to use &lt;code&gt;@11ty/eleventy-img&lt;/code&gt; on this very blog. It&#39;ll slurp media from
elsewhere. Also, flickr makes it damn-near impossible to find the static links
to your pictures these days. More internet bitrot.&lt;/p&gt;
&lt;pre class=&quot;language-jinja2&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jinja2&quot;&gt;&lt;span class=&quot;token jinja2 language-jinja2&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token tag keyword&quot;&gt;image&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;http://killtheliterate.com/zines/the-grackles-seething/img/helicopter.jpg&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;a shadow&quot;&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;picture class=&quot;image&quot;&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://memo.forof.dev/img/ocmxZOf3tv-792.avif 792w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://memo.forof.dev/img/ocmxZOf3tv-792.webp 792w&quot;&gt;&lt;img src=&quot;https://memo.forof.dev/img/ocmxZOf3tv-792.jpeg&quot; alt=&quot;a shadow&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;792&quot; height=&quot;528&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;h2 id=&quot;clarifying-ballistics&quot; tabindex=&quot;-1&quot;&gt;Clarifying &amp;quot;ballistics&amp;quot; &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241001/#clarifying-ballistics&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Probably obvious to a lot of people, but given Israel&#39;s invasion of Lebanon, and
Iran&#39;s &amp;quot;preparation&amp;quot; to launch ballistic missiles ostensibly to somewhere within
Israel, I wondered &amp;quot;when is a missile not ballistic?&amp;quot;. &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/til&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;til&lt;/span&gt;&lt;/a&gt; the answer is when
it&#39;s a cruise missile. Ballistic missiles are delivered along (ahem) gravity&#39;s
rainbow, and cruise missiles are unpiloted kamikaze jets.&lt;/p&gt;
&lt;h2 id=&quot;devcontainers&quot; tabindex=&quot;-1&quot;&gt;devcontainers &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241001/#devcontainers&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One of the things I&#39;ve heard about, and chose to ignore. Encountered a
&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/devcontainer&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;devcontainer&lt;/span&gt;&lt;/a&gt; (&lt;code&gt;.devcontainer&lt;/code&gt;) file after cloning a file, so &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/til&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;til&lt;/span&gt;&lt;/a&gt; what it actually
is. Seems like a pragma for operating an IDE within the context of a container,
so that one doesn&#39;t have to install all the &lt;em&gt;stuff&lt;/em&gt;, e.g. &lt;code&gt;black&lt;/code&gt; or &lt;code&gt;prettier&lt;/code&gt;
or &lt;code&gt;node&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;soup-beans&quot; tabindex=&quot;-1&quot;&gt;soup beans &lt;a class=&quot;header-anchor&quot; href=&quot;https://memo.forof.dev/blog/20241001/#soup-beans&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A post elsewhere sent me on a journey learning about
&lt;a href=&quot;https://en.wikipedia.org/wiki/Pellagra&quot;&gt;pellagra&lt;/a&gt;, salmon cakes and therefore
&lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/til&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;til&lt;/span&gt;&lt;/a&gt; what soup beans are.&lt;/p&gt;
&lt;p&gt;&lt;picture class=&quot;image&quot;&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://memo.forof.dev/img/CIWiNQUlqi-800.avif 800w&quot;&gt;&lt;img src=&quot;https://memo.forof.dev/img/CIWiNQUlqi-800.webp&quot; alt=&quot;a photo that looks old in which a man is eating what I assume are soup beans.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;800&quot; height=&quot;616&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>The bees made honey in the lion&#39;s skull.</title>
		<link href="https://memo.forof.dev/blog/20240930/"/>
		<updated>2024-09-30T00:00:00Z</updated>
		<id>https://memo.forof.dev/blog/20240930/</id>
		<content type="html">&lt;p&gt;Kicking things off. &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/til&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;til&lt;/span&gt;&lt;/a&gt; about a few &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/11ty&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;11ty&lt;/span&gt;&lt;/a&gt; and &lt;a class=&quot;hashtag&quot; href=&quot;https://memo.forof.dev/tags/nunjucks&quot;&gt;&lt;span class=&quot;hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;nunjucks&lt;/span&gt;&lt;/a&gt; incantations. A few
observations as well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MDN is highly involved with nunjucks?&lt;/li&gt;
&lt;li&gt;Eleventy feels &lt;em&gt;way&lt;/em&gt; behind with regard to modern tooling. &lt;code&gt;esm&lt;/code&gt;,
type-checking, that sort of thing.&lt;/li&gt;
&lt;li&gt;I&#39;ve immediately collided with the eleventy API. The documentation is not that
easy to navigate, and lack of typing means that it&#39;s a bit more difficult to
interrogate the user-facing API directly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This all seems a bit odious. However, I&#39;m probably not the target audience for a
tool like 11ty (eleventy?). It seems like it has the same core &amp;quot;I&#39;m a big loop&amp;quot;
as CMSs I&#39;ve used before.&lt;/p&gt;
&lt;p&gt;To get the following to print, I&#39;ve had to wrap the fenced block with a nunjucks
&lt;code&gt;raw&lt;/code&gt; tag.&lt;/p&gt;
&lt;pre class=&quot;language-jinja2&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-jinja2&quot;&gt;&lt;span class=&quot;token jinja2 language-jinja2&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;{#
  nunjucks will render some very strange stuff if you don&#39;t do variable
  assignments properly.
#}&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token jinja2 language-jinja2&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;{# this #}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token jinja2 language-jinja2&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token tag keyword&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;hashtags&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;hashtagMap&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;getHashtags&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token jinja2 language-jinja2&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;{# not this #}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token jinja2 language-jinja2&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token tag keyword&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;hashtags&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token jinja2 language-jinja2&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;hashtagMap&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;getHashtags&lt;/span&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;}}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token jinja2 language-jinja2&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token tag keyword&quot;&gt;endset&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
</content>
	</entry>
</feed>
