Cat logomenu


page 2

Everybody knows that the dice are loaded\ Everybody rolls with their fingers crossed\ Everybody knows the war is over\ Everybody knows the good guys lost\ Everybody knows the fight was fixed\ The poor stay poor, the rich get rich\ That’s how it goes\ Everybody knows — Leonard Cohen, “Everybody Knows”

June 2, 2020

Becoming more and more convinced that one of the most important questions an application developer can ask themselves is: “But what about later?“*

*also a helpful question for everyone else

May 15, 2020

Goodbye, Adobe

I finally caved and upgraded to MacOS Catalina today. This means that my old, old, old copy of the Adobe CS4 Production Premium Suite no longer works. I had prepared for this over a year ago by purchasing Pixelmator Pro and Affinity Designer, which seemed like the best options given my requirements. I also ended up buying a license of Sketch a few months later because I needed it for a client’s app, and then Acorn when it was 50% off earlier this year.

None of them are the same. I don’t mind losing Photoshop so much, because Acorn in particular does seem like a great replacement for my typical workflow, and I can always figure out how to do the more powerful stuff in Pixelmator if it ever comes to that. But I’m going to miss Illustrator so much. Affinity Designer and Sketch both make me kind of furious in different ways, and I very, very much hate that there’s no way to just open, edit, and save an SVG in Designer—it’s always an “Export” function.

But also I realized that this will be the first time in twenty years that I won’t have Adobe apps running on my machine. They’ve been a huge part of my professional and amateur life. They just killed me with this $21/month pricing. I don’t need Illustrator that much. But I’m going to miss it something terrible. Hopefully being pushed into the arms of Affinity will help me embrace their UI paradigms and eventually become comfortable. But it still sucks to say goodbye to an old friend like Illustrator.

May 12, 2020

People Don't Change, But Older People Think They Do

Somehow when it comes to evaluating the cause of societal trouble, it basically always comes around to “people just suck more now”.

April 14, 2020

One of the unsung benefits of reading glasses is that they render the world beyond your book (I assume for the purposes of this thought that you are reading a book) a little out of focus. Taking them off makes putting down your novel seem even more like coming out of a dream.

March 22, 2020

The Martini is a demanding drink; the Manhattan is an accommodating one.

March 21, 2020


I know there’s a certain faddishness to functional programming, but if you work with React a lot it’s a good idea to remember that it’s moving more and more in the fp direction. Being at least comfortable with some of functional programming’s basics will help align your mindset with that of the creators of the library you’re using to create your app.

March 19, 2020

So I’m watching Captain America: The First Avenger for the first time in a while, and I realized: WWII is basically part of our mythology. It’s not that it’s not real---it’s that it’s historical and also more than historical. We feel like our role in the war says something deeper and truer about America than the mere historical facts can communicate.

The thing is… does it?

September 1, 2019

Programming, Tutorials

Apollo getCacheKey() with TypeScript

I’m currently working on the front end of an app that uses React + Apollo (via apollo-boost) + TypeScript. I’m to the point where I’m retrieving items from the cache in my resolvers using fragments1, which means I need to use getCacheKey() to search for the item’s cache key using its ID field. (In this app, it would probably work to just assume the cache key is TypeName:UUID, but you never know, so we should probably do things properly.)

Unfortunately, I have not been able to find the correct typings for getCacheKey(). When passing in cache as an argument to a resolver, one can import NormalizedCacheObject for the typings, like so:

import { ApolloCache } from 'apollo-cache'
import { NormalizedCacheObject } from 'apollo-boost'


Mutation: {
  resolveSomeStuff: (
    _: undefined,
    { itemId, itemOptions }: { itemId: string; itemOptions: Array<string> },
    { cache }: { cache: ApolloCache<NormalizedCacheObject> }
  ) => {
  /* Now we resolve everything. Global warming, world
  hunger, over- and under-population.... */

Inside my resolver, the Apollo docs tell me to get an item’s cacheKey like this:

const cacheKey = cache.getCacheKey({ __typename: "Item", id: itemId })

Unfortunately, if I use this formulation, tslint will yell at me:

“Property ‘getCacheKey’ does not exist on type ‘ApolloCache’.”


Half an hour of Googling was unhelpful. But eventually I found someone reporting a similar-sounding problem as an issue over at the apollo devtools repo. I adopted his workaround, and it was effective for me. So here is the code inside my resolver:

const cacheKey = cache["config"].dataIdFromObject({
  __typename: "Item",
  id: itemId,

This essentially does an end run around the problem by not calling getCacheKey() at all. I don’t know enough about the inner workings of the Apollo client to understand why this works, but I kind of don’t care.

  1. If you don’t know what some or all of that means, this post probably isn’t for you.

June 17, 2019

Ambient Privacy

Because our laws frame privacy as an individual right, we don’t have a mechanism for deciding whether we want to live in a surveillance society. Congress has remained silent on the matter, with both parties content to watch Silicon Valley make up its own rules. The large tech companies point to our willing use of their services as proof that people don’t really care about their privacy. But this is like arguing that inmates are happy to be in jail because they use the prison library. Confronted with the reality of a monitored world, people make the rational decision to make the best of it.

That is not consent.

Maciej Cegłowski

June 14, 2019