patcharan

Patch and unpatch JavaScript functions multiple times, in any order.

npm install patcharan

patcharan lets you wrap JavaScript functions with multiple patches and remove them individually — even out of order. Patches are stacked and tracked, so removing one automatically rebuilds the function with the remaining patches intact.

Usage

import { patch, unpatch } from 'patcharan';

const mod = {
  greet(name) {
    return `hello ${name}`;
  }
};

// A patcher receives the original function and returns a replacement
const loud = (orig) => function (...args) {
  return orig.apply(this, args).toUpperCase();
};

patch(mod, 'greet', loud);
mod.greet('world'); // => "HELLO WORLD"

unpatch(mod, 'greet', loud);
mod.greet('world'); // => "hello world"

Stacking patches

Multiple patches can be applied to the same function. When a patch is removed with unpatch, the remaining patches are re-applied in order so the function stays consistent.

const logger = (orig) => function (...args) {
  console.log('called with', args);
  return orig.apply(this, args);
};

const timer = (orig) => function (...args) {
  const start = performance.now();
  const result = orig.apply(this, args);
  console.log(`took ${performance.now() - start}ms`);
  return result;
};

patch(mod, 'greet', logger);
patch(mod, 'greet', timer);

// Remove logger while keeping timer active
unpatch(mod, 'greet', logger);

API Reference

patch(obj, name, patcher)

Wraps obj[name] with the function returned by patcher.

Parameter Type Description
obj object The object that owns the function to patch.
name string Property name of the function to patch.
patcher (original) => replacement Receives the current function and must return the replacement.
unpatch(obj, name, patcher)

Removes a previously applied patcher and rebuilds obj[name] from the remaining patches. Arguments are the same as patch.

Parameter Type Description
obj object The object that owns the patched function.
name string Property name of the patched function.
patcher (original) => replacement The same patcher reference that was passed to patch.