This is a valid RSS feed.
This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.
... ://www.peterbe.com/rss.xml" rel="self"/><language>en-us</language><lastB ...
^
line 87, column 181: (6 occurrences) [help]
... c to PissueTracker</a>."</p></description><pubDate>Sun, 16 M ...
^
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Peterbe.com</title><link>http://www.peterbe.com/rss.xml</link><description>Stuff in Peter's head</description><atom:link href="http://www.peterbe.com/rss.xml" rel="self"/><language>en-us</language><lastBuildDate>Tue, 13 May 2025 14:59:18 +0000</lastBuildDate><item><title>Set up iTerm to delete whole words on Option-Backspace</title><link>http://www.peterbe.com/plog/iterm-to-delete-whole-words-option-backspace</link><description><p>Out of the box, on a fresh <a href="https://iterm2.com/">iTerm2</a> installation when you press Option-Backspace (<kbd>⌥</kbd> <kbd>⌫</kbd>) it <strong><em>won't</em> delete whole words</strong> but instead backspace delete one character at a time.</p>
<p>The solution is to</p>
<ol>
<li>Open iTerm2's settings by pressing <kbd>⌘</kbd> <kbd>,</kbd> </li>
<li>Go to Profiles </li>
<li>Select "Keys" tab </li>
<li>Look for "Left option (⌥) key:" </li>
<li>Change it from "Normal" to "Esc+" </li>
<li>Close the preferences window</li>
</ol>
<p>I keep forgetting this and struggled to find up-to-date instructions so hopefully by blogging about it I won't forget next time.</p></description><pubDate>Tue, 13 May 2025 14:59:18 +0000</pubDate><guid>http://www.peterbe.com/plog/iterm-to-delete-whole-words-option-backspace</guid></item><item><title>How to SSG a Vite SPA</title><link>http://www.peterbe.com/plog/ssg-vite-spa</link><description>You can write a script to statically generate the HTML of a SPA to make the initial load feel faster.</description><pubDate>Sat, 26 Apr 2025 04:06:04 +0000</pubDate><guid>http://www.peterbe.com/plog/ssg-vite-spa</guid></item><item><title>Inspecting the index size in PostgreSQL</title><link>http://www.peterbe.com/plog/index-size-postgresql</link><description><p><strong>tl;dr ...</strong></p>
<pre><code class="hljs">
<span class="hljs-keyword">SELECT</span>
indexrelname,
pg_size_pretty(pg_relation_size(indexrelid)) <span class="hljs-keyword">AS</span> index_size
<span class="hljs-keyword">FROM</span> pg_stat_user_indexes
<span class="hljs-keyword">WHERE</span> relname <span class="hljs-keyword">LIKE</span> <span class="hljs-string">&#x27;search_terms%&#x27;</span>;
</code></pre>
<p>I'm working on a new table that is "search terms". A search term is constructed from extracting combinations of words, from <strong>titles</strong>, on my blog. For example, if the title is "Inspecting the index size in PostgreSQL" the search terms for that are:</p>
<ul>
<li><code>inspecting</code></li>
<li><code>inspecting index</code></li>
<li><code>inspecting index size</code></li>
<li><code>inspecting index size postgresql</code></li>
<li><code>index</code></li>
<li><code>index size</code></li>
<li><code>index size postgresql</code></li>
<li><code>size</code></li>
<li><code>size postgresql</code></li>
<li><code>postgresql</code></li>
</ul>
<!--split-->
<p>It's created by lower casing the input and taking one, two, three, and four non-stopwords.</p>
<p>To search these in PostgreSQL I use <strong>trigrams</strong> using <a href="https://www.postgresql.org/docs/current/pgtrgm.html"><code>pg_trgm</code></a>. For example,</p>
<pre><code class="hljs">
<span class="hljs-keyword">SELECT</span> id, term
<span class="hljs-keyword">FROM</span> search_terms
<span class="hljs-keyword">WHERE</span>
term <span class="hljs-keyword">LIKE</span> <span class="hljs-string">&#x27;conf%&#x27;</span>
<span class="hljs-keyword">OR</span> term <span class="hljs-keyword">LIKE</span> <span class="hljs-string">&#x27;% conf%&#x27;</span>
LIMIT <span class="hljs-number">10</span>
</code></pre>
<p>There's more to it, but this is a good start.</p>
<p>Anyway, I was curious how much space this is going to take up.<br />
By indexing trigrams, you're indexing a lot of small individual strings. So lots of combinations.</p>
<p>The index is defined like this:</p>
<pre><code class="hljs">
<span class="hljs-keyword">CREATE</span> INDEX search_terms_term_trgm
<span class="hljs-keyword">ON</span> search_terms
<span class="hljs-keyword">USING</span> GIST (term gist_trgm_ops)
</code></pre>
<p>After inserting a bit over 10,000 of these "search terms" the size of the index becomes:</p>
<pre><code class="hljs">
peterbecom=#
SELECT
indexrelname,
pg_size_pretty(pg_relation_size(indexrelid)) AS index_size
FROM pg_stat_user_indexes
WHERE relname LIKE &#x27;search_terms%&#x27;;
indexrelname | index_size
------------------------+------------
search_terms_pkey | 248 kB
search_terms_term_key | 488 kB
search_terms_term_trgm | 856 kB
(3 rows)
</code></pre>
<p>Curiously, if you set a higher <code>siglen</code> (e.g. <code>GIST (term gist_trgm_ops(siglen=24))</code>), it actually becomes smaller.</p>
<h3>Conclusion(?)</h3>
<p>If anything, it's not that large. In this particular example, there are only 10k of these smaller word combinations. It would be curious to see what the numbers become at 100k and 1M.</p></description><pubDate>Mon, 21 Apr 2025 16:36:26 +0000</pubDate><guid>http://www.peterbe.com/plog/index-size-postgresql</guid></item><item><title>Adding client-to-server sync to PissueTracker</title><link>http://www.peterbe.com/plog/client-to-server-sync-pissuetracker</link><description>When you save a record in Dexie.js, its payload is sent to the server for backup, and once that works, the record in Dexie.js is updated to indicate that it successfully synced.</description><pubDate>Thu, 20 Mar 2025 16:06:50 +0000</pubDate><guid>http://www.peterbe.com/plog/client-to-server-sync-pissuetracker</guid></item><item><title>Useful GitHub.com trick I learned today: l</title><link>http://www.peterbe.com/plog/useful-github.com-trick-l</link><description>Use the keyboard shortcut `l` when viewing a file on GitHub</description><pubDate>Wed, 19 Mar 2025 13:57:32 +0000</pubDate><guid>http://www.peterbe.com/plog/useful-github.com-trick-l</guid></item><item><title>Starting a side project: PissueTracker</title><link>http://www.peterbe.com/plog/starting-a-side-project-pissuetracker</link><description><p>I've started a new side project called PissueTracker. It's an issue tracker, but adding the "P" because my name is "Peter" and it makes the name a bit more unique. Also, the name isn't important. What this project <em>can do</em> is important.</p>
<p>In a sense, it's a competitor to GitHub Issues. An issue can be anything such as a feature or bug report or just something that needs to be addressed. In another sense, it's a competitor to a web product I built 24 years ago called <a href="/plog/issuetrackerproduct-no-more">IssueTrackerProduct</a>. That was a huge success and it was so much fun to build.</p>
<p>What's special about this issue tracker is that it's all about offline data, with server sync. All the issues you create and edit are stored in your browser. And if you don't want to lose all your data if/when your browser resets, you can have all that data constantly synchronized to the server which will either store it in PostgreSQL or the file system of a server. Since there's a shared data store, you can also authorize yourself amongst others in the system and this way it can become a collaborative experience.</p>
<p>I'm building it by using a React framework called <a href="https://mantine.dev/">Mantine</a>, which I'm a huge fan of. The browser storage is done with <a href="https://dexie.org/">Dexie.js</a> which uses <a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API">IndexedDB</a> and allows you to store data in relational ways.</p>
<p>So far, I've only spent 1 weekend day on it but I now have a foundation. It doesn't support comments or auth, yet. And I haven't even started on the server sync. But it supports creating multiple trackers, creating/editing issues, fast filtering, and safe Markdown rendering.</p>
<p>The front end is handled by Vite, React Router, and Bun, I don't know if that's important. Right now, the <strong>most important thing is to have fun and build</strong> something that feels intuitive and so fast that it feels instantly responsive.</p>
<p>More to come!</p>
<p><a href="/cache/70/51/7051dfb22e4c97bf3476798198210f14.png"><img src="/cache/4e/c3/4ec305c211858dfdc5bbb2e31a099091.png" alt="Listing issues" width="370" height="206"></a><br />
<em>List of issues in a tracker</em></p>
<p><a href="/cache/67/f1/67f18254262be0c4cef013d6cadc36c8.png"><img src="/cache/e3/b9/e3b98d36051fcee1cefdbb45530742ca.png" alt="Viewing an issue" width="370" height="227"></a><br />
<em>Viewing an issue</em></p>
<p><strong>UPDATE (Mar 20, 2025)</strong></p>
<p>Blogged about the client-to-server sync here: "<a href="/plog/client-to-server-sync-pissuetracker">Adding client-to-server sync to PissueTracker</a>."</p></description><pubDate>Sun, 16 Mar 2025 22:31:46 +0000</pubDate><guid>http://www.peterbe.com/plog/starting-a-side-project-pissuetracker</guid></item><item><title>Announcing: Spot the Difference</title><link>http://www.peterbe.com/plog/announcing-spot-the-difference</link><description>Spot the Difference is a web app where you're shown two snippets of code and you're supposed to find the one difference. If you get it right, you get showered in confetti.</description><pubDate>Sun, 23 Feb 2025 21:08:54 +0000</pubDate><guid>http://www.peterbe.com/plog/announcing-spot-the-difference</guid></item><item><title>get in JavaScript is the same as property in Python</title><link>http://www.peterbe.com/plog/get-in-javascript-is-the-same-as-property-in-python</link><description>Prefix a function, in an object or class, with `get` and then that acts as a function call without brackets. Just like Python's `property` decorator.</description><pubDate>Thu, 13 Feb 2025 12:41:56 +0000</pubDate><guid>http://www.peterbe.com/plog/get-in-javascript-is-the-same-as-property-in-python</guid></item><item><title>Use 'key' in React components to reset them</title><link>http://www.peterbe.com/plog/key-react-components-to-reset</link><description>You can use a unique `key` prop to reset a sub-components state in React.</description><pubDate>Wed, 12 Feb 2025 04:16:00 +0000</pubDate><guid>http://www.peterbe.com/plog/key-react-components-to-reset</guid></item><item><title>How to send custom headers in a loader in react-router v7</title><link>http://www.peterbe.com/plog/custom-headers-loader-react-router-v7</link><description>Use `data()` in your `loader` function and pass `headers` to be able to connect a `loader` function to the `header` function.</description><pubDate>Fri, 07 Feb 2025 17:11:51 +0000</pubDate><guid>http://www.peterbe.com/plog/custom-headers-loader-react-router-v7</guid></item></channel></rss>
If you would like to create a banner that links to this page (i.e. this validation result), do the following:
Download the "valid RSS" banner.
Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)
Add this HTML to your page (change the image src
attribute if necessary):
If you would like to create a text link instead, here is the URL you can use:
http://www.feedvalidator.org/check.cgi?url=https%3A//www.peterbe.com/rss.xml