# hot-patcher

> Hot method patching framework for handling environmental method differences

Latest version **2.0.1** (published 2023-07-17) · MIT license · 0 weekly downloads

## Install

```sh
npm install hot-patcher
pnpm add hot-patcher
yarn add hot-patcher
bun add hot-patcher
```

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.0.1 |
| Published | 2023-07-17 |
| First published | 2018-07-21 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM |
| Dependencies | 0 |
| Unpacked size | 19.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 3 |
| Author | Perry Mitchell |
| Maintainers | perrymitchell |
| Keywords | patch, override, hot, patch |

## Links

- npm: https://www.npmjs.com/package/hot-patcher
- Repository: https://github.com/perry-mitchell/hot-patcher
- Homepage: https://github.com/perry-mitchell/hot-patcher#readme
- Issues: https://github.com/perry-mitchell/hot-patcher/issues
- npm.io page: https://npm.io/package/hot-patcher

## Alternatives

- [@sindresorhus/slugify](https://npm.io/package/@sindresorhus/slugify.md) — 3.7M weekly downloads
- [solid-js](https://npm.io/package/solid-js.md) — 2.7M weekly downloads
- [expo-glass-effect](https://npm.io/package/expo-glass-effect.md) — 2.5M weekly downloads
- [nanoassert](https://npm.io/package/nanoassert.md) — 780.8K weekly downloads
- [@ffmpeg/ffmpeg](https://npm.io/package/@ffmpeg/ffmpeg.md) — 529.5K weekly downloads

## Recent versions

- 2.0.1 (latest) — 2023-07-17
- 1.0.0-r03 (next) — 2022-11-18
- 2.0.0 — 2022-11-19
- 1.0.0-r02 — 2022-11-18
- 1.0.0-r01 — 2022-11-18
- 1.0.0 — 2022-09-04
- 0.5.0 — 2018-11-06
- 0.4.0 — 2018-08-04
- 0.3.0 — 2018-07-22
- 0.2.0 — 2018-07-21
- 0.1.0 — 2018-07-21

## README

# Hot-Patcher
> Hot method patching framework for handling environmental method differences

![Build status](https://github.com/perry-mitchell/hot-patcher/actions/workflows/test.yml/badge.svg) [![npm version](https://badge.fury.io/js/hot-patcher.svg)](https://www.npmjs.com/package/hot-patcher)

## About

Hot-Patcher provides a simple API to manage patched methods. I found while writing [Buttercup](https://buttercup.pw) that managing overwritten methods between environments (Node/Browser/React-Native) was becoming cumbersome, and having a single _agreed-upon_ method of doing so was the best way to go.

## Installation

Install Hot-Patcher from [npm](https://www.npmjs.com/package/hot-patcher):

```shell
npm install hot-patcher --save
```

**NB:** This is an ESM library.

## Usage

Hot-Patcher is a class and can simply be instantiated:

```typescript
import { HotPatcher } from "hot-patcher";

const hp = new HotPatcher();
```

Hot-Patcher is designed to be used with patchable tools:

```typescript
import { HotPatcher } from "hot-patcher";

export class MyHelper {
    public patcher: HotPatcher;

    constructor() {
        this.patcher = new HotPatcher();
    }

    increment(arg: number): number {
        return this.patcher.patchInline<number>("increment", someArg => {
            return someArg + 1;
        }, arg);
    }
}
```

You can then patch methods when required:

```typescript
import { MyHelper } from "./MyHelper.js";

export function getHelper() {
    const helper = new MyHelper();
    helper.patch("increment", (val: number) => val + 2);
    return helper;
}
```

Patched methods can easily be fetched later:

```typescript
import { getSharedPatcher } from "./patching.js";

const randomString = getSharedPatcher().get("randomString");
randomString(5); // Generates a random string

// Or, execute the method directly:
getSharedPatcher().execute("randomString", 5) // Generates a random string
```

You can check if a method is patched by using `isPatched`: `patcher.isPatched("some method")`.

### Inline patching and execution

Ideally you could wrap function implementation with a patch call, executing it on demand:

```typescript
function add(a: number, b: number): number {
    return patcher.patchInline("add", (a, b) => a + b, a, b);
}

patcher.isPatched("add"); // false
add(1, 2); // 3
patcher.isPatched("add"); // true
// calling add() multiple times will call the patched method without "re-patching" it
// over and over again..
```

### Plugins - Chaining/Sequencing functions

You can use Hot-Patcher to create sequences of functions:

```typescript
patcher.plugin("increment", x => x * 2, x => x * 2);

patcher.execute("increment", 2); // 8
```

Which is basically syntactic sugar for a regular `patch()` call: 

```typescript
patcher
    .patch("increment", x => x * 2, { chain: true })
    .patch("increment", x => x * 2, { chain: true });

patcher.execute("increment", 2); // 8
```

Executing a regular `patch()` without `chain: true` will overwrite all chained methods with the new method. 

Calling `patch()` with `chain: true` when a method already exists will simply add the new method after the existing:

```typescript
patcher
    .patch("increment", x => x * 2, { chain: false }) // or simply without `chain` specified
    .patch("increment", x => x * 2, { chain: true });

patcher.execute("increment", 2); // still 8
```


### Restoring methods
Methods can be restored to their _originally patched function_ by calling the `restore` method:

```typescript
const methodA = () => {};
const methodB = () => {};

patcher
    // methodA is now the current (and original)
    .patch("someMethod", methodA)
    // methodB is now the current
    .patch("someMethod", methodB);

// Restore "someMethod" to methodA (original)
patcher.restore("someMethod");
```

## Use Sparingly

The intention of Hot-Patcher is not to push every method into a patching instance, but to provide a common API for specific methods which _require_ patching in some specific environments or in situations where users/consumers are expected to provide their own custom implementations.

---
_Source: https://npm.io/package/hot-patcher · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
