# cache-base [![NPM version](https://img.shields.io/npm/v/cache-base.svg?style=flat)](https://www.npmjs.com/package/cache-base) [![NPM monthly downloads](https://img.shields.io/npm/dm/cache-base.svg?style=flat)](https://npmjs.org/package/cache-base) [![NPM total downloads](https://img.shields.io/npm/dt/cache-base.svg?style=flat)](https://npmjs.org/package/cache-base) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/cache-base.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/cache-base)

> Basic object cache with `get`, `set`, `del`, and `has` methods for node.js/javascript projects.

Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.

- [Install](#install)
- [Quickstart](#quickstart)
- [API](#api)
- [Usage examples](#usage-examples)
- [About](#about)

_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_

## Install

Install with [npm](https://www.npmjs.com/):

```sh
$ npm install --save cache-base
```

## Quickstart

```js
const CacheBase = require('cache-base');
const app = new CacheBase();

app.set('a.b', 'c');

console.log(app.cache.a);    //=> { b: 'c' }
console.log(app.cache.a.b);  //=> 'c'

console.log(app.get('a'));   //=> { b: 'c' }
console.log(app.get('a.b')); //=> 'c'
```

More [usage examples](#usage-examples) below.

## API

**Params**

* `prop` **{String|Object}**: (optional) Property name to use for the cache, or the object to initialize with.
* `cache` **{Object}**: (optional) An object to initialize with.

**Example**

```js
const app = new CacheBase();
```

### [.set](index.js#L65)

Assign `value` to `key`. Also emits `set` with the key and value.

**Params**

* `key` **{String|Array}**: The name of the property to set. Dot-notation may be used to set nested properties.
* `value` **{any}**
* `returns` **{Object}**: Returns the instance for chaining.

**Events**

* `emits`: `set` with `key` and `value` as arguments.

**Example**

```js
app.on('set', function(key, val) {
  // do something when `set` is emitted
});

app.set('admin', true);

// also takes an object or an array of objects
app.set({ name: 'Brian' });
app.set([{ foo: 'bar' }, { baz: 'quux' }]);
console.log(app);
//=> { name: 'Brian', foo: 'bar', baz: 'quux' }
```

### [.get](index.js#L90)

Return the value of `key`.

**Params**

* `key` **{String|Array}**: The name of the property to get. Dot-notation may be used to set nested properties.
* `returns` **{any}**: Returns the value of `key`

**Events**

* `emits`: `get` with `key` and `value` as arguments.

**Example**

```js
app.set('a.b.c', 'd');
app.get('a.b');
//=> { c: 'd' }
```

### [.prime](index.js#L120)

Create a property on the cache with the given `value` only if it doesn't already exist.

**Params**

* `key` **{String}**: Property name or object path notation.
* `val` **{any}**
* `returns` **{Object}**: Returns the instance for chaining.

**Example**

```js
console.log(app.cache); //=> {}
app.set('one', { foo: 'bar' });
app.prime('one', { a: 'b' });
app.prime('two', { c: 'd' });
console.log(app.cache.one); //=> { foo: 'bar' }
console.log(app.cache.two); //=> { c: 'd' }
```

### [.default](index.js#L162)

Set a default value to be used when `.get()` is called and the value is not defined on the cache. Returns a value from the defaults when only a key is passed.

**Params**

* `key` **{String|Array}**: The name of the property to set. Dot-notation may be used to set nested properties.
* `value` **{any}**: (optional) The value to set on the defaults object.
* `returns` **{Object}**: Returns the instance for chaining.

**Example**

```js
app.set('foo', 'xxx');
app.default('foo', 'one');
app.default('bar', 'two');
app.default('baz', 'three');
app.set('baz', 'zzz');

console.log(app.get('foo'));
//=> 'xxx'

console.log(app.get('bar'));
//=> 'two'

console.log(app.get('baz'));
//=> 'zzz'

console.log(app);
// CacheBase {
//   cache: { foo: 'xxx', bar: 'two', baz: 'zzz' },
//   defaults: { foo: 'one', bar: 'two', baz: 'three' } }
```

### [.union](index.js#L199)

Set an array of unique values on cache `key`.

**Params**

* `key` **{String|Array}**: The name of the property to union. Dot-notation may be used to set nested properties.
* `value` **{any}**
* `returns` **{Object}**: Returns the instance for chaining.

**Example**

```js
app.union('a.b.c', 'foo');
app.union('a.b.c', 'bar');
app.union('a.b.c', ['bar', 'baz']);
console.log(app.get('a'));
//=> { b: { c: ['foo', 'bar', 'baz'] } }
```

### [.has](index.js#L223)

Return true if the value of property `key` is not `undefined`.

**Params**

* `key` **{String|Array}**: The name of the property to check. Dot-notation may be used to set nested properties.
* `returns` **{Boolean}**

**Example**

```js
app.set('foo', true);
app.set('baz', null);
app.set('bar', undefined);

app.has('foo'); //=> true
app.has('bar'); //=> true
app.has('baz'); //=> false
```

### [.hasOwn](index.js#L253)

Returns true if the specified property is an own (not inherited) property. Similar to [.has()](#has), but returns true if the key exists, even if the value is `undefined`.

**Params**

* `key` **{String}**
* `returns` **{Boolean}**: Returns true if object `key` exists. Dot-notation may be used to set nested properties.

**Example**

```js
app.set('a.b.c', 'd');
app.set('x', false);
app.set('y', null);
app.set('z', undefined);

app.hasOwn('a');      //=> true
app.hasOwn('b');      //=> true
app.hasOwn('c');      //=> true
app.hasOwn('a.b.c');  //=> true
app.hasOwn('x');      //=> true
app.hasOwn('y');      //=> true
app.hasOwn('z');      //=> true
app.hasOwn('lslsls'); //=> false
```

### [.del](index.js#L278)

Delete one or more properties from the instance.

**Params**

* `key` **{String|Array}**: The name of the property to delete. Dot-notation may be used to set nested properties.
* `returns` **{Object}**: Returns the instance for chaining.

**Events**

* `emits`: `del` with the `key` as the only argument.

**Example**

```js
// setup a listener to update a property with a default
// value when it's deleted by the user
app.on('del', key => app.set(key, app.default(key)));

app.del(); // delete all properties on the cache
// or
app.del('foo');
// or an array of keys
app.del(['foo', 'bar']);
```

### [.clear](index.js#L301)

Reset the entire cache to an empty object. Note that this does not also clear the `defaults` object, since you can manually do `cache.defaults = {}` if you want to reset that object as well.

**Example**

```js
// clear "defaults" whenever the cache is cleared
app.on('clear', key => (app.defaults = {}));
app.clear();
```

### [.visit](index.js#L318)

Visit (or map visit) the specified method (`key`) over the properties in the
given object or array.

**Params**

* `key` **{String|Array}**: The name of the method to visit.
* `val` **{Object|Array}**: The object or array to iterate over.
* `returns` **{Object}**: Returns the instance for chaining.

### [.keys](index.js#L338)

Gets an array of names of all enumerable properties on the cache.

**Example**

```js
const app = new CacheBase();
app.set('user', true);
app.set('admin', false);

console.log(app.keys);
//=> ['user', 'admin']
```

### [.size](index.js#L357)

Gets the length of [keys](#keys).

**Example**

```js
const app = new CacheBase();
app.set('user', true);
app.set('admin', false);

console.log(app.size);
//=> 2
```

## Usage examples

**Create an instance of cache-base**

```js
const app = new CacheBase();

app.set('a', 'b');
app.set('c.d', 'e');

console.log(app.get('a'));
//=> 'b'
console.log(app.get('c'));
//=> { d: 'e' }
console.log(app);
//=> CacheBase { a: 'b' }
```

**Initialize with an object**

```js
const app = new CacheBase({ a: 'b', c: { d: 'e' } });

console.log(app.get('a'));
//=> 'b'
console.log(app.get('c'));
//=> { d: 'e' }
console.log(app.get('c.d'));
//=> 'e'
console.log(app);
//=> CacheBase { cache: { a: 'b' } }
```

**Inherit**

```js
class MyApp extends CacheBase {}

const app = new MyApp();
app.set('a', 'b');
app.set('c', 'd');

console.log(app.get('a'));
//=> 'b'

console.log(app);
//=> MyApp { cache: { a: 'b', c: 'd' } }
```

**Custom namespace**

Pass a string as the first value to the contructor to define a custom property name to use for the cache. By default values are stored on the `cache` property.

```js
const CacheBase = require('cache-base');
const app = new CacheBase('data', { a: 'b' });
app.set('c.d', 'e');

// get values
console.log(app.get('a'));
//=> 'b'
console.log(app.get('c'));
//=> { d: 'e' }
console.log(app.data);
//=> { a: 'b', c: { d: 'e' } }
console.log(app);
//=> CacheBase { data: { a: 'b', c: { d: 'e' } } }
```

## About

<details>
<summary><strong>Contributing</strong></summary>

Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).

</details>

<details>
<summary><strong>Running Tests</strong></summary>

Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:

```sh
$ npm install && npm test
```

</details>

<details>
<summary><strong>Building docs</strong></summary>

_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_

To generate the readme, run the following command:

```sh
$ npm install -g verbose/verb#dev verb-generate-readme && verb
```

</details>

### Related projects

You might also be interested in these projects:

* [base-methods](https://www.npmjs.com/package/base-methods): base-methods is the foundation for creating modular, unit testable and highly pluggable node.js applications, starting… [more](https://github.com/jonschlinkert/base-methods) | [homepage](https://github.com/jonschlinkert/base-methods "base-methods is the foundation for creating modular, unit testable and highly pluggable node.js applications, starting with a handful of common methods, like `set`, `get`, `del` and `use`.")
* [get-value](https://www.npmjs.com/package/get-value): Use property paths like 'a.b.c' to get a nested value from an object. Even works… [more](https://github.com/jonschlinkert/get-value) | [homepage](https://github.com/jonschlinkert/get-value "Use property paths like 'a.b.c' to get a nested value from an object. Even works when keys have dots in them (no other dot-prop library can do this!).")
* [has-value](https://www.npmjs.com/package/has-value): Returns true if a value exists, false if empty. Works with deeply nested values using… [more](https://github.com/jonschlinkert/has-value) | [homepage](https://github.com/jonschlinkert/has-value "Returns true if a value exists, false if empty. Works with deeply nested values using object paths.")
* [option-cache](https://www.npmjs.com/package/option-cache): Simple API for managing options in JavaScript applications. | [homepage](https://github.com/jonschlinkert/option-cache "Simple API for managing options in JavaScript applications.")
* [set-value](https://www.npmjs.com/package/set-value): Create nested values and any intermediaries using dot notation (`'a.b.c'`) paths. | [homepage](https://github.com/jonschlinkert/set-value "Create nested values and any intermediaries using dot notation (`'a.b.c'`) paths.")
* [unset-value](https://www.npmjs.com/package/unset-value): Delete nested properties from an object using dot notation. | [homepage](https://github.com/jonschlinkert/unset-value "Delete nested properties from an object using dot notation.")

### Contributors

| **Commits** | **Contributor** | 
| --- | --- |
| 67 | [jonschlinkert](https://github.com/jonschlinkert) |
| 2 | [wtgtybhertgeghgtwtg](https://github.com/wtgtybhertgeghgtwtg) |

### Author

**Jon Schlinkert**

* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)
* [GitHub Profile](https://github.com/jonschlinkert)
* [Twitter Profile](https://twitter.com/jonschlinkert)

### License

Copyright © 2018, [Jon Schlinkert](https://github.com/jonschlinkert).
Released under the [MIT License](LICENSE).

***

_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on March 23, 2018._