Skip to content

Instantly share code, notes, and snippets.

// Zero-Clause BSD (more permissive than MIT, doesn't require copyright notice)
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
@mikelehen
mikelehen / generate-pushid.js
Created February 11, 2015 17:34
JavaScript code for generating Firebase Push IDs
/**
* Fancy ID generator that creates 20-character string identifiers with the following properties:
*
* 1. They're based on timestamp so that they sort *after* any existing ids.
* 2. They contain 72-bits of random data after the timestamp so that IDs won't collide with other clients' IDs.
* 3. They sort *lexicographically* (so the timestamp is converted to characters that will sort properly).
* 4. They're monotonically increasing. Even if you generate more than one in the same timestamp, the
* latter ones will sort after the former ones. We do this by using the previous random bits
* but "incrementing" them by 1 (only in the case of a timestamp collision).
*/
@jbmoelker
jbmoelker / README.md
Created March 12, 2017 14:34
Immutable caching of static assets with Express.js and Service Worker

Immutable caching of static assets with Express.js and Service Worker

This recipe revisions all asset files in a dist/assets/ directory using gulp-rev. The adds a unique content based hash to each asset file. The pattern of that hash (/.*-[0-9a-f]{10}\..*/) is then used to handle these files in Express.js and the Service Worker. Express.js sets the Cache-Control header to immutable. The Service Worker serves these files directly from cache without ever attempting the server again.

@na2hiro
na2hiro / Remix-request-cheatsheet.md
Last active March 18, 2024 02:42
Remix request cheatsheet
@cjavilla-stripe
cjavilla-stripe / webhooks.tsx
Created March 25, 2022 13:11
Handle Stripe webhooks in Remix
import Stripe from 'stripe'
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY)
export const action = async ({request}) => {
const secret = 'whsec_...' // process.env.WEBHOOK_SIGNING_SECRET
const sig = request.headers.get('stripe-signature')
let event;
const payload = await request.text()
// TODO: make `pages` optional and measure the div when unspecified, this will
// allow more normal document flow and make it easier to do both mobile and
// desktop.
import {
createContext,
useCallback,
useContext,
useEffect,
useMemo,
useRef,

Remix's useFetcher doesn't return a Promise for any of its methods (like fetcher.submit()) because Remix doesn't want you to explicitly await anything so they can handle things like cancellation for you. Instead, they recommend adding a useEffect and performing whatever logic you need to after the fetcher is in a particular state.

I found using an effect to run some logic after a submission to be too indirect, and there seem to be plenty of cases where you want to submit a form and then perform some other work on the client (sometimes async, like requesting the user's permission for their location), and I'd rather just do that after a submission in the event handler rather than an effect.

So here's a proof of concept hook that wraps Remix's useFetcher and returns a version of submit that is a promise, and resolves with the data from the action:

function useFetcherWithPromise() {
  let resolveRef = useRef();
  let promiseRef = useRef();
@nandorojo
nandorojo / eas-update-sentry.ts
Last active January 11, 2024 02:03
EAS Update + Sentry Source Maps
import { getConfig } from '@expo/config'
import fs from 'fs'
import spawnAsync from '@expo/spawn-async'
import chalk from 'chalk'
import path from 'path'
const appDir = process.cwd()
console.log()
console.log(chalk.green('Sentry source maps script. Working directory:'))