Skip to content

Instantly share code, notes, and snippets.

View jamesarosen's full-sized avatar

James A Rosen jamesarosen

View GitHub Profile
@jamesarosen
jamesarosen / addServerTiming.ts
Created October 20, 2022 01:54
addServerTiming is a node function that wraps a sync or async function and adds server-timing headers with the elapsed time.
/**
* @example
* const users = addServerTiming(responseHeaders, 'LU', () => db.fetch('users'))
* @see https://web.dev/custom-metrics/?utm_source=devtools#server-timing-api
*/
export default function addServerTiming<T>(headers: Headers, label: string, callback: () => T): T {
const start = Date.now();
const maybePromise = callback();
if (maybePromise instanceof Promise) {
@jamesarosen
jamesarosen / braintree.tf
Created May 13, 2021 16:55
I'm trying to fetch and parse some JSON in Terraform using jq and I just can't figure it out.
# Braintree publish a list of their CIDR blocks and IP addresses at
# https://assets.braintreegateway.com/json/ips.json
# The body looks like
# {
# "production": {
# "cidrs": [
# "1.2.3.4/5"
# ]
# "ips": [
# "6.7.8.9"
@jamesarosen
jamesarosen / cloudflare-cache.js
Created February 20, 2020 19:20
Caching with Cloudflare
function isCacheable(response) {
const vary = response.headers.get('Vary')
return (
response.status >= 200 &&
response.status < 400 &&
response.status !== 206 &&
response.headers.get('Cache-Control') != null &&
vary !== '_' &&
vary !== '*'
@jamesarosen
jamesarosen / react-state-machines.jsx
Created December 12, 2019 16:52
Using state machines in hook-based React components
const STATUSES = {
initial: {},
fetching: { showLoadingIndicator: true },
fetched: { showResults: true },
error: { showError: true },
}
function Foo() {
const [status, setStatus] = useState(STATUSES.initial)
const [results, setResults] = useState(null)
@jamesarosen
jamesarosen / helper-functions-in-redux.md
Last active June 8, 2023 16:45
Helper Functions in the Redux Store

I have a function that generates image URLs. This function combines some relatively static global configuration with some dynamic data that changes on every invocation. I say "relatively static" because the configuration is loaded asynchronously during the application boot, but remains fixed after that.

Option One

export default async function imageUrl(imageId, { size = 'normal' }) {
  if (imageId == null) return null
  
  const constantsResponse = await fetch('/api/constants')
 const imagesRoot = constantsResponse.json().imagesRoot
@jamesarosen
jamesarosen / 1.1.1.1.md
Created October 11, 2019 16:42
Does 1.1.1.1 resolve .org domains properly?

A friend asked me whether Cloudflare's 1.1.1.1 service was having trouble resolving .org domains. Here are some findings.

From SF:

dig zendesk.com
;; ANSWER SECTION:
zendesk.com.		3432	IN	A	54.172.126.223
zendesk.com.		3432	IN	A	34.206.241.1
zendesk.com.		3432	IN	A	34.225.199.37
@jamesarosen
jamesarosen / notes.md
Last active August 27, 2018 01:18
Quality Engineering
@jamesarosen
jamesarosen / 0-README.md
Created August 25, 2018 23:42
addon-mirage-supprot

The following code will let an ember addon provide an addon-test-support/ folder whose contents get merged into app/mirage/. It excludes addon-test-support/ from the build if mirage is disabled.

See Better Addon Support on the Ember CLI Mirage feature-request board.

@jamesarosen
jamesarosen / emberjs2018.md
Last active May 31, 2018 19:59
Ember 2018 Roadmap

Background

I have been working with Ember since the SproutCore days. I have watched a passionate, dedicated team spend the last 7 years continually improving the framweork and its ecosystem. Along the way, many things have changed (almost always for the better), but some things have remained constant.

Many of the things I say below have been said by others before. I particularly recommend reading Matt McManus's Improve the interoperability of the community and the framework and Chris Garrett's Ember as a Component-Service Framework.

@jamesarosen
jamesarosen / controllers.application.js
Last active May 17, 2018 19:45
query-params-debugging
import Ember from 'ember';
console.clear()
export default Ember.Controller.extend({
appName: 'Ember Twiddle',
clearLog() {
this.get('log').clear()
},
foo: undefined,