Skip to content

Instantly share code, notes, and snippets.

@pesterhazy
pesterhazy / promises-cljs.md
Last active April 14, 2025 16:42
Promises in ClojureScript

Chaining promises

Chaining promises in ClojureScript is best done using the thread-first macro, ->. Here's an example of using the fetch API:

(-> (js/fetch "/data")
    (.then (fn [r]
             (when-not (.-ok r)
               (throw (js/Error. "Could not fetch /data")))
             (.json r)))
@pesterhazy
pesterhazy / indexeddb-problems.md
Last active June 13, 2026 04:57
The pain and anguish of using IndexedDB: problems, bugs and oddities

This gist lists challenges you run into when building offline-first applications based on IndexedDB, including open-source libraries like Firebase, pouchdb and AWS amplify (more).

Note that some of the following issues affect only Safari. Out of the major browsers, Chrome's IndexedDB implementation is the best.

Backing file on disk (WAL file) keeps growing (Safari)

When this bug occurs, every time you use the indexeddb, the WAL file grows. Garbage collection doesn't seem to be working, so after a while, you end up with gigabytes of data.

Random exceptions when working with a large number of indexeddb databases (Safari)

(ns scrap.scrap
(:require [clojure.test :as t]))
=>
;;(ns scrap.scrap
(:require [clojure.test :as t]))
@pesterhazy
pesterhazy / memorable-uuids.md
Last active April 1, 2025 16:55
A UUID to remember

In their most used version v4, UUIDs are random, and that's a useful property. But sometimes all you want is a UUID that is easy to remember. To hell with randomness!

A minor complication is that for a string to parse as a valid UUID, the variant and version bits should be set correctly (to 2 and 4, respectively). Here are a few suggestions that pass the test:

facade00-0000-4000-a000-000000000000
decade00-0000-4000-a000-000000000000
@pesterhazy
pesterhazy / promise-wait.js
Last active May 7, 2024 07:12
wait() - promise for waiting for an event
// Returns, in a pair, a new promise along with a callback function
// such that the promise resolves when the callback function
// is called
//
// `wait` seems like a useful function, especially in async unit
// tests. Is this widely known and is there a common name for this
// pattern?
function wait() {
var resolve, p=new Promise(r => { resolve=r });
@pesterhazy
pesterhazy / indexeddb-multiple-tabs.md
Created February 26, 2019 08:37
Offline-first browser apps and multiple tabs

Offline-first browser apps and multiple tabs

For offline-first operation, browser apps cache data in an IndexedDb database. When the user makes a change while offline, they persist the change optimistically. When connectivity is restored, changes are synced to the server.

This pattern is well established today. However, given the possibility of opening the app in multiple tabs at the same time, we seem to be faced with a dilemma:

  • We allow users to use the app and to make changes in multiple tabs at the same time. But then two "threads" are writing to the same shared resource at the same time. Co-ordinating writes seems to be difficult.

    To make things worse, while the localStorage API allows you to register a callback that fires whenever an item is changed outside the current tab, the IndexedDb API doesn't, at least not in a widely-available way.

@pesterhazy
pesterhazy / 0-ripgrep-lispy-word-characters.md
Last active February 14, 2019 15:28
ripgrep: lispy word characters

Experiment to search words using ripgrep

If you use rg -w, ripgrep won't recognize lispy characters like - and + and regular word characters.

But ./rg-lispy-word will.

@pesterhazy
pesterhazy / configuring-zprint.md
Last active January 15, 2019 02:14
Customizing zprint

The zprint auto-formatter for Clojure comes with built-in defaults, but it is also highly customizable. The docs can be a bit daunting, so in what follows I will explain how to set some configuration options that are commonly used.

defn

By default, zprint will move the arg vector of defn forms to a separate line:

@pesterhazy
pesterhazy / lambda-edge-spa.js
Created September 26, 2018 14:56
Lambda@Edge trigger: simple URL rewriting
"use strict";
// Lambda@Edge trigger to serve index.html when the
// user requests /app/*; use in Cloudfront as a viewer-request
// event
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
if (/^\/app($|\/)/.test(request.uri) || request.uri == "/") {
request.uri = "index.html";
@pesterhazy
pesterhazy / temperatures.clj
Created September 9, 2018 16:47
temperatures
(defn temperatures [xs]
(->> xs
(iterate rest)
(take (count xs))
(map (fn [[x0 :as xs]]
(loop [[x & rst] xs
n 0]
(cond (nil? x) 0
(> x x0) n
:else (recur rst (inc n))))))))