npm package: @opdime/cache
Description: A simple higher order function to generate cached copies of functions.
Author: Jörn Neumeyer
Latest version: 0.5.2

# Cache-JS

---
Cache-JS is a library which makes it easy to create cached versions of a function which takes a long time to execute. This caching can be applied on asynchronous functions as well as synchronous functions.
At the moment, there are three possible ways to create a cached function: one way for synchronous functions and two ways for asynchronous functions. The reasoning for this will be shown later. First, let's have a look on how we can create a cached versions of a synchronous functions.

__Note! Only primitive arguments (`string`, `number`, `boolean`) are taken into account for caching! If the function you want to cache requires an object for configuration, consider wrapping it into another function which then only takes primitive values as arguments.__

__Note!__ By setting the `repackDeep` flag to true, the function will always create a deep copy of the value which has been stored in the cache. Otherwise it will just create a flat copy to remove the common reference to the cached object.

__Note!__ If a cached value is strictly equal to `undefined`, the original function is going to be executed, to retrieve an up-to-date result. __That will not result in a recursive call until a non-`undefined` is returned!__ It will only call the original once again, not regarding the type of the result of the result. However, this does not apply, if the function returns `null`! That is a valid result because the library does not check based on truthiness, but on the actual value not being `undefined`.

#### `cache(original, repackDeep = false)`

The normal cache function takes a function as its onliest argument and returns a new function, which uses a cache to store function result and arguments.
If the wrapped function returns an object or an array, it will automatically destructure that object and repack it into a new object/array, so the cache and the returned result to not share a common reference.

```javascript
const { cache } = require('@opdime/cache');
// or
import { cache } from '@opdime/cache';
// later imports will only be in this ES6 format
function someExpensiveMathematicalFunction(x, y, z) {
  // maybe much vector calculus..
  // with some factorials inbetween..
  return {
    x, y, z
  };
}

const cachedFunction = cache(someExpensiveMathematicalFunction);
```

The resulting function, which is stored in `cachedFunction`, can be executed just as the normal function.

#### `cacheAsync(original, repackDeep = false)`

`cacheAsync` expects its original function to always return a promise. Therefore, `cacheAsync` will always return an _async_ function, which alwaysw returns a `Promise`.

```javascript
import { cacheAsync } from '@opdime/cache';

const fetchFromApi = () => fetch('http://api.example.com/slow/');

const fetchCached = cacheAsync(fetchFromApi);
```

#### `cacheAsyncWithTimeLimit(original, limit,repackDeep = false)`

`cacheAsyncWithTimeLimit` works similar to `cacheAsync`. The main difference is, that it also expects a limit of seconds, after which a cached result is invalid. After the given time, the cached value will automatically be invalidated. So, the value for the passed parameters will be fetched by the original function again. The newly fetched value will then also be invalidted after the given time.

```javascript
import { cacheAsyncWithTimeLimit } from '@opdime/cache';

const fetchFromApi = () => fetch('http://api.example.com/slow/');

// calling
const fetchCached = cacheAsyncWithTimeLimit(fetchFromApi, 20);
```