Skip to content

Instantly share code, notes, and snippets.

View tom-sherman's full-sized avatar

Tom Sherman tom-sherman

View GitHub Profile
function wrapWithSignal(ms, fn) {
const signal = AbortSignal.timeout(ms)
return fn(signal)
}
function foo() {
return wrapWithSignal(signal => fetch("/", {signal}))
}
try {
The following is text converted from an email received from Aiven support using OCR software:
Hello:
Aiven recently experienced an internal security issue which has been remediated.
However, we require some additional action from affected customers.
What went wrong
When enabling multi-factor authentication in the Aiven console, there is a modal
pop-up on s.creen asking for the user to supply their password. After entering the
password, if the user pressed the "Enter" key instead ot clicking on the "Next"
button, the value of the password field was sent as a GET parameter alongside
@tom-sherman
tom-sherman / typescriptreact.json
Created July 7, 2023 19:35
Next.js server component vs code snippets
{
"Next.js Layout": {
"prefix": "nextjs-layout",
"body": [
"export default function Layout({ children }: { children: React.ReactNode }) {",
" $0",
"}"
]
},
"Next.js Page": {
export function Layout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
{children}
</body>
</html>
);
}
@tom-sherman
tom-sherman / shiki.tsx
Created April 15, 2023 13:03
Perfect syntax highlighting with Shiki and React Server Components in under 50 lines of code
import { getHighlighter as shikiGetHighlighter } from "shiki";
import { cache } from "react";
interface ShikiProps {
code: string;
lang: string;
theme: string;
}
export async function Shiki({ code, lang, theme }: ShikiProps) {
type RouteParams<string> = Record<string, string>;
type RouteParams<`${infer Start}:${infer Param}/${infer Rest}`> = {[k in Param | keyof RouteParams<Rest>]: string};
type RouteParams<`${infer Start}:${infer Param}`> = {[k in Param]: string};
type RouteParams<unknown> = {};
import * as React from "react";
import { ImageResponse } from "workers-og";
interface Env {}
export default {
async fetch(
request: Request,
env: Env,
ctx: ExecutionContext
@tom-sherman
tom-sherman / dynamoDbSessionStorage.ts
Created August 3, 2022 13:56
Remix session storage implementation using DynamoDB
import * as crypto from "node:crypto";
import type {
SessionIdStorageStrategy,
SessionStorage,
} from "@remix-run/server-runtime";
import { createSessionStorage } from "@remix-run/node";
import { DynamoDB } from "aws-sdk";
interface DynamoDbSessionStorageOptions {
/**
@tom-sherman
tom-sherman / App.res
Created June 12, 2022 08:38
WIP - use-effect-reducer in ReScript
type effect
@module("use-effect-reducer")
external useEffectReducer: (
@uncurry (
'state,
'action,
@uncurry ((('state, unit, @uncurry ('action => unit)) => option<unit => unit>) => effect),
) => 'state,
'state,
@tom-sherman
tom-sherman / assertEventType.ts
Created December 23, 2021 08:09
XState Event Type Invariant
import { EventObject } from 'xstate';
export function assertEventType<
TEvent extends EventObject,
TType extends TEvent['type']
>(
event: TEvent,
type: TType
): asserts event is Extract<TEvent, { type: TType }>;
export function assertEventType<