Skip to content

Instantly share code, notes, and snippets.

View bmeck's full-sized avatar

Bradley Farias bmeck

View GitHub Profile
bmeck@Bradleys-MacBook-Pro promise-diagnostics-hook % sh ./cover.sh node ./test.mts
Unused Promise 64 (allocated 1 times):
node:internal/deps/undici/undici:6402:24
node:internal/deps/undici/undici:6:50
node:internal/deps/undici/undici:8095:21
node:internal/deps/undici/undici:6:50
node:internal/deps/undici/undici:8548:18
node:internal/deps/undici/undici:6:50
node:internal/deps/undici/undici:8649:16
node:internal/deps/undici/undici:6:50
@bmeck
bmeck / hooks.mjs
Created July 14, 2025 14:57
A WIP helper that needs some love around detecting wasted Promise usages
// LICENSE: MIT License
import {
triggerAsyncId,
createHook,
executionAsyncId,
} from "node:async_hooks"
import fs from 'node:fs'
import { debug as createDebug } from "node:util"
let log_raw = new Set()
@bmeck
bmeck / bench.mjs
Created July 9, 2025 20:20
Why I want a sane await deferal and cache
import { createHook } from 'node:async_hooks';
let ticks = 0
const asyncHook = createHook({
before() {
ticks++
},
});
asyncHook.enable();
let normal = Promise.resolve('cloud_secret');
alert('GOOD')

If you have ever had to deal with Promise heavy code, and in particular deep data structures you will likely be familiar with code like the following:

const body = await (await fetch(url)).json()

This has a LHS RHS interchange that causes non-linear edits while writing code (especially with autocomplete):

fetch(url) // LTR
/// <reference types="node" />
// See NOTES below
import flatstr from 'flatstr'
import v8 from 'v8'
// @ts-check
class ArrayOfObjects {
store = []
constructor(count) {
// node [--trace-gc] local-storage-exmaple.cjs
// creates a server
// will drop /favicon.ico connections poorly without properly closing them
// `cleanupContext` AsyncLocalStorage + `cleanup` FinalizationRegistry will clean up
// will track the http request URL for errors in httpContext
// will show up in error generated for bad permissions
// will grant permissions in permissionsContext based upon query params / search params
// need ?fs=true to make / respond with a 200
//
// goto /?fs=true in browser to see it work
// node [--trace-gc] local-storage-exmaple.cjs
// creates a server
// will drop /favicon.ico connections poorly without properly closing them
// `cleanupContext` AsyncLocalStorage + `cleanup` FinalizationRegistry will clean up
// will track the http request URL for errors in httpContext
// will show up in error generated for bad permissions
// will grant permissions in permissionsContext based upon query params / search params
// need ?fs=true to make / respond with a 200
//
// goto /?fs=true in browser to see it work
import util from 'util';
const promiseDebugging = util.debuglog('promises').enabled;
const danglingPromise = new FinalizationRegistry((stack) => {
danglingStacks.delete(stack);
console.log(stack);
});
const danglingStacks = new Set();
const stackCache = new WeakMap();
/**
* @template T
@bmeck
bmeck / wip.mjs
Created June 24, 2021 14:00
in-progress in-thread heapsnapshot reflective API
import * as ns from './index.js';
import {promisify} from 'util';
import {createReadStream, createWriteStream} from 'fs';
import {Session} from 'inspector';
import {PassThrough} from 'stream';
import {createHash} from 'crypto';
const session = new Session();
const stream = new PassThrough();