# promise-cachify

> Caching for promises

Latest version **1.0.4** (published 2022-03-12) · MIT license · 0 weekly downloads

## Install

```sh
npm install promise-cachify
pnpm add promise-cachify
yarn add promise-cachify
bun add promise-cachify
```

## 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.4 |
| Published | 2022-03-12 |
| First published | 2021-12-16 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 35.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | elvin zhu |
| Maintainers | elvinzhu |
| Keywords | 缓存, 异步, cache, promise, async |

## Links

- npm: https://www.npmjs.com/package/promise-cachify
- Repository: https://github.com/elvinzhu/promise-cachify
- Homepage: https://github.com/elvinzhu/promise-cachify/blob/main/README.md
- Issues: https://github.com/elvinzhu/promise-cachify/issues
- npm.io page: https://npm.io/package/promise-cachify

## Alternatives

- [memory-cache](https://npm.io/package/memory-cache.md) — 795.0K weekly downloads
- [@httptoolkit/proxy-agent](https://npm.io/package/@httptoolkit/proxy-agent.md) — 11.2K weekly downloads
- [express-cache-controller](https://npm.io/package/express-cache-controller.md) — 5.3K weekly downloads
- [http-cache-middleware](https://npm.io/package/http-cache-middleware.md) — 4.5K weekly downloads
- [cache2](https://npm.io/package/cache2.md) — 1.5K weekly downloads

## Recent versions

- 1.0.4 (latest) — 2022-03-12
- 1.0.3 — 2022-03-12
- 1.0.2 — 2021-12-17
- 1.0.1 — 2021-12-16
- 1.0.0 — 2021-12-16

## README

# promise-cachify

[![Build Status](https://app.travis-ci.com/elvinzhu/promise-cachify.svg?branch=main)](https://app.travis-ci.com/elvinzhu/promise-cachify)
[![codecov](https://codecov.io/gh/elvinzhu/promise-cachify/branch/main/graph/badge.svg?v=1)](https://codecov.io/gh/elvinzhu/promise-cachify)

Caching for promises.

## Installation

```
npm install promise-cachify
```

## Features

- Concurrent de-duplication.
- Caching resolved values while ignore rejected.
- Data persistance.
- Data isolation(fresh new data for each return).
- Strong and type-safe cache key generation.
- Customizable (key generation, exipre time... )
- Deletion of cached items.
- Debug mode
- Support two styles of usage.
- Fully typescript-ready.
- No dependencies

## Get Started

### Basic Usage

_.do_ style (recommended)

```ts
import withCache, { setDefaults, DefaultKey } from 'promise-cachify';

const getDetail = withCache(function (id: number) {
  return yourFetchFn('/api/getDetail', { id });
});

await Promise.all([getDetail.do(1), getDetail.do(1), getDetail.do(1)]);
// concurrent request share the same http request.
// so the above results in just 1 http call;
// note the '.do(...)', that explicitly tell the reader
// "hi man, the result is probably from cache! "

await getDetail.do(1); // from cache;
```

_as-it-is_ style

```ts
import { cache, setDefaults, DefaultKey } from 'promise-cachify';

const getDetail = cache(function (id: number) {
  return yourFetchFn('/api/getDetail', { id });
});

await Promise.all([getDetail(1), getDetail(1), getDetail(1)]);
await getDetail(1); // from cache;
```

APIs of Both styles are with the same signature. But APIs are under `getDetail.cache` when _as-it-is_ style.

| style      | API signature | API location | Suitable scene |
| ---------- | ------------- | ------------ | -------------- |
| _.do_      | same          | fn.          | new code       |
| _as-it-is_ | same          | fn.cache.    | old project    |

### Deletion of cached items.

```ts
// clear all cached data for every 'id';
getDetail.clearAll();
// clear cached data for id=1
getDetail.clear(getDetail.getCacheKey(1));
// or the following, if you know how the cache key is generated;
getDetail.clear('$-1');

getDetail.do(1); // from server;
```

### Customize cache key

Most of time you don't need to do this, but this is needed when your params is complex.

```ts
const getDetail = withCache(
  function (id: number) {
    return yourFetchFn('/api/getDetail', { id });
  },
  {
    // same signature as the first argument of withCache
    key: (id) => String(id),
    // key: 'or_your_static_key',
  }
);
```

### Data persistance

```ts
const getDetail = withCache(
  function (id: number) {
    return yourFetchFn('/api/getDetail', { id });
  },
  {
    persist: 'your_global_unique_key',
    // persistMedia: 'sessionStorage', // default. Another available option is "localStorage"
  }
);
// this will respect to `expire` policy
```

### Debug

```ts
const getDetail = withCache(
  function (id: number) {
    return yourFetchFn('/api/getDetail', { id });
  },
  { debug: true }
);
// track cache behavior.
```

### Full example

```ts
const getDetail = withCache(
  function (id: number) {
    return yourFetchFn('/api/getDetail', { id });
  },
  {
    persist: 'CRM_USER_GETDETIAL',
    persistMedia: 'sessionStorage',
    maxAge: 2, // expire after 2 seconds
    debug: true,
    key: (id) => String(id),
  }
);
```

## API

- `do(...args: TArgs): Promise<TOut>`
- `getCacheKey(...args: TArgs): string | null;`
- `clear(key?: TKey): void;`
- `clearAll(): void;`
- `set(data: TOut | Promise<TOut>, key?: TKey): boolean;`
- `get(key?: TKey): Promise<TOut> | null;`
- `getAll(): Map<string, ICacheItem>;`
- `has(key?: TKey): boolean;`

## Key generation

auto-key-generation only supports signature with the following constraints;

```ts
type TValue = string | number | boolean;
fn(...args: ({ [key: string]: TValue } | TValue | TValue[])[])
```

- arguments that not satisfy the above constraints will cause no cache.
- the keys of an object will be sorted.
- none-string value will be prefixed with `$-`
- use default key if no arguments or one argument with `undefined` value

examples

| signature                                | key                                 |
| ---------------------------------------- | ----------------------------------- |
| fn({ id: 1, name: 'xx', age: 1 })        | 'age=\$-1&id=$-1&name=xx'           |
| fn({ name: 'xx', age: 1, id: 1 })        | 'age=\$-1&id=$-1&name=xx'           |
| fn('1', [1, '2'], { id: 1, name: null }) | '1&[\$-1_2]&id=\$-1&name=\$-null'   |
| fn({ id: 1 }, { id: 2 })                 | 'id=$-1&id=\$-2'                    |
| fn([1], ['2'])                           | '[\$-1]&[2]'                        |
| fn({})                                   | '{}'                                |
| fn(null)                                 | '$-null'                            |
| fn('null')                               | 'null'                              |
| fn() or fn(undefined)                    | '\_\_INTERNAL_USE\_\_'              |
| fn({ id: 1, d: { name: 'el' } })         | null and no cache will be performed |

see more at the first test case in `__test__/index.test.ts`

## Compatibility

browsers that support or polyfilled `Map` `Promise`

## Licence

MIT

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