TypeScript libraries
Small tools that make
illegal states unrepresentable.
A set of focused, aggressively type-safe libraries. Every doc page here is written and versioned inside the library's own repository — this site just knows where to look.
Buckets
Rules that read like sentences
Declare named conditions over an item once, then declare buckets as boolean expressions over those conditions. Condition names, bucket names and the shape of the report are all inferred.
- Conditions are answered once per item, then reused by every bucket
- Buckets are boolean expressions — AND, OR, NOT, ONLY
- Bucket names and the shape of the report are inferred, not declared
@michaelrwalker/buckets 17 pages Step Queue
Steps that resume exactly where they failed
Define BullMQ jobs as a set of fully type-safe steps. Job data accumulates as it moves through the pipeline, and a retried job resumes on the exact step it left off at.
- Each step is typed against exactly what the steps before it produced
- A retried job restarts on the step it failed on, not from the top
- Wait on child jobs without hand-rolling WaitingChildrenError
@michaelrwalker/step-queue 14 pages {} Stagehand
A failed step rolls back everything that already succeeded
Scripts are phases, phases are steps. Steps have a handler and an optional rollback that fires when a later step fails, with a typed context threaded through the whole run.
- A failing step rolls back every step that already succeeded
- A typed context threads through the entire run
- Live rendering on a TTY, plain line output in CI
@michaelrwalker/stagehand 16 pages Search
Cheap algorithms first, fuzzy ones only if they miss
Register the algorithms you want, hand it a dataset, and decide what order they run in and what happens when one hits. Registering an algorithm widens the pipeline's type, so an unregistered name in the run order is a compile error rather than a silent no-op.
- Registering an algorithm widens the type — an unknown run-order name will not compile
- Eleven algorithms ship, and your own implement the same contract
- Stop at the first hit, or collect everything with matched rows culled
@michaelrwalker/search 15 pages - naive exact —
- kmp substring —
- levenshtein fuzzy —
- soundex phonetic —
Braid
Joins that scale linearly not quadratically
Declare what each detail source is and how it joins. Braid indexes every source once into a Map and does a single lookup per row, so adding a fourth source costs one more pass instead of another scan per row.
- Every source is indexed once, then one lookup per row — O(n + m), not O(n × m)
- Each join widens the output row, so a duplicate name or mismatched key will not compile
- Keys match the way a Map matches: no coercion, so "2" never silently joins 2
@michaelrwalker/braid 16 pages { sku: "TS-100", channel_one : {…} , shopify : {…} , variations : [2] }