Add posts

post/wasm-gol-2
Ashelyn Dawn 1 year ago
parent 18aed71c18
commit 8ca1ca0588

@ -14,6 +14,8 @@ export async function getStaticProps(): Promise<{ props: PageProps }> {
const sortedPosts = const sortedPosts =
posts posts
.filter((post) => post !== null)
.filter((post) => !post.unlisted)
.sort((a: Post, b: Post) => b.date.valueOf() - a.date.valueOf()) .sort((a: Post, b: Post) => b.date.valueOf() - a.date.valueOf())
.map((post: Post): SerializablePost => ({ ...post, date: post.date.toISOString() })) .map((post: Post): SerializablePost => ({ ...post, date: post.date.toISOString() }))

@ -0,0 +1,50 @@
---
title: Pixelbook First Impressions
subtitle: Becasue web dev in a web browser is sure to go well (/s)
---
My wife and I have been looking to upgrade her laptop for about a month or so. Our options were to buy her a new one directly or to find a replacement for me so she could use my old one. Last week we came across an interesting option: a used but great condition Pixelbook for basically half price.
Ive been using this Pixelbook for about a week now, and I think Im ready to give my first impressions.
### First, some context
Im a computer science student with an emphasis towards security and web programming. I already have a serviceable desktop PC for occasional gaming and class projects. My previous laptop was a Dell Inspiron from 2015. It worked well enough --- a bit heavy, but it was powerful enough to serve as my primary machine for several years. Since building my desktop I no longer need quite as much power on the go, so it was time to find something new.
Not everyone is in a position like mine, nor do we all have the same expectations with our devices. Because of this, you may disagree with my observations or conclusions. That's okay --- this isn't meant to be a review, but only a personal account of my experiences with the device.
### The Hardware
I purchased the i3 / 128 Gb model Pixelbook. Its surprisingly lightweight when compared to any laptop Ive ever owned. Ive not ever intentionally bought a lightweight device before though, so take that with a grain of salt. The keyboard is okay - its a bit soft and the lack of delete or end keys really bothers me. On the upside: the adjustable keyboard backlight is a nice touch.
The touchscreen is responsive and seems to be accurate. Its pen is useful for note-taking or annotating documents. Overall the hardware is not disappointing, but there's nothing particularly remarkable about it.
It's real strength in this category is the versatile tablet mode. It works well when propped up as a tent, and this has quickly become my favorite orientation to use for D&D sessions!
### The Software
This is where we get into the contentious topics! ChromeOS is ... okay. Its really not consistent and still feels very unfinished. Installing Linux apps in a container helps, but there are definitely some issues. Linux apps are inconsistent in how they handle the high-dpi screen, and sometimes the whole container sems to crash. This wouldn't be so bad if the integration was a bit more seamless --- an easy way to expose development ports, or integrating the clipboard perhaps.
Coming in with a slightly better overall experience is the Android app support. Clipboard works, the text is scaled properly, and these apps generally feel better to use. Not every app is available, and even those that are can sometimes seem stretched to fit the screen. On the whole though, Android apps are a much more delightful experience than Linux ones.
Chrome apps are of course the star of the show on ChromeOS and franky I dont really use them that much. Other than the core OS I don't use Chrome on my Pixelbook. For development I need a browser running _inside_ the container, so I've kept on using Firefox for now.
### Conclusion
Pros:
- Very convenient form factor
- Tablet mode is fantastic for annotations, note taking, etc
- Linux support works fairly well
- Powerful enough for my development, although your workflow may vary
Cons:
- ChromeOS settings are quite limited
- Keyboard lacks some keys I really do miss (del, home, end)
- Cant remap the Google Assistant key to function more like a traditional Super key
- Minor bugs here and there … nothing game-breaking, but they add up
Overall, Im happy enough with my new Pixelbook. ChromeOS is just _barely_ good enough that I put up with it, but who knows! I may still flash it with real Linux just for fun one of these days. If I do I'll be sure to update this post to include my experiences with Linux driver support, bootloader issues, etc.

@ -0,0 +1,56 @@
---
title: "Pixelbook Development Mode: A Cautionary Tale"
subtitle: It was all going far too well
---
So for about a month I've been using the Pixelbook as my portable development
and note-taking laptop, and it's been generally going well. Like I mentioned in
my [first impressions](/pixelbook-first-impressions) post, the
pen support is great, Android apps run surprisingly well, and while the Linux
container has some quirks it's pretty useful overall.
My biggest complaint so far, is that enabling ChromeOS developer mode puts it
it in a state where it's far too easy to accidentally wipe your system. **(Yes,
I say this from experience - it just happened to me.)**
Putting the Pixelbook in developer mode requires disabling its boot-time OS
verification, and every time the device starts it splashes up a warning screen
to inform you of this fact. The warning screen helpfully recommends you press
the spacebar to re-enable OS verification, but neglects to mention that doing
so will factory reset the device.
> *Developer Mode Boot Screen*
>
> ![Image of Pixelbook stating "OS verification is off"](/images/chromebook-developer-mode-warning.png)
>
> Source [Android Central](https://www.androidcentral.com/how-enable-developer-mode-chrome-os)
If developer mode was more stable, this wouldn't really be an issue - the
problem comes from when the device reboots unexpectedly.
This morning I was using my Pixelbook in tablet mode with the keyboard folded
behind it. This configuration puts the keys on the exposed bottom face of the
device . . . where I was holding it.
I was moving some windows around when the system froze and restarted, and before
I could realize what was happening my Pixelbook started resetting itself. The
way I was holding it, the spacebar was depressed (which normally isn't an issue
since keyboard input is disabled in tablet mode, but the bootloader isn't smart
enough to know that) and within seconds it had cleared the OS verification
screen and started the reset.
Luckily most of my projects are in git and all the Android apps I was using
sync to cloud storage automatically, so I didn't end up losing anything. But it
definitely made my heart skip a beat when I saw that powerwash screen come up!
So if you think you'd like to get the latest features, or pehaps you want to
sideload some Android apps onto your Pixelbook - whatever it is, think long and
hard about the risk of living one crash away from accidentally resetting your
device.
I think Google should potentially make it a bit harder to activate the powerwash
function from the bootloader, but developer mode _is_ supposed to be unstable
and dangerous. Personally I'll be sticking to the stable branch from now on,
so there's not any risk of this happening again. If you decide developer mode
is right for you, be sure to back up your work regularly!

@ -0,0 +1,213 @@
---
title: "A Beginner's Guide to HTML: Layout and Display"
subtitle: Some early thoughts for a friend
---
Welcome back! It's been a while, but today we're going to talk about
web stuff - I've been meaning to write a beginner's guide for a friend, so
today's the day!
We're not going to get too far into depth, we'll just be going over the basics of
browser layout, and how to use display `inline`, `block`, and `inline-block` elements.
> *Note:* This post will not be addressing `flex` or `grid` elements - I plan to cover those in a later post.
## Browser Layout and the Display Property
Every element in an HTML page has a `display` property - you might see it defined in CSS like this:
```css
img.photo {
display: block;
}
img.icon {
display: inline;
}
img.galleryCard {
display: inline-block;
}
```
This instructs the browser to render various elements as either `display: block`, `display: inline`, or `display: inline-block`. But what exactly do these display rules mean?
Generally speaking: block elements are elements which the browser renders as a box, and inline elements are elements which the browser renders as flowing text. Lets get into that a bit more!
### Block elements:
- Can have a defined width and height
- Can be given both vertical and horizontal margins
- Clear the whole width of their container
Block elements are typically things like &lt;div&gt;, &lt;ul&gt;, and header (&lt;h1&gt;&lt;h6&gt;) elements - although most HTML elements can be rendered as a block if you enforce it with the `display: block` rule. Heres a quick example:
```
<div style="
padding: 10px;
background: gray;
color: white
">
<p>This box is display block. Notice it takes the full width of its container.</p>
</div>
```
<div style="background:#444; padding: 20px">
<div style="background: gray; padding:10px; color: white">
<p>This box is display block. Notice it takes the full width of its container.</p>
</div>
</div>
See how this box automatically takes the full width? We can give it a fixed width and it will behave slightly differently:
```
<div style="
width:200px;
padding: 10px;
background: gray;
color: white
">
<p>This box is display block.</p>
<p>It is constrained to be 200px wide.</p>
</div>
```
<div style="background:#444; padding: 20px">
<div style="width:200px; background: gray; padding:10px; color: white">
<p>This box is display block.</p>
<p>It is constrained to be 200px wide.</p>
</div>
</div>
Lets look at whats going on here:
- The box is set to have a width of 200px
- We give it 10px of padding on each side (so the text doesn't run right up to the edge)
- We set the background color of the box and text color for elements in the box
Remember how initially I mentioned that block elements clear the width of their container? Let's demonstrate that:
<div style="color: white; background:#444; padding: 20px">
Text before the block element . . .
<div style="width:200px; height: 200px;margin:20px 0;background: gray; padding:10px; color: white">
<p>Even when we remove the centering margin - block elements clear the whole width of their container.</p>
</div>
Text after the block element . . .
</div>
Block elements clear all of the space to the side of them _by default_. This can be convenient sometimes, but other times it will be a bit annoying - try putting a border around a &lt;h1&gt; tag sometime, unless youre clever the border will extend to the full width of the page.
So if thats block elements, how are inline elements different?
### Inline elements:
- Flow from line to line, filling the space defined by their closest `block` ancestor
- Cannot have vertical margins
- Do not clear space to either side of them
Inline elements are things like &lt;a&gt;, &lt;b&gt;, &lt;i&gt;, and &lt;span&gt; tags. These are effectively treated as text, they wrap at the end of the line, and generally flow like you would expect text to in a word processor, although they dont necessarily have to be text:
```
<img src="https://placekitten.com/250/100"/>
<img src="https://placekitten.com/250/100"/>
<img src="https://placekitten.com/250/100"/>
<img src="https://placekitten.com/250/100"/>
```
<div style="padding: 20px; text-align: center; background: #444;">
<img style="display: inline" src="https://placekitten.com/250/100"/>
<img style="display: inline" src="https://placekitten.com/250/100"/>
<img style="display: inline" src="https://placekitten.com/250/100"/>
<img style="display: inline" src="https://placekitten.com/250/100"/>
</div>
Notice how when your screen isn't wide enough for all of them, these kitten images wrap at the end of the line? Also of interest is that there is a space between each of them (from the whitespace in our source code) but not between different rows of images. Images are by default `display: inline` so the browser tries to use its text-layout rules for how it should display these kittens.
One downside to inline display elements like this is that we have very little control over how much space is around our kittens - we can set a left or right margin, but theres no way to make sure we have vertical spacing between the rows. Well see in a bit how we can use `inline-block` to get around this, but lets keep exploring how `inline` works for a second.
Because these images are treated as very tall text, other text immediately before or after the kittens can also get weird - inline elements **dont** clear space beside them like block elements:
```
Text immediately before an image
<img src="https://placekitten.com/100/100"/>
<img src="https://placekitten.com/100/100"/>
Text immediately after
```
<div style="color: white; padding: 20px; background: #444;">
Text immediately before an image
<img style="display: inline" src="https://placekitten.com/100/100"/>
<img style="display: inline" src="https://placekitten.com/100/100"/>
Text immediately after
</div>
But remember we said before that any of these `display` properties can be overwritten?! If we instead set our kittens to be `display: block` then we see that our kittens suddenly behave much more like our space-clearing box from earlier:
```
Text immediately before an image
<img style="display: block" src="https://placekitten.com/250/300"/>
Text immediately after
```
<div style="color: white; padding: 20px; background: #444;">
Text immediately before an image
<img style="display: block" src="https://placekitten.com/250/300"/>
Text immediately after
</div>
**Note:** This technique of setting images to be `display: block` is often used for illustrations on the web - just add an `auto` side margin and its even centered:
```
Illustration of a kitten:
<img style="display: block; margin: 20px auto" src="https://placekitten.com/200/300"/>
(Text after the kitten)
```
<div style="color: white; padding: 20px; background: #444;">
Illustration of a kitten:
<img style="display: block; margin: 20px auto" src="https://placekitten.com/200/300"/>
(Text after the kitten)
</div>
Now you might be thinking _“Couldnt I just use &lt;p&gt; tags for my text and not have to deal with this `display: block` stuff?”_ . . . well yes. Sort of.
Its true that if you put your text in &lt;p&gt; tags then you get a nice result more or less for free:
```
<p>Text in a &lt;p&gt; before an image</p>
<img src="https://placekitten.com/300/200"/>
<p>Text in a &lt;p&gt; after</p>
```
<div style="color: white; padding: 20px; background: #444;">
<p>Text in a &lt;p&gt; before an image</p>
<img style="display: inline" src="https://placekitten.com/300/200"/>
<p>Text in a &lt;p&gt; after</p>
</div>
But even here, youre dealing with the pernicious influence of the `display: block` - &lt;p&gt; tags are block elements! This might seem counter-intuitive at first because we started by describing inline elements like flowing text, and &lt;p&gt; tags are _literally for text_, but I promise it makes sense: &lt;p&gt; tags represent a paragraph, and a paragraph should fill the width of its container. (Now, the _text inside_ the &lt;p&gt; tag is inline, but thats another story . . . )
So anyways, now that weve exposed the dirty secret of &lt;p&gt; tags, what exactly are `inline-block` elements?
### Inline-Block: A Surprisingly Useful Hybrid
So it should come as no surprise to you that an element with the style rule `display: inline-block` should behave in some ways like an inline element, and in some ways like a block element. `inline-block` is useful because it allows us the control over width, height, padding, and margin that a `block` element does, but it can be used a situation where `block` doesnt work - primarily where you want your elements to come one after the other within the same line like an `inline` element.
This kind of element is commonly used for photo galleries or navigation menus like this:
```
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px;" href="#">Home</a>
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px;" href="#">Posts</a>
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px;" href="#">Contact</a>
```
<div style="background:#444; padding: 20px; color: white;">
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px" href="#">Home</a>
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px" href="#">Posts</a>
<a style="display: inline-block; margin: 10px; padding: 10px; border: solid 1px white; border-radius: 3px" href="#">Contact</a>
</div>
There are a lot of different ways to use `inline-block` elements, and for a long time it was the preferred way to make several block elements that flowed from left to right rather than just top to bottom. Nowadays this use has largely been replaced by the new CSS flexbox and grid rules - but well have to talk about that another time!

@ -0,0 +1,36 @@
---
title: "Adventures with my Pixelbook: Linux Scaling Mode"
subtitle: Be warned, it's kind of janky
unlisted: true
---
This is just a quick update on one of the largest issues I've had with the
ChromeOS Linux app support: display scaling.
ChromeOS has a display scaling mode for Linux applications that don't handle the
high-DPI screen very well, and it generally works okay. It's a bit blurry, but
better than having a tiny UI in some applications.
The downside is that to enable this mode for an app, you need to pin that app
to your taskbar.
I'm not particularly fond of having a full taskbar, so I like to keep just the
essentials on there - and what about apps I need to launch with command line
parameters? Those can't be pinned to the taskbar without losing that ability.
If you've run into this issue, then don't worry - there is a solution!
ChromeOS's Linux container is allowed to draw to the screen through a special
X11 server that is run _inside_ the container, and then forwards that image
to the Wayland server running in ChromeOS. The magical screen scaling? It's
just a second X11 server!
Therein lies the trick to start apps with window scaling,
simply set the `DISPLAY` environment variable to `:1`.
```shell
DISPLAY=:1 firefox
```
Enjoy running your Linux apps without needing a magnifying glass!

@ -0,0 +1,120 @@
---
title: Sample Debugging Write-up
subtitle: ''
unlisted: true
---
> This is a sample write-up of how I investigated an issue for work.
>
> I'm putting this up with permisison from my former job, but it is ***unlisted***
and I would appreciate if you do not share it around.
>
> Additionally, code screenshots originally included when sending this write-up
to my co-workers have been removed so as to not leak confidential information.
Where applicable the document has been lightly re-worded to still make sense.
## Initial Issue
To start off with, let's talk about the actual bug. We observed that after
deploying a small change (which added a few static files and a URL redirect), our A/B
test between versions of the site started to act weird. Several of the pages
that had been implemented in the new design would briefly display the old UI,
then flash abruptly to the new version.
This issue was easily reproducible, and from our analytics it appeared
to be happening to **all** visitors assigned to the old UI. The weirdest part
though was that none of those affected pages were at all related to the changes
we had eployed!
At first I didn't really know what was going on, so I started poking around
in the sources for the various pages that manifested this issue. I didn't
expect there to be anything there, particularly since none of them had been
changed in the bad deploy, but it was a good place to start.
It's important to note here that our A/B testing for this application was
done at least in part at the HTTP routing level. Multiple different Next.js page
paths were being remapped by our reverse proxy to the same external URL, and
so from the beginning I knew something was rather weird here, as the old design
wasn't even importing any of the components of the new design. Just from that
we knew this couldn't be a component-level issue, and this had something to
do with Next's page routing.
## Weird behavior in webpack
After quickly double checking there was nothing obvious in the pages themselves,
I opened up the browser debugger and checked to see
which component files were being loaded. I thought perhaps there
could be an issue where the static cached version of the page was the old design
but then on rendering in the client it would reset to the new one.
While I was there, I happened to see something interesting: both versions of the page
were having their JS bundles loaded, and both still had sourcemaps cached in the browser developer tools. This seemed
weird to me. If the browser were (for some reason) choosing to reload the tab, it would
have unloaded all of the old layout's resources. Seeing both loaded at once
indicated that Next was doing a *client side* navigation from one to the other.
So after noting down that I needed to remind the team to disable sourcemaps in production, I started
digging into the debugger and dropping breakpoints.
## Debugging
I added a breakpoint to Next's `router.push()` and `router.replace()` functions,
just to see if they were being called at all.
As luck would have it, I was right - the `replace()` function *was* being called
immediately after the page's first render.
Firefox's debugger even helpfully had a call stack for me, with where it was being called from!
As I clicked through the call stack I found there was a check somewhere in one
of Next's internal components - as part of its `componentDidMount()` function
there were a few conditions where it would force-reload the page.
Because of how it's built, Next's sourcemaps were incomplete in the view I had,
but after comparing some of the constants in the file I was able to track it down
to the file [next/client/index.js](https://github.com/vercel/next.js/blob/v11.1.0/packages/next/client/index.tsx#L181)
in the Next.js source (line 181).
This section definitely looked like it could be causing the issue - the way Next
was figuring out what URL to pass to `router.replace()` was relying on the URL
in the browser's location history, which means that it would entirely bypass
our reverse proxy A/B routing. Unfortunately I didn't yet know why this was
being called, or if it was the only reason the page was being reinitialized.
I spent a while walking through the conditions in this line one by one, using
my debugger to check the value of each variable in the faulty production pages,
and work out what exactly was happening. It skips the checks for 404 and error pages,
since that's not the kind of page we were on, `isFallback` is false so it moves
on to the other conditions combined with an `||` there, `data.nextExport` is
undefined (as we don't use static export for our site), but `hydrateProps` and
`hydrateProps.__N_SSG` were both set!
So because `hydrateProps` and `hydrateProps.__N_SSG` both exist, it reloads the
page if either of the following conditions are true:
- The page has a query string (`location.search`)
- The environment variable `__NEXT_HAS_REWRITES` is set
Obviously the pages we first observed the bug on didn't have query strings, but
the rewrite condition had been optimized by webpack to just `true` so that seemed promising. With a bit more searching I tracked that
environment variable to Next's [webpack config](https://github.com/vercel/next.js/blob/v11.1.0/packages/next/build/webpack-config.ts),
which seems to set the variable if Next's config file has a rewrite property configured.
## Confirming the hunch
At this point it seemed I had found the issue, but I wanted to confirm it without
any doubt. So I reverted my local repo to the last commit we had deployed before
seeing the issue, and quickly navigated back to that same line in the generated
app bundle. This time the `process.env.__NEXT_HAS_REWRITES` condition had been
entirely removed, as webpack saw that environment variable was `false` for the build
and could never affect the condition.
Lastly I spun up my full local environment, reverse proxy and all, just to confirm
that in as close to a production-like environment as I could. I removed the rewrite
rule from the Next.js application and made an equivalent redirect in our reverse
proxy - just to make sure I could preserve the intended application behavior without
the bug.
And sure enough - with the redirect behavior moved out of Next.js and into the reverse
proxy, the bug entirely disappeared! So I reverted and restored my changes a few times
just to double check, and then alerted the other senior developers I had a solution.

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

@ -44,7 +44,7 @@ export async function loadSinglePage(slug: string): Promise<Post | null> {
const fileContents = (await fs.readFile(path.join(process.cwd(), 'posts', fileName))).toString('utf8') const fileContents = (await fs.readFile(path.join(process.cwd(), 'posts', fileName))).toString('utf8')
const { attributes, body } = frontmatter(fileContents) const { attributes, body } = frontmatter(fileContents)
type Attributes = { [key: string]: string } type Attributes = { [key: string]: any }
const data: Attributes = attributes as Attributes const data: Attributes = attributes as Attributes
if (!data.title) return null; if (!data.title) return null;
@ -54,7 +54,7 @@ export async function loadSinglePage(slug: string): Promise<Post | null> {
date: new Date(postMatch.groups.date), date: new Date(postMatch.groups.date),
title: data.title, title: data.title,
subtitle: data.subtitle, subtitle: data.subtitle,
unlisted: data.unlisted === 'true', unlisted: typeof data.unlisted === 'boolean' ? data.unlisted : false,
body body
} }
} }

Loading…
Cancel
Save