]> git.wincent.com - masochist.git/log
9 months agochore: clean out some old/broken links main master
Greg Hurrell [Wed, 17 Aug 2022 06:56:57 +0000 (08:56 +0200)] 
chore: clean out some old/broken links

9 months agodocs: update Synergy version support info
Greg Hurrell [Wed, 17 Aug 2022 06:39:02 +0000 (08:39 +0200)] 
docs: update Synergy version support info

Just got an email from somebody who thought from the "and above" and "or
later" text that Synergy would work on later versions of macOS. That
text was written years ago (in some cases, over a decade ago), so it is
sorely out of date and wasn't written in a future-proof way. Update it
for clarity.

10 months agochore: remove references to ancient PEM certificates
Greg Hurrell [Sun, 17 Jul 2022 11:59:18 +0000 (13:59 +0200)] 
chore: remove references to ancient PEM certificates

10 months agochore: remove reference to ancient PGP key
Greg Hurrell [Sun, 17 Jul 2022 11:57:38 +0000 (13:57 +0200)] 
chore: remove reference to ancient PGP key

13 months agochore: clean up Keybase references
Greg Hurrell [Wed, 27 Apr 2022 20:41:20 +0000 (22:41 +0200)] 
chore: clean up Keybase references

Closes: https://github.com/wincent/masochist/issues/191
14 months agochore: clean up stray '";' strings
Greg Hurrell [Sun, 27 Mar 2022 20:27:47 +0000 (22:27 +0200)] 
chore: clean up stray '";' strings

14 months agodocs: update broken hextrapolate.wincent.com links
Greg Hurrell [Sun, 27 Mar 2022 20:02:59 +0000 (22:02 +0200)] 
docs: update broken hextrapolate.wincent.com links

Seeing as the subdomain doesn't resolve any more, update to point at
hex.wincent.com instead.

15 months agochore: fix some more broken links
Greg Hurrell [Mon, 28 Feb 2022 22:43:59 +0000 (23:43 +0100)] 
chore: fix some more broken links

15 months agochore: fix some broken links
Greg Hurrell [Mon, 28 Feb 2022 22:35:34 +0000 (23:35 +0100)] 
chore: fix some broken links

16 months agochore: ignore "next/" worktree
Greg Hurrell [Sat, 15 Jan 2022 14:06:07 +0000 (15:06 +0100)] 
chore: ignore "next/" worktree

Don't want to see noise that results from:

    git worktree add next upstream/next

16 months agorefactor: use `overflow-wrap: break-word` more extensively
Greg Hurrell [Sat, 8 Jan 2022 21:28:35 +0000 (22:28 +0100)] 
refactor: use `overflow-wrap: break-word` more extensively

Is this a good idea? This question was asked here:


and the consensus seems to be it's a bad idea, but only for some
non-English languages, and all my content is in English.

This will stop pages like:


which have long URLs visible inside `a` tags from looking like crap on
mobile (where they overflow the width and make the page too wide,
creating a horizontal scroll).

16 months agochore: remove stale package from cache
Greg Hurrell [Sat, 8 Jan 2022 21:17:55 +0000 (22:17 +0100)] 
chore: remove stale package from cache

17 months agorefactor: tweak navbar background to be not so deeply black
Greg Hurrell [Fri, 17 Dec 2021 20:48:27 +0000 (21:48 +0100)] 
refactor: tweak navbar background to be not so deeply black

Full black can be a bit too intense.

17 months agochore: switch license to MIT
Greg Hurrell [Thu, 16 Dec 2021 08:11:34 +0000 (09:11 +0100)] 
chore: switch license to MIT

Had only been using CC-BY-NC-SA-4 because Corporate Overlords at
previous job had recommended it for use in personal projects. Left there
some years ago, and MIT is a better fit in the JS ecosystem.

Closes: https://github.com/wincent/masochist/issues/181
17 months agofeat: implement retry/reconnect on Redis client
Greg Hurrell [Mon, 13 Dec 2021 22:16:17 +0000 (23:16 +0100)] 
feat: implement retry/reconnect on Redis client

At the moment I am just catching the two most obvious possible errors;
EPIPE and ECONNREFUSED, but the truth is there are others that might
conceivably occur — from:


maybe ECONNRESET and ETIMEDOUT (even though Node sockets don't time out
by default) are obvious candidates... I might end up just doing a
blanket retry, too... not sure.

17 months agofeat: add --trace-warnings to `yarn start` (in dev)
Greg Hurrell [Mon, 13 Dec 2021 22:15:37 +0000 (23:15 +0100)] 
feat: add --trace-warnings to `yarn start` (in dev)

Useful for when I do things like leaking EventEmitters.

17 months agochore: remove express-graphql
Greg Hurrell [Mon, 13 Dec 2021 17:57:45 +0000 (18:57 +0100)] 
chore: remove express-graphql

I was only using it as a shortcut to getting GraphiQL in dev, but the
schema is basically "finished" at this point and I don't think I'm going
to need to troubleshoot it again (if I'm wrong about that, I can easily
revert this change). In the meantime, killing this is a small step
towards reducing the dependency footprint.

17 months agochore: remove stale comment
Greg Hurrell [Mon, 13 Dec 2021 17:53:20 +0000 (18:53 +0100)] 
chore: remove stale comment

