Skip to content

Instantly share code, notes, and snippets.

View samwightt's full-sized avatar
🔍
ast-grep stan

Sam Wight samwightt

🔍
ast-grep stan
View GitHub Profile
@samwightt
samwightt / missing-done-callback-in-subscribe.yml
Last active September 8, 2025 18:42
ast-grep rule for when you're missing a `done` callback in an observable's `subscribe`. Only triggers when there are assertions inside the subscribe as we don't want to be too hasty.
language: TypeScript
id: missing-done-callback-in-subscribe
message: When subscribing to an observable inside a test function, you must call the 'done' function. Otherwise the assertions will never run.
severity: error
note: |
When testing observables in Jest, you must call the `done()` function in the subscribe callback. Jest provides a `done` function to test functions that must be executed to let Jest know when the test is done.
If you don't call the done function, the assertions will never run because Jest will finish the test before the subscribe callback is called.
If possible, it is encouraged to use `firstValueFrom` or `lastValueFrom` instead of subscribing to an observable directly in a test function. These handle subscribing / unsubscribing for you.
@samwightt
samwightt / bun-concurrent.ts
Last active September 4, 2025 16:00
Runs a list of commands concurrently using bun. npm-run-all but in less than 100 lines of code.
interface Runnable {
name: string;
command: string[];
}
function createPrefixedWriter(prefix: string, output: Bun.BunFile) {
let buffer = "";
// Tried implementing this using a TransformStream but Bun didn't like it for some reason. So we use a
// WritableStream and Bun.write instead :(
@samwightt
samwightt / ast-grep-codeowners.js
Last active July 15, 2025 15:28
Break down ast-grep results by github codeowners.
const { execSync } = require('child_process');
const fs = require('fs');
// Simple glob to regex conversion
function globToRegex(glob) {
const escaped = glob
.replace(/[.+^${}()|[\]\\]/g, '\\$&') // Escape regex special chars
.replace(/\*/g, '.*') // Convert * to .*
.replace(/\?/g, '.'); // Convert ? to .
import {
Owner,
type Evolu,
type EvoluSchema,
type QueryResult,
type SyncState,
} from "@evolu/common";
export * from "@evolu/common";
export * from "@evolu/common-web";
@samwightt
samwightt / hello-world.js
Created April 20, 2024 17:27
Asking Claude to write Hello World
// I asked Claude to write Hello World. Then I continually asked it to extract new classes until we got the below.
// Introducing the world's most complicated Hello World program.
class Printable {
toString() {
throw new Error('toString() method must be implemented');
}
}
class MessageCreator {
@samwightt
samwightt / go.mod
Last active February 16, 2022 07:20
Ebiten example with perlin noise generation
module samw.dev/ebiten
go 1.15
require (
github.com/aquilax/go-perlin v1.1.0
github.com/hajimehoshi/ebiten/v2 v2.2.4
)
export function bootstrap() {
// All of your code for setting stuff up should go in here.
// This will be run once when our module loads, and then again on every reload.
}
export function teardown() {
// This is where you delete anything you created. For instance, if you add a canvas element
// using JS, you should remove that here. Any listeners should be removed as well.
}
@samwightt
samwightt / utils.ts
Created September 3, 2021 16:40
Non-shitty angle.js
//////////////////////////////////////////////////////////////////////////////
//
// Angel.js
//
//////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
//
// Helper functions
//
import currentUser from "app/auth/queries/currentUser"
// You'd need some sort of transform to evaluate this function and turn it into an object
// that could be passed to the server. You could just replace the definition of the `currentUser`
// function with:
// const currentUser = (args) => args
// and then just send the returned params to the server.
export const query = currentUser();
// This displays when the query is loading.
@samwightt
samwightt / channelManager.ts
Last active May 18, 2023 22:15
Channel Manager
/**
* This is a small library I wrote when I was doing R&D work and needed a way to communicate
* between an iFrame on the same domain and its parent tab. The existing browser API kinda sucked
* and had a lot of issues, and it wasn't particularly enjoyable to use. So I made this small library to solve that.
*
* The library allows you to communicate using *channels*, which are just streams of events with a given name.
* You can subscribe to events of a particular type. Each event type has its own event queue, and each subscriber
* must subscribe to a particular event type. This keeps things simple and fast.
*
* Events are buffered and sent asychronously. There are two ways to send events: firing and blocking.