# fn.locky

> Lock utils for asynchronous function to avoid concurrent calls

Latest version **1.0.0** (published 2023-08-25) · MIT license · 0 weekly downloads

## Install

```sh
npm install fn.locky
pnpm add fn.locky
yarn add fn.locky
bun add fn.locky
```

## 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 | 1.0.0 |
| Published | 2023-08-25 |
| First published | 2023-06-16 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 72.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | calvin_von |

## Links

- npm: https://www.npmjs.com/package/fn.locky
- Repository: https://github.com/CalvinVon/fn-lock
- Homepage: https://github.com/CalvinVon/fn-lock#readme
- Issues: https://github.com/CalvinVon/fn-lock/issues
- npm.io page: https://npm.io/package/fn.locky

## Dependencies (1)

- [lodash.isequal](https://npm.io/package/lodash.isequal.md) ^4.5.0

## Recent versions

- 1.0.0 (latest) — 2023-08-25
- 1.0.0-beta — 2023-06-17
- 0.0.0-alpha.0 — 2023-06-16

## README

# fn.locky

Lock utils for asynchronous function to **avoid concurrent calls**.

[![npm](https://img.shields.io/npm/v/fn.locky)](https://www.npmjs.com/package/fn.locky)
![npm](https://img.shields.io/npm/dt/fn.locky)
![Codecov](https://img.shields.io/codecov/c/github/CalvinVon/fn.locky)
![npm bundle size](https://img.shields.io/bundlephobia/minzip/fn.locky)
![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/CalvinVon/fn.locky/node.js.yml)

- ✨ Written in **TypeScript**
- ✨ Lock/unlock **automatically**
- ✨ **100%** **Tests** coverage
- ✨ Support **Tree-Shaking**
- ✨ **732 B + 5.4 KB** gzip *([subpath import](#subpath-import))*

## Install

```bash
npm i fn.locky -S
```

## Usage

This package contains two useful tools:

- **AsyncLock**: A semantic encapsulation based on `Promise`, controls the function execution flow manually.
- **lockify**: A higher-order function, for adding lock protection to the functions, fully automatic locking and unlocking

### Basic usage

use `AsyncLock` in functions

```ts
import { Lock, AsyncLock } from "fn.locky";
// create
const lock = Lock.createAsyncLock();
// or
const lock = new AsyncLock();

// lock
lock.lock();

// inside the function
// judge status to wait or continue
if (lock.locked) {
  // waiting util unlock
  await lock.pending;
}
console.log('done');

// outside the function
// unlock
lock.unlock(); // log 'done'
```

### Advanced usage ✨✨

**`lockify`**

Convert a `lockable` function to a `lockified` function, manage locking and unlocking **automatically**.

> Yep, we do distinguish between different function parameters, see these test cases for details

```ts
import { lockify } from "fn.locky";

let count = 0;
const asyncFn = (param1, param2) =>
  new Promise((resolve) => {
    // mock request
    setTimeout(() => {
      // do something with param1 and param2
      resolve({ success: true, count: count++ }); // auto unlock the (inner) lock
    }, 1000);
  });

const lockified = lockify(asyncFn);

// concurrent calls
const result_1 = lockified();
const result_2 = lockified();
const result_3 = lockified();

// after first call resolves:
// count: 1
// result_1, result_2, result_3: { success: true, count: 1 }
```

> **NOTICE**:
>
> - We assume that the lockable function should be a pure function( fn(x) always
return y, what means the function has no side effects ), so the other waiting
calls would return the same result immediately when unlocking instead of re-calling
the original `lockable` function.
> - lockify not support `lockable` functions that use `arguments` object inside
or something like `rest parameter`. Cause we cannot tell whether the function
has parmaters list or not. In this case, you should pass another parameter
`useParams` manually

### subpath-import

You can only import `Lock` class, it only costs **732 B** !

> **Additions**: You may set `moduleResolution` field to `node16`/`nodenext` in your `tsconfig.json`, see [here](https://www.typescriptlang.org/tsconfig#moduleResolution).

```ts
import { Lock, AsyncLock } from "fn.locky/lock";
import { lockify } from "fn.locky/lockify";
```

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