Originally added in 375562c7dfb92691e6b32954be1d47a4e8550cfd ("Unbreak
webpack build", Nov 23, 2018). The problematic syntax was stripped out
in 7765e44d81c543c191a9deb78705a53885c29151 ("chore: remove unused Flow
types", Dec 12, 2021).

17 months agochore: remove dead code
Greg Hurrell [Sun, 12 Dec 2021 22:25:55 +0000 (23:25 +0100)] 
chore: remove dead code

I initially thought I might use these, which correspond to the commands
that I actually use, but in reality, I only use `get()`, and all the
others get used via `multi()`.

Now, when I start rewriting stuff in TypeScript, there will be some
value in having named methods like this, although I will probably want
to expose them on `multi()` like this:


as opposed to calling them individually (but having said that, I kind of
like the way the array calling convention mirrors the array result, so I
might see how far I can get with static types using that approach...)

17 months agorefactor: prefer ZRANGE over ZREVRANGE
Greg Hurrell [Sun, 12 Dec 2021 22:22:32 +0000 (23:22 +0100)] 
refactor: prefer ZRANGE over ZREVRANGE

As noted here:


> As per Redis 6.2.0, this command is considered **deprecated.** Please
> prefer using the ZRANGE command with the REV argument in new code.

(emphasis added)

17 months agochore: remove commented-out test code
Greg Hurrell [Sun, 12 Dec 2021 22:19:49 +0000 (23:19 +0100)] 
chore: remove commented-out test code

17 months agofix: adjust readIndex call in Tag model to work with new client
Greg Hurrell [Sun, 12 Dec 2021 22:11:19 +0000 (23:11 +0100)] 
fix: adjust readIndex call in Tag model to work with new client

So the old client returned an array with doubled rows, like:


The new client returns proper arrays:

   [foo, 10]
   [bar, 5]
   [baz, 3]

I think the only place where this matters is in the tags index, because
it is the only place where we're using `WITHSCORES`.

17 months agofeat: do a better job of logging interesting errors
Greg Hurrell [Sun, 12 Dec 2021 14:13:16 +0000 (15:13 +0100)] 
feat: do a better job of logging interesting errors

Like the one fixed in the parent commit. That kind of bug would cause a
500 in the browser, but in the server's console out, nothing would be

17 months agofix: add back PropTypes import
Greg Hurrell [Sun, 12 Dec 2021 14:10:03 +0000 (15:10 +0100)] 
fix: add back PropTypes import

I was moving quickly and not paying attention, but I _think_ the LSP
told me this was unused so I just deleted it. Or perhaps I blew it away
by accident while trying to delete the comment right above it.

Whatever. This was causing 500 errors.

17 months agofix: don't leak event listeners
Greg Hurrell [Sun, 12 Dec 2021 13:55:26 +0000 (14:55 +0100)] 
fix: don't leak event listeners

Because we were setting up an `on('line')` listener for every command
we ran, we were leaking these quite badly. Wouldn't be a problem if
the clients were short-lived (because when the client is GC'd, the
emitter/listener would go away, because the emitter and the listeners
are all the same object), but the clients live for as long as the server
process runs.

17 months agochore: clean up additional Flow loose ends
Greg Hurrell [Sun, 12 Dec 2021 10:16:26 +0000 (11:16 +0100)] 
chore: clean up additional Flow loose ends

Some stuff that didn't get covered in the last commit, which I made

    yarn global add flow-remove-types
    flow-remove-types --pretty src -d lib
    cp -R lib/* src/
    yarn run pretty

Then I backed out the changes to `**/__generated__/*` files.

Now I've swept through, cleaning up empty comments, removing lint
suppressions etc, as well as converting the `scripts/` directory that I
had neglected, and removing some type-only imports.

17 months agochore: remove unused Flow types
Greg Hurrell [Sun, 12 Dec 2021 10:09:57 +0000 (11:09 +0100)] 
chore: remove unused Flow types

I stopped using Flow a while ago, and have a pending ticket open for
porting to TypeScript[^1], and another in-progress rewrite anyway[^2]...
so for now these are mostly just noise (at best, you can consider them
as inline documentation that might go stale).

[^1]: https://github.com/wincent/masochist/issues/142
[^2]: https://github.com/wincent/masochist/issues/140 — although note
the ticket is nominally about updating the Relay version, which is way
behind, but which is tantamount to doing a full rewrite anyway because
so much is going to have to change.

17 months agorefactor: switch `then()` to use `async`/`await` instead
Greg Hurrell [Sun, 12 Dec 2021 09:55:16 +0000 (10:55 +0100)] 
refactor: switch `then()` to use `async`/`await` instead

Micro-refactoring that collapses 4 lines into 3 in a couple of places.

(Places, BTW, that I could DRY up by extracting out the common
functionality, but I don't won't to because the dumb and simple
duplicated version is easier to read.)

17 months agorefactor: turn lines into a property
Greg Hurrell [Sun, 12 Dec 2021 09:51:41 +0000 (10:51 +0100)] 
refactor: turn lines into a property

As all we ever do is pass it around unconditionally without changing it.
I originally had it as a param because I wasn't sure whether it was
going to be needed everywhere.

17 months agorefactor: rename parseResponse() to parse()
Greg Hurrell [Sun, 12 Dec 2021 09:48:24 +0000 (10:48 +0100)] 
refactor: rename parseResponse() to parse()

I only had it under a different name as an intermediate step while
preparing the parent commit.

17 months agorefactor: make redis client more robust
Greg Hurrell [Sat, 11 Dec 2021 23:36:57 +0000 (00:36 +0100)] 
refactor: make redis client more robust

I tried a few things here but eventually "settled" on this design; that
is to say, I wanted to make the async handling a bit more
robust/idiomatic, so I explored using an async generator, then switched
to using an async iterator. The problem should fix is that when we are
pipelining a bunch of commands and executing them with MULTI + EXEC, we
may get several data payloads back with the responses. In the parent
commit, I could run the little test case multiple times, and my MULTI
request would sometimes get 4 `undefined` responses, or 1, or none.

I think I've fixed that now, and just need to add in error handling
everywhere, but we don't actually expect too many errors as Redis should
pretty reliably return exactly what I'm asking it for.

How does this work? Basically, we want to be able to `await` one line at
a time until we've got everything we need, hence the async iterator.
This ended up being a bit more useful than the generator because we can
pass it around (eg. to parse bulk strings in a subroutine) or into a
recursive call (which we need in order to parse maps, sets, arrays etc).

17 months agochore: update some "safe" packages
Greg Hurrell [Fri, 10 Dec 2021 23:49:59 +0000 (00:49 +0100)] 
chore: update some "safe" packages

    yarn upgrade-interactive
    npx yarn-deduplicate yarn.lock

After this, `yarn audit` reports:

    12 vulnerabilities found - Packages audited: 1166
    Severity: 2 Low | 4 Moderate | 6 High

17 months agorefactor: cut over to WIP Redis client
Greg Hurrell [Fri, 10 Dec 2021 23:36:11 +0000 (00:36 +0100)] 
refactor: cut over to WIP Redis client

As noted in parent commit, it has some problems, but it still works well
enough to render the blog index in the local development environment
(this is the only page I've tested so far, and I only tested it once, so
you _know_ this is good).

Split up big file into smaller files so that I can keep things tidy as I
slowly refactor this into something robust.

17 months agofeat: add more stuff to WIP redis client
Greg Hurrell [Fri, 10 Dec 2021 22:16:21 +0000 (23:16 +0100)] 
feat: add more stuff to WIP redis client

As noted from the TODOs inline, still lots of missing pieces, and it's
not totally robust. Oh, and also, it's ugly. But it is pretty much
"feature complete" at this point and just needs to be fixed up, cleaned
up, and redesigned a bit. Ha.

17 months agorefactor: add WIP replacement Redis client
Greg Hurrell [Thu, 9 Dec 2021 23:06:37 +0000 (00:06 +0100)] 
refactor: add WIP replacement Redis client

We only need to handle a tiny number of commands:


(used alone, and...)


(used in `multi` transactions).

So something crude like this is probably going to be enough. It is
definitely not going to be efficient, but the payloads we are talking
about here are miniscule, so it really won't matter.

Still to do:

- Implement error handling.
- Add `multi` support.
- Address missing features and "TODOs" noted inline (for example, we
  aren't bailing early if we get an incomplete response).
- Add reconnect.
- Maybe write some tests.

Adding this as a .txt file just to show that it's not intended for
actual execution yet, but I do want it in version control in case my
machine dies.

17 months agodocs: s/master/main in README.md
Greg Hurrell [Wed, 8 Dec 2021 23:40:05 +0000 (00:40 +0100)] 
docs: s/master/main in README.md

17 months agodocs: fix and clean-up some paths in README
Greg Hurrell [Wed, 8 Dec 2021 23:38:33 +0000 (00:38 +0100)] 
docs: fix and clean-up some paths in README

Backticks because they look nicer when rendered, and "var" isn't true
any more — it's "srv".

17 months agochore: empty commit for redeploy
Greg Hurrell [Wed, 8 Dec 2021 23:22:01 +0000 (00:22 +0100)] 
chore: empty commit for redeploy

Our post-receive hook was dying trying to run Gulp:

    remote: $ node_modules/.bin/gulp build
    remote: error: aborting due to non-zero exit status (127)

I just changed it to run `node build.js` instead, and now need to retry
deploying, hence this empty commit.

17 months agorefactor: replace Gulp with crude script
Greg Hurrell [Wed, 8 Dec 2021 23:16:36 +0000 (00:16 +0100)] 
refactor: replace Gulp with crude script

Script was coded up in haste so is probably riddled with bugs, but it
seems to do what Gulp did without the enormous dependency footprint.

`yarn audit` is a bit happier after this:

19 vulnerabilities found - Packages audited: 1167
Severity: 2 Low | 11 Moderate | 6 High

Previously, it was:

28 vulnerabilities found - Packages audited: 1416
Severity: 2 Low | 17 Moderate | 9 High

Most of the remaining issues are in the relay-compiler, of which I am
running a super-old version.

Closes: https://github.com/wincent/masochist/issues/177
17 months agofix: use correct name for license file
Greg Hurrell [Wed, 8 Dec 2021 23:14:42 +0000 (00:14 +0100)] 
fix: use correct name for license file

Instead of:

    [object Object].LICENSE.txt

generate something like:


17 months agochore: remove unused Flow file
Greg Hurrell [Wed, 8 Dec 2021 23:14:21 +0000 (00:14 +0100)] 
chore: remove unused Flow file

17 months agorefactor: improve contrast in footer area
Greg Hurrell [Wed, 8 Dec 2021 18:50:28 +0000 (19:50 +0100)] 
refactor: improve contrast in footer area

17 months agochore: clean up stray packages
Greg Hurrell [Wed, 8 Dec 2021 18:17:34 +0000 (19:17 +0100)] 
chore: clean up stray packages

Just by running `yarn`.

17 months agochore: run `npx yarn-deduplicate yarn.lock`
Greg Hurrell [Wed, 8 Dec 2021 18:17:17 +0000 (19:17 +0100)] 
chore: run `npx yarn-deduplicate yarn.lock`

17 months agochore: back out redis "upgrade"
Greg Hurrell [Wed, 8 Dec 2021 18:13:54 +0000 (19:13 +0100)] 
chore: back out redis "upgrade"

Because it's not worth it.

The `ZREVRANGE` command is not implemented, which breaks things for us.

Note that we can get the same with `ZRANGE` and passing a `REV` option:


but that still leaves headaches elsewhere, where we were using
`ZREVRANGE` with the `WITHSCORES` option. This isn't supported by the
npm package, even though Redis itself supports it:


The suggestion is to switch overt to `ZRANGEBYSCORE` instead, but that
is starting to sound awfully like a hassle.

17 months agorefactor: switch multi invocation to v4 style
Greg Hurrell [Wed, 8 Dec 2021 17:57:53 +0000 (18:57 +0100)] 
refactor: switch multi invocation to v4 style

As documented here:


But here's the interesting thing about it — it doesn't work for all
Redis commands. So, for example, we can hit a blog permalink page just
fine but not a page using a reverse-sorted index, like the blog index

This shows up as a server crash:

    TypeError: Cannot read property 'posts' of null
        at PostsIndex.render (/Users/wincent/code/masochist/src/client/components/PostsIndex.js:64:35)

Dicking around in the console I established that the API works for some
commands but not others; for example, `ZREVRANGE` is missing, but
`ZCARD` is not:

    in loop ZREVRANGE masochist:6:blog-index [ 0, 2 ]
    command undefined
    in loop ZCARD masochist:6:blog-index []
    command [Function (anonymous)]

So, if I can't find a way to work around this I may just have to
"downgrade" (that is, "upgrade") to the previously working version of
the software.

17 months agoRevert "chore: revert to state as of 447b2a875"
Greg Hurrell [Wed, 8 Dec 2021 16:55:09 +0000 (17:55 +0100)] 
Revert "chore: revert to state as of 447b2a875"

Now that I've got the production site back up by "rolling back" to the
prior rev, I'm doing this revert (to the bad rev) in the hope of
reproducing locally and finding out what's going on.

This reverts commit 43dee176285d111227a31634425188d91f4a29c2.

17 months agochore: revert to state as of 447b2a875
Greg Hurrell [Wed, 8 Dec 2021 16:52:00 +0000 (17:52 +0100)] 
chore: revert to state as of 447b2a875

This reverts the last 13 commits because something isn't liking the
changes in prod, where the server serves up the top part of the document
and then nothing.

"Rolling back" in order to do some troubleshooting.

17 months agochore: bump graphql-relay v0.6.0 to v0.7.0
Greg Hurrell [Wed, 8 Dec 2021 16:39:58 +0000 (17:39 +0100)] 
chore: bump graphql-relay v0.6.0 to v0.7.0

To get rid of the duplicate prettier version it was bringing in to the

17 months agochore: update Prettier
Greg Hurrell [Wed, 8 Dec 2021 16:34:20 +0000 (17:34 +0100)] 
chore: update Prettier

Although note that we still have an old duplicate copy lying around

    => Found "graphql-relay#prettier@1.19.1"
    info This module exists because "graphql-relay" depends on it.

I don't know/recall why it has it as a non-dev dependency; all its other
deps are under `devDependencies`... looking, seems it is unintended and
was fixed in:


but there are too many breaking changes for me to feel all that
enthusiastic about moving from 0.6.0 to the current release (0.9.0):


although admittedly, we could get that fix by going just to v0.7.0, I
think, which does look relatively safe. I might try that in the next

17 months agochore: update sinon package too
Greg Hurrell [Wed, 8 Dec 2021 16:31:28 +0000 (17:31 +0100)] 
chore: update sinon package too

Another safe upgrade; `yarn test` still green.

If only getting rid of Gulp were so easy... *sigh*

17 months agochore: update some more (hopefully safe) packages
Greg Hurrell [Wed, 8 Dec 2021 16:16:53 +0000 (17:16 +0100)] 
chore: update some more (hopefully safe) packages

The redis update requires some shenanigans to get around breaking


17 months agochore: update webpack-dev-server
Greg Hurrell [Wed, 8 Dec 2021 16:04:38 +0000 (17:04 +0100)] 
chore: update webpack-dev-server

Note that I had to go through a few tweak-restart loops to flush out all
the problems:

    ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
     - options has an unknown property 'noInfo'. These properties are valid:

    ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
    - options has an unknown property 'publicPath'. These properties are valid:

    (node:46306) [DEP_WEBPACK_DEV_SERVER_CONSTRUCTOR] DeprecationWarning: Using 'compiler' as the first argument is deprecated. Please use 'options' as the first argument and 'compiler' as the second argument.

    (node:46332) [DEP_WEBPACK_DEV_SERVER_LISTEN] DeprecationWarning: 'listen' is deprecated. Please use async 'start' or 'startCallback' methods.

    <w> [webpack-dev-server] "hot: true" automatically applies HMR plugin, you don't have to add it manually to your webpack configuration.

17 months agochore: clean up lockfile and straggling packages
Greg Hurrell [Wed, 8 Dec 2021 16:01:06 +0000 (17:01 +0100)] 
chore: clean up lockfile and straggling packages

This is the diff produced by running just `yarn` alone.

17 months agochore: run `npx yarn-deduplicate yarn.lock`
Greg Hurrell [Wed, 8 Dec 2021 16:00:48 +0000 (17:00 +0100)] 
chore: run `npx yarn-deduplicate yarn.lock`

17 months agochore: update more packages
Greg Hurrell [Wed, 8 Dec 2021 16:00:21 +0000 (17:00 +0100)] 
chore: update more packages

I think this covers all of the "safe" ones.

17 months agochore: update some more webpack-ish deps
Greg Hurrell [Wed, 8 Dec 2021 15:42:20 +0000 (16:42 +0100)] 
chore: update some more webpack-ish deps

Most of these without a hitch, except for terser-webpack-plugin, which
was causing:

    - options has an unknown property 'sourceMap'. These properties are valid:
      object { test?, include?, exclude?, terserOptions?, extractComments?, parallel?, minify? }

So, I just removed the option. According to the changelog:


in version v5.0.0 they dropped it:

> removed the `sourceMap` option (respect the `devtool` option by default)

17 months agorefactor: use "Asset Modules" in lieu of url-loader
Greg Hurrell [Wed, 8 Dec 2021 15:32:43 +0000 (16:32 +0100)] 
refactor: use "Asset Modules" in lieu of url-loader

See: https://webpack.js.org/guides/asset-modules/

17 months agochore: update to webpack
Greg Hurrell [Wed, 8 Dec 2021 15:07:45 +0000 (16:07 +0100)] 
chore: update to webpack

This is the minimal set of changes specified in:


with tweaks to make `yarn start` and `yarn build` complete without

Note I had to get rid of the `!` chaining syntax, as noted here:

    Error: Compiling RuleSet failed: Exclamation mark separated
    loader lists has been removed in favor of the 'use'
    property with arrays (at ruleSet[1].rules[2].loader:

`yarn build` spews out a lot of deprecation notices and other warnings
(edited for readability):

    (node:33331) [DEP_WEBPACK_MAIN_TEMPLATE_RENDER_MANIFEST] DeprecationWarning: MainTemplate.hooks.renderManifest is deprecated (use Compilation.hooks.renderManifest instead)
    (Use `node --trace-deprecation ...` to show where the warning was created)
    (node:33331) [DEP_WEBPACK_CHUNK_TEMPLATE_RENDER_MANIFEST] DeprecationWarning: ChunkTemplate.hooks.renderManifest is deprecated (use Compilation.hooks.renderManifest instead)
    (node:33331) [DEP_WEBPACK_MAIN_TEMPLATE_HASH_FOR_CHUNK] DeprecationWarning: MainTemplate.hooks.hashForChunk is deprecated (use JavascriptModulesPlugin.getCompilationHooks().chunkHash instead)
    (node:33331) [DEP_WEBPACK_COMPILATION_OPTIMIZE_CHUNK_ASSETS] DeprecationWarning: optimizeChunkAssets is deprecated (use Compilation.hooks.processAssets instead and use one of Compilation.PROCESS_ASSETS_STAGE_* as stage option)
    (node:33331) [DEP_WEBPACK_COMPILATION_NORMAL_MODULE_LOADER_HOOK] DeprecationWarning: Compilation.hooks.normalModuleLoader was moved to NormalModule.getCompilationHooks(compilation).loader
    [16:06:38] Finished 'graphql' after 2.18 s
    (node:33331) [DEP_WEBPACK_COMPILATION_ASSETS] DeprecationWarning: Compilation.assets will be frozen in future, all modifications are deprecated.
    BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation.
            Do changes to assets earlier, e. g. in Compilation.hooks.processAssets.
            Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*.
    (node:33331) [DEP_WEBPACK_MODULE_ID] DeprecationWarning: Module.id: Use new ChunkGraph API
    (node:33331) [DEP_WEBPACK_MODULE_UPDATE_HASH] DeprecationWarning: Module.updateHash: Use new ChunkGraph API
    (node:33331) [DEP_WEBPACK_CHUNK_MODULES_ITERABLE] DeprecationWarning: Chunk.modulesIterable: Use new ChunkGraph API
    (node:33331) [DEP_WEBPACK_CHUNK_GROUP_GET_MODULE_INDEX_2] DeprecationWarning: ChunkGroup.getModuleIndex2 was renamed to getModulePostOrderIndex
    (node:33331) [DEP_WEBPACK_COMPILATION_CACHE] DeprecationWarning: Compilation.cache was removed in favor of Compilation.getCache()

    WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
    This can impact web performance.
      bundle-45d526449584b2234f04.js (525 KiB)

    WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
      main (541 KiB)

    WARNING in webpack performance recommendations:
    You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
    For more info visit https://webpack.js.org/guides/code-splitting/

    WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
      main (425 KiB)

    WARNING in webpack performance recommendations:
    You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
    For more info visit https://webpack.js.org/guides/code-splitting/

17 months agochore: update webpack to latest v4 version
Greg Hurrell [Wed, 8 Dec 2021 14:52:44 +0000 (15:52 +0100)] 
chore: update webpack to latest v4 version

Because this is the first step in the migration to v5:


`yarn start` still works after this, as does `yarn build`.

17 months agochore: update some CSS dependencies
Greg Hurrell [Wed, 8 Dec 2021 14:33:44 +0000 (15:33 +0100)] 
chore: update some CSS dependencies

To avoid this deprecation warning caused by a transitive dep,
es-abstract, as seen on the machine I'm currently on, which happens to
have NodeJS v16.8.0:

    (node:25719) [DEP0148] DeprecationWarning: Use of deprecated folder mapping "./" in the "exports" field module resolution of the package at $HOME/code/masochist/node_modules/es-abstract/package.json.
    Update this package.json to use a subpath pattern like "./*".
        at emitFolderMapDeprecation (node:internal/modules/esm/resolve:88:11)
        at packageExportsResolve (node:internal/modules/esm/resolve:648:7)
        at resolveExports (node:internal/modules/cjs/loader:482:36)
        at Function.Module._findPath (node:internal/modules/cjs/loader:522:31)
        at Function.Module._resolveFilename (node:internal/modules/cjs/loader:919:27)
        at Function.Module._load (node:internal/modules/cjs/loader:778:27)
        at Module.require (node:internal/modules/cjs/loader:1005:19)
        at require (node:internal/modules/cjs/helpers:94:18)
        at Object.<anonymous> ($HOME/code/masochist/node_modules/object.values/implementation.js:3:10)
        at Module._compile (node:internal/modules/cjs/loader:1101:14)

So, updated cssnano from 4.1.10 to 5.0.12, because that's the one that
was pulling in es-abstract. That, in turn, required a couple of other
updates. postcss got bumped to 8.4.4 (we still have some duplicate
divergent versions hiding away in various places though), as per `yarn
why postcss`:

    => Found "postcss@8.4.4"
    info Has been hoisted to "postcss"
    info This module exists because it's specified in "dependencies".
    => Found "css-loader#postcss@7.0.27"
    info This module exists because "css-loader" depends on it.
    => Found "autoprefixer#postcss@7.0.27"
    info This module exists because "autoprefixer" depends on it.
    => Found "icss-utils#postcss@7.0.27"
    info This module exists because "css-loader#icss-utils" depends on it.
    => Found "postcss-modules-local-by-default#postcss@7.0.27"
    info This module exists because "css-loader#postcss-modules-local-by-default" depends on it.
    => Found "postcss-modules-extract-imports#postcss@7.0.27"
    info This module exists because "css-loader#postcss-modules-extract-imports" depends on it.
    => Found "postcss-modules-scope#postcss@7.0.27"
    info This module exists because "css-loader#postcss-modules-scope" depends on it.
    => Found "postcss-modules-values#postcss@7.0.27"
    info This module exists because "css-loader#postcss-modules-values" depends on it.

and postcss-loader went from 3.0.0 to 4.2.0; I couldn't go all the way
to the latest (6.2.1), because that depends on webpack v5, and I'm on


Other release notes:


I'll look at doing some more updates in separate commits, as these
things tend to be such a cluster that it is best to approach them
incrementally and check that things are still working along the way.

18 months agorefactor: change overflow-wrap from "anywhere" to "break-word"
Greg Hurrell [Sat, 4 Dec 2021 11:56:57 +0000 (12:56 +0100)] 
refactor: change overflow-wrap from "anywhere" to "break-word"

Because "anywhere" is considered an invalid value by Safari, which means
that long `<code>` spans in my blog posts look crap on iOS (even in
Chrome, which is really a thin skin over WebKit on iOS), causing
unwanted horizontal scrolling.

I think this should be adequate. Should work in Chrome and Firefox too.
As described in:


the difference is as follows:

> **normal**
> Lines may only break at normal word break points (such as a space
> between two words).
> **anywhere**
> To prevent overflow, an otherwise unbreakable string of characters
> — like a long word or URL — may be broken at any point if
> there are no otherwise-acceptable break points in the line. No
> hyphenation character is inserted at the break point. Soft wrap
> opportunities introduced by the word break are considered when
> calculating min-content intrinsic sizes.
> **break-word**
> The same as the anywhere value, with normally unbreakable words
> allowed to be broken at arbitrary points if there are no otherwise
> acceptable break points in the line, but soft wrap opportunities
> introduced by the word break are NOT considered when calculating
> min-content intrinsic sizes.

Looking back over the history, I don't think I've tried this before.
See the output of `git log -Goverflow-wrap -p`, and specifically some
interesting commits like:

8d1b60d1aba6f21466e7562fc77aab37aec66516 ("fix: improve wrapping of
  code elements", Jul 9, 2021)
56bd364eb4e8cc4c33dfa70ef5f85dd051bf7fc9 ("fix: don't break words in
  <code> elements quite so aggressively", Jul 9, 2021)
bf8fbaa6647aa2386ccfd0d9ea60cb3800a37df1 ("refactor: don't abuse
  <code> element for styling tag lozenges", Jul 9, 2021)

Closes: https://github.com/wincent/masochist/issues/171
18 months agochore: freshen yarn.lock
Greg Hurrell [Sat, 4 Dec 2021 01:11:04 +0000 (02:11 +0100)] 
chore: freshen yarn.lock

Just ran `yarn` to make sure it is in "canonical form".

18 months agochore: remove duplication from yarn.lock
Greg Hurrell [Sat, 4 Dec 2021 01:09:58 +0000 (02:09 +0100)] 
chore: remove duplication from yarn.lock


    npx yarn-deduplicate yarn.lock

Has the side-effect of improving the `yarn audit` count a bit:

    54 vulnerabilities found - Packages audited: 1581
    Severity: 3 Low | 31 Moderate | 20 High

18 months agochore: update jest 25.1.0 → 27.4.3
Greg Hurrell [Sat, 4 Dec 2021 01:07:28 +0000 (02:07 +0100)] 
chore: update jest 25.1.0 → 27.4.3

Busy work to make `yarn audit` less upset. But still upset.


    106 vulnerabilities found - Packages audited: 1592
    Severity: 3 Low | 77 Moderate | 26 High


    65 vulnerabilities found - Packages audited: 1666
    Severity: 3 Low | 42 Moderate | 20 High

Note that I also needed to provide a `fail` function to avoid:

    ReferenceError: fail is not defined

18 months agofix: don't undo browser scroll-to-anchor actions
Greg Hurrell [Sat, 4 Dec 2021 00:24:42 +0000 (01:24 +0100)] 
fix: don't undo browser scroll-to-anchor actions

Seeing as I just added footnotes, I'm noticing the brokenness here.

18 months agochore: update React 16.13.0 → 17.0.2
Greg Hurrell [Fri, 3 Dec 2021 23:51:49 +0000 (00:51 +0100)] 
chore: update React 16.13.0 → 17.0.2

Was hoping this would fix some bugs I'm seeing around how click events
are handled (specifically, jump to and back from footnotes is only
working on the first click, or when JS is disabled), but it didn't.
Doesn't hurt to update though, as far as I can tell, so may as well keep
the change.

18 months agorefactor: start using CSS custom properties
Greg Hurrell [Fri, 3 Dec 2021 21:33:40 +0000 (22:33 +0100)] 
refactor: start using CSS custom properties

The copy-pasted hex values have long been getting on my nerves. There
are still lots of hard-coded values to be migrated, but I just want to
port a few to serve as a reminder of the direction I want to head in.

18 months agofeat: highlight footnote when it is active
Greg Hurrell [Fri, 3 Dec 2021 21:21:22 +0000 (22:21 +0100)] 
feat: highlight footnote when it is active

18 months agofeat: add support for footnotes
Greg Hurrell [Fri, 3 Dec 2021 20:37:18 +0000 (21:37 +0100)] 
feat: add support for footnotes

Now that GitHub supports footnotes, I find myself in the habit of using
them there pretty often and therefore wanting to use them here too.

I am not sure if I am fully sold on the design here, but I'm passing in
a DOM identifier so that the `id` attributes in the generated markup can
be unique. One question, for example, is should this field be nullable?
Another is is "DOMIdentifier" the right name? (I wanted to avoid
confusion with GraphQL "id" fields.) Should I be doing more with these
IDs, like using them on title anchor tags? (probably not). Should I
tighten up the schema documentation, where it misleadingly talks of
"prefix"? (As you can see from the link below, the "DOMIdentifier" ends
up being embedded somewhere in the middle of an ID.)

Anyway, all this is possible by setting `docId`, which you can see being
used to construct the anchor names here:


Possible follow-ups: want to check the contrast levels for accessibility
because I eye-balled these and they are probably horrible. May in
general want to do a pass on the styles to make sure they look as pretty
as they should be.

18 months agodocs: drop references to `npm`
Greg Hurrell [Fri, 3 Dec 2021 18:00:25 +0000 (19:00 +0100)] 
docs: drop references to `npm`

Just to reduce clutter. People can probably figure out that wherever
they see `yarn` they could probably use `npm` instead.

18 months agodocs: provide suggestion for how to install prerequisites
Greg Hurrell [Fri, 3 Dec 2021 18:00:09 +0000 (19:00 +0100)] 
docs: provide suggestion for how to install prerequisites

18 months agodocs: remove stale line from README
Greg Hurrell [Fri, 3 Dec 2021 17:51:58 +0000 (18:51 +0100)] 
docs: remove stale line from README

19 months agofix: repair some mangled redirects
Greg Hurrell [Sun, 24 Oct 2021 12:01:32 +0000 (14:01 +0200)] 
fix: repair some mangled redirects

22 months agofix: use "bash" not "shell" for "sh" markup
Greg Hurrell [Fri, 9 Jul 2021 12:18:22 +0000 (14:18 +0200)] 
fix: use "bash" not "shell" for "sh" markup

Turns out that "bash" is for scripts and "shell" is for "shell

So you want stuff like this for bash:

    echo "hi"

And stuff like this for sessions:

    $ sudo -s
    # ls

Supposedly, "zsh" and "sh" are aliases for "bash", but in my testing, I
can't really see what "sh" actually does.

22 months agorefactor: avoid highlight.js deprecation warning
Greg Hurrell [Fri, 9 Jul 2021 12:01:38 +0000 (14:01 +0200)] 
refactor: avoid highlight.js deprecation warning

    Deprecated as of 10.7.0. highlight(lang, code, ...args) has been deprecated.
    Deprecated as of 10.7.0. Please use highlight(code, options) instead.

22 months agorefactor: don't abuse <code> element for styling tag lozenges
Greg Hurrell [Fri, 9 Jul 2021 11:36:34 +0000 (13:36 +0200)] 
refactor: don't abuse <code> element for styling tag lozenges

22 months agochore: update highlight.js
Greg Hurrell [Fri, 9 Jul 2021 09:56:38 +0000 (11:56 +0200)] 
chore: update highlight.js

A scary update, but I actually think it's going to be ok:

- https://github.com/highlightjs/highlight.js/releases/tag/10.0.0
- https://github.com/highlightjs/highlight.js/releases/tag/11.0.0
- https://github.com/highlightjs/highlight.js/blob/main/VERSION_11_UPGRADE.md

22 months agochore: remove unused extract-text-webpack-plugin
Greg Hurrell [Fri, 9 Jul 2021 09:48:25 +0000 (11:48 +0200)] 
chore: remove unused extract-text-webpack-plugin

Unused since ba7fdb914c16bca7e0ce062 ("Make ES modules bundle as well",
Dec 16, 2018) and deprecated to boot:


22 months agochore: clean lockfile
Greg Hurrell [Fri, 9 Jul 2021 09:36:39 +0000 (11:36 +0200)] 
chore: clean lockfile

By running `yarn`. It always seems to want to make changes after
`yarn-deduplicate` has run. As you can see, it also removed a bunch of
dead(?) pages from the cache.

22 months agochore: deduplicate yarn.lock
Greg Hurrell [Fri, 9 Jul 2021 09:35:49 +0000 (11:35 +0200)] 
chore: deduplicate yarn.lock

With `npx yarn-deduplicate yarn.lock`.

22 months agorefactor: relax version ranges in package.json
Greg Hurrell [Fri, 9 Jul 2021 09:32:23 +0000 (11:32 +0200)] 
refactor: relax version ranges in package.json

22 months agochore: update markdown-it
Greg Hurrell [Fri, 9 Jul 2021 09:30:04 +0000 (11:30 +0200)] 
chore: update markdown-it

22 months agofix: don't break words in <code> elements quite so aggressively
Greg Hurrell [Fri, 9 Jul 2021 09:27:23 +0000 (11:27 +0200)] 
fix: don't break words in <code> elements quite so aggressively

The recent addition of `overflow-wrap: anywhere` was breaking my lovely
tag lozenges, which probably shouldn't be using `<code>` anyway because
they aren't code...

22 months agofix: remove unwanted bold styling
Greg Hurrell [Thu, 8 Jul 2021 23:34:06 +0000 (01:34 +0200)] 
fix: remove unwanted bold styling

Whoops, like I said in my last commit:

> Also experimented with bold but it is too heavyweight for my taste.

Somehow I managed to commit the unwanted change though...

22 months agofix: improve wrapping of code elements
Greg Hurrell [Thu, 8 Jul 2021 23:28:52 +0000 (01:28 +0200)] 
fix: improve wrapping of code elements

Chrome seems pretty flaky with `box-decoration-break`. ie. in order to
see the difference between "clone" and "slice" I need to toggle the
border on and off again. Whatever; I think the wrapped spans look better
without borders or rounded corners anyway, so removing those. Also
experimented with bold but it is too heavyweight for my taste.

23 months agorefactor: point at new location for content repo
Greg Hurrell [Tue, 6 Jul 2021 20:41:31 +0000 (22:41 +0200)] 
refactor: point at new location for content repo

23 months agofix: update npm packages
Greg Hurrell [Tue, 6 Jul 2021 17:50:51 +0000 (19:50 +0200)] 
fix: update npm packages

On new machine, we have a newer NodeJS, so we're running into this:

    Error: Cannot find module '$path_to/@babel/compat-data/data/corejs3-shipped-proposals'

Which I think is the issue described here:


and fixed here:


I just ran `yarn upgrade-interactive` and updated all the packages which
looked safe-ish.

23 months agochore: freshen stale vendor/yarn-cache
Greg Hurrell [Tue, 6 Jul 2021 17:38:14 +0000 (19:38 +0200)] 
chore: freshen stale vendor/yarn-cache

Not sure how this got stale, but it is. On trying to deploy to a new EC2
machine, got:

    error Can't make a request in offline mode

So, freshening the cache by running `yarn`.

23 months agofix: remove bad index.php
Greg Hurrell [Sun, 13 Jun 2021 21:17:15 +0000 (23:17 +0200)] 
fix: remove bad index.php

Whoops. I had this formerly harmless file in here, but when we added
`index.php` to our nginx `try_files` directive, it started getting
served up to visitors hitting the root. :facepalm:

So let's kill it, and if anybody goes to https://wincent.com/index.php
they'll just get a 404, which is fine.

23 months agofix: mend some broken image resources
Greg Hurrell [Sun, 13 Jun 2021 00:51:27 +0000 (02:51 +0200)] 
fix: mend some broken image resources

23 months agostyle: prettify static HTML files
Greg Hurrell [Sat, 12 Jun 2021 23:55:42 +0000 (01:55 +0200)] 
style: prettify static HTML files


    npx prettier --write "**/*.{html,php}" --parser html

23 months agorefactor: clean up links
Greg Hurrell [Sat, 12 Jun 2021 23:50:23 +0000 (01:50 +0200)] 
refactor: clean up links

Motivation is to avoid broken images caused by CSP violations (eg.
images hosted on www from non-www pages), but there are too many files
to do this in a non-automated way so this is just the dumbest of dumb

    find ./ -type f -exec gsed -i -e 's/www.wincent.com/wincent.com/g' {} \;
    find . -type f -exec gsed -i -e 's/secure.wincent.com/wincent.com/g' {} \;
    find . -type f -exec gsed -i -e 's#http://wincent.com#https://wincent.com#g' {} \;

23 months agochore: add some static files from old hosts
Greg Hurrell [Sat, 12 Jun 2021 22:17:25 +0000 (00:17 +0200)] 
chore: add some static files from old hosts

I want to "decommission" the hosts running at www.wincent.com and
secure.wincent.com without breaking any links, if I can help it. They
contain a bunch of PHP pages that do some very simple stuff like
composing a header and a footer and so on. There are only two (basically
dead) pages that handle POST requests.

So, I made this simple Ruby script that runs on the hosts and `curl`s
the pages (and other resources), taking a snapshot of everything. I
normally don't like leaking internal paths like this, but like I said,
the machines are going off the net forever shortly, so it's ok.

The directories that are guarded by .htaccess files all return 403s as
intended, so I haven't included those files in the dump.

As follow up I am going to have to tweak DNS records and SSL
certificates (SAN entries). But then I'll be able to kill off the old

    require 'fileutils'
    require 'shellwords'

    def escape(word)
      Shellwords.shellescape word

    # Note: we don't have to worry about simlinks over here;
    # both directories contain only directories and regular files
    #       find /var/www/secure.wincent.com/public_html -type l
    #       find /var/www/www.wincent.com/public_html -type l
    ].each do |base|
      puts "Scraping from: #{base}"

      # Note that `Dir.[]` won't return dot-files, so we miss out on:
      #       $ find /var/www/www.wincent.com/public_html -name '.*'
      #       /var/www/www.wincent.com/public_html/.well-known
      # and:
      #       $ find /var/www/secure.wincent.com/public_html -name '.*'
      #       /var/www/secure.wincent.com/public_html/a/products/install/licensees/binary-only/.htaccess
      #       /var/www/secure.wincent.com/public_html/a/products/install/licensees/full-source/.htaccess
      #       /var/www/secure.wincent.com/public_html/a/products/install/licensees/binary+framework/.htaccess
      #       /var/www/secure.wincent.com/public_html/a/products/install/licensees/.htaccess
      #       /var/www/secure.wincent.com/public_html/codegen/.htaccess
      #       /var/www/secure.wincent.com/public_html/.well-known
      Dir["#{base}/**/*"].each do |source|
        host = "#{source}".split(%r{/})[3]
        path = "#{source}".split(%r{/})[5..-1].join('/')
        destination = File.join(__dir__, 'output', source)
        if File.file? source
          if system "curl --silent https://#{host}/#{escape path} -o #{escape destination}"
            puts " OK : #{host}/#{path}"
            puts "FAIL: #{host}/#{path}"
          FileUtils.mkdir_p destination

2 years agofeat: add direct link to "About" page from site footer
Greg Hurrell [Wed, 2 Jun 2021 21:29:16 +0000 (23:29 +0200)] 
feat: add direct link to "About" page from site footer

2 years agofeat: dim images a bit in dark mode
Greg Hurrell [Tue, 17 Nov 2020 23:08:12 +0000 (00:08 +0100)] 
feat: dim images a bit in dark mode

2 years agofeat: add dark mode
Greg Hurrell [Tue, 17 Nov 2020 22:58:05 +0000 (23:58 +0100)] 
feat: add dark mode

Just a primitive first pass at this.

2 years agofix: degrade "gracefully" for undefined Search result
Greg Hurrell [Thu, 15 Oct 2020 19:56:13 +0000 (21:56 +0200)] 
fix: degrade "gracefully" for undefined Search result

I don't have time now to dig into why we're getting `undefined` here,
but I can at least stop the app from crashing.

    TypeError: Cannot destructure property `search` of 'undefined' or 'null'.

2 years agorefactor: update Vim link in footer
Greg Hurrell [Thu, 17 Sep 2020 22:38:19 +0000 (00:38 +0200)] 
refactor: update Vim link in footer

2 years agoperf: add `loading="lazy"` attribute to images
Greg Hurrell [Fri, 7 Aug 2020 19:46:58 +0000 (21:46 +0200)] 
perf: add `loading="lazy"` attribute to images

See: https://web.dev/native-lazy-loading/