RSSAmplifier

Blog

Jim Fisher’s blog

jameshfisher.comRSS feed ↗10 posts

Latest posts

The migration SQL should go in the table

So you run migrate in your dev environment, but it fails: some unknown migration add-foobar has already been applied from some other experimental branch, and the migration tool doesn’t know how to down-migrate it. To fix it, you have to hunt for the branch that created that migration, to find its down-migration SQL. Hopefully you still have that migration! I want migrate to always get me to my…

A job queue in two lines of JS

If you need a job queue in JS, you can do it in two lines: type Job = ( ) => Promise < unknown > ; let chain = Promise . resolve ( ) ; const enqueue = ( job : Job ) => chain = chain . then ( job , job ) ; For example, if your app makes API requests, you may need requests to be processed in the order they were dispatched: function setDone ( id : string , done : boolean ) { enqueue ( ( ) => fetch (…

Sticky snap: a better snapping algorithm

The “snapping” feature in most drawing apps has a problem: you can’t place the object near snap lines, so for precise positioning, you have to disable snapping. In this post, I show sticky snap , a better algorithm. But first, try to place the green rectangle at the target using the standard snap algorithm: You’ll soon find that it’s impossible to reach! The snap lines always pull the object out…

`window.ai` hello world

If you’re running Chrome with the window.ai API, here’s a UI to prompt an LLM running locally in your browser: Prompt Top K: Temperature: Run prompt Status: Output I wrote these TypeScript type definitions for the API: declare global { interface WindowOrWorkerGlobalScope { readonly ai ? : { canCreateTextSession ( ) : Promise < "readily" | "after-download" | "no" > ; createTextSession ( options ? :…

Interactive Turing patterns in WebGPU

Below is an interactive Turing pattern. It follows Karl Sims’ model . It’s implemented in WebGPU. Feed Rate: 0.055 Kill Rate: 0.062

WebGPU hello world in 2024

Below is a Game of Life simulation. It uses WebGPU. Here’s the essential JavaScript: const canvas = document . getElementById ( "example-canvas" ) ; if ( ! navigator . gpu ) { throw new Error ( "WebGPU not supported on this browser." ) ; } const adapter = await navigator . gpu . requestAdapter ( ) ; if ( ! adapter ) { throw new Error ( "No appropriate GPUAdapter found." ) ; } const device = await…

What is Monte Carlo integration?

What’s the average distance that someone can jump? Let’s estimate it! I have a silly function that gives me the distance that someone can jump, based on their height h in centimeters: function jumpDistance ( h : number ) : number { return h < 0 || h > 360 ? 0 : 300 * Math . sin ( h * ( Math . PI / 400 ) ) ; } Next we’ll describe the heights of people in the population. To start, let’s say the…

How to escape JavaScript for a script tag

To add JavaScript to a web page, we use a <script> tag like this: < script > console . log ( "Hello!" ) ; </ script > But what if we need to add arbitrary JavaScript to our web page? Say, a valid script like this?: if ( x < ! -- y ) { ... } We can’t just write that in a <script> tag, because the browser will interpret the <!-- as the start of an HTML comment! “But that’s fine,” you think. “We can…

On that flickering blur in Chrome

backdrop-filter: blur is a popular design for navbars. But it’s unusable in its current state, due to its flickery appearance in Chrome. Here’s an example: A heading Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.…

What is the Metropolis algorithm?

We could estimate Bob’s lunch tomorrow by counting the previous lunches you’ve seen him eating in the cafeteria: Lunch Count Apple 2 Banana 3 Now we want to simulate Bob’s future lunches. Assume Bob randomly picks a lunch each morning, with the relative proportions you’ve observed. Then we can simulate Bob’s lunch with: type Meal = "Apple" | "Banana" ; function sample ( ) : Meal { return Math .…