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. |