Skip to content

Instantly share code, notes, and snippets.

View alii's full-sized avatar
🗿
compuoter

Alistair Smith alii

🗿
compuoter
View GitHub Profile

Keybase proof

I hereby claim:

  • I am aabbccsmith on github.
  • I am aabbccsmith (https://keybase.io/aabbccsmith) on keybase.
  • I have a public key ASAjdhw9WSY3MWPwMArg_1ctDRGffZppjkLhWZSfdSUBIgo

To claim this, I am signing this object:

@alii
alii / nadine.txt
Created September 22, 2020 22:26 — forked from jmwind/nadine.txt
What is this all about?
// Please don't fork this!
// One
@alii
alii / notifications.ts
Created January 19, 2021 13:31
Notification permissions system with Permer
import { Permer } from "permer";
const permer = new Permer(["web", "email"]);
type NotificationSettings = {
user_id: number;
review_comment: number;
user_likes_review: number;
user_comment_review: number;
user_like_list: number;
@alii
alii / wrap-redis.ts
Last active September 26, 2023 23:07
wrap-redis.ts
async function wrapRedis<T>(key: string, fn: () => Promise<T>, seconds = 60): Promise<T> {
const cached = await redis.get(key);
if (cached) return JSON.parse(cached);
const recent = await fn();
if (recent) {
await redis.set(key, JSON.stringify(recent), 'ex', seconds);
}
/**
* Handle clicks outside of an element.
* This is useful for closing a modal by clicking outside of the modal.
* @param callback - The callback function to run when clicking outside of an element
*/
export function useOutsideClick<E extends HTMLElement = HTMLElement>(callback: () => unknown) {
const container = useRef<E | null>(null);
useEffect(() => {
const handler = (event: MouseEvent) => {
@alii
alii / use-throttle.ts
Created July 7, 2021 00:14
use-throttle.ts
export function useThrottle<T>(value: T, limit = 1000) {
const [throttledValue, setThrottledValue] = useState(value);
const lastRan = useRef(Date.now());
useEffect(() => {
const handler = setTimeout(() => {
if (Date.now() - lastRan.current >= limit) {
setThrottledValue(value);
lastRan.current = Date.now();
}
@alii
alii / ensure-keys.ts
Created August 25, 2021 14:12
Infer object values while strictly specifying keys in TypeScript
/**
* TypeScript currently lacks a way of typing a record of keys only but not values.
* we need this because we want an object of typed keys but we want to leave the values inferred.
* thankfully, we can do this with generics. This function allows the second generic's values to be inferred
* so that our object is fully type safe for hugely complex types, but we can guarantee that all the keys we need exist.
* It's not perfect, but it gets the job done for the time being
*/
export function ensureKeys<T>() {
/**
* Function that returns the value that gets put in, values are type-safely inferred
@alii
alii / pick.ts
Created August 25, 2021 14:21
Pick a subset of keys from an object in a type-safe fashion
/**
* Pick a subset of keys from an object in a type-safe fashion
* @param obj
* @param keys
*/
export function pick<T, K extends Array<keyof T>>(
obj: T,
keys: K
): Pick<T, K[number]> {
return Object.fromEntries(
@alii
alii / ts-fun.ts
Created September 6, 2021 17:24
typescript fun with generics
// Was having some fun with TypeScript and built a signature for some theoretical
// object that could cast any type to any other type. This uses template literal types,
// generics, infer and mapped types.
import {Except} from 'type-fest';
type TypeofsTypes = {
string: string;
number: number;
bigint: BigInt;
@alii
alii / join.ts
Last active September 29, 2021 16:20
ridiculously type-safe Array<string>.join()
/**
* Joins a string array together with a given spacer. Ridiculously unecessarily type-safe!
* @param t The tuple/array of string items to join together
* @param s The spacer to go between each character
* @returns A joint string joined together
*/
export function join<V extends string, Tuple extends Readonly<[V, ...V[]]>, Spacer extends string>(
t: Tuple,
s: Spacer
) {