Skip to content

Instantly share code, notes, and snippets.

View TCotton's full-sized avatar
🎯
Focusing

Andrew Walpole TCotton

🎯
Focusing
View GitHub Profile
@TCotton
TCotton / branded.ts
Last active November 29, 2025 12:20
branded types
/**
Branding in TypeScript is a technique for creating opaque, nominal, or distinct types even when they
have the same underlying structure.
It’s one of the most useful advanced type tricks in TS, because the language is otherwise structurally typed. **/
// Branding:
// Makes structurally identical types distinct
@TCotton
TCotton / effect-drizzle-error-handling.ts
Created November 26, 2025 15:42
Effect PostgreSQL and Drizzle with error handling
import { DbSchema } from '@repo/database/schema'
import { type ExtractTablesWithRelations } from 'drizzle-orm'
import { drizzle, type NodePgDatabase, type NodePgQueryResultHKT } from 'drizzle-orm/node-postgres'
import { type PgTransaction } from 'drizzle-orm/pg-core'
import { Cause, Context, Data, Effect, Exit, Layer, Option, Redacted, Runtime } from 'effect'
import * as pg from 'pg'
type TransactionClient = PgTransaction<
NodePgQueryResultHKT,
typeof DbSchema,
@TCotton
TCotton / useful.ts
Last active November 29, 2025 10:40
TypeScript cheatsheet
// return types from functions
type P = ReturnType<typeof dateFromUUIDv7>;
// return type with promise
type P = Awaited<ReturnType<typeof dateFromUUIDv7>>;
// see all types
type PrettifyPromise<T> = {
[K in keyof T]: T[K] extends Promise<infer U> ? U : T[K];
} & {}
@TCotton
TCotton / briggs.hs
Created October 26, 2025 17:04
Use of every and superimpose
d3
$ every 4 ( superimpose
( slice 2 (fast "2" "[1 2 3 4]" ) -- re-slice give variation of slight glitch
. (|+| gain "0.1") -- slightly louder
. ( # sound "bd*4") -- different sound from the bDrums
))
$ every 2 ( superimpose
( (|+| gain "-0.2") -- slightly quieter
. (0.25 <~) -- delay by 1/4 cycle
. (slice 4 (fast "2" "[1 3 2 4]")) -- re-slice + rearrange
let spread1 = (spread ($) [jux rev, rev])
spread2 = spread ($) [density 2, rev, slow 2, striate 3, (# speed "0.8")]
juxrev = jux rev
revEffect = rev
palindrom = palindrome
fadeOut = range 1 0 $ slow 16 saw
in d4 $ stack [(
slow 2
$ chop 32
$ sound "piano_c"
@TCotton
TCotton / demo.hs
Last active September 19, 2025 17:19
Example of TidalCycle and as used on the YouTube demonstraton
cps (120/60/4)
-- drum patterns in do block
do
let drumz1 = every 4 (|> sound "drum")
$ sound "[drum <dr:2>] drum *2"
# gain 0.7
# orbit 0 -- routed to audiochannel 1-2
let drumz2 = sound "[drum <dr:1>] drum [drum <techno:5>] drum /2"
@TCotton
TCotton / tidalCycle-example
Created September 10, 2025 14:56
TidalCycle example
setcps (120/60/4)
-- drum patterns in do block
do
let drumz1 = every 4 (|> sound "drum")
$ sound "[drum <dr:2>] drum *2"
# gain 0.6
# orbit 0
let drumz2 = sound "[drum <dr:1>] drum [drum <techno:5>] drum /2"
@TCotton
TCotton / typescript-autocomplete.ts
Created August 19, 2025 07:26
typescript autocomplete
type AutoComplete =
| 'astring'
| 'bstring'
| 'cstring'
| (string & {})
@TCotton
TCotton / not-enum.ts
Created August 19, 2025 05:55
Better TypeScript ENUMs
const LOG_LEVEL = {
DEBUG: "DEBUG",
WARNING: "WARNING",
ERROR: "ERROR",
} as const
type ObjectValues <T> = T[keyof T];
type LogLevel = ObjectValues<typeof LOG_LEVEL>
@TCotton
TCotton / hook.js
Created May 17, 2021 10:55
Stale data invalidation
const swr = new Map;
const useSWR = (path, fetcher, cache) => {
let [data, update] = useState(null);
if (!swr.has(path) || swr.get(path) !== cache) {
fetcher(path).then(update, () => update(new Error(path)));
swr.set(path, cache);
}
const isError = data instanceof Error;
return {