Skip to content

Commit

Permalink
Merge pull request #3 from svipben/execute-cb-after-clear
Browse files Browse the repository at this point in the history
reject Promise or execute callback after `clear()`
  • Loading branch information
svipas authored Feb 17, 2018
2 parents eb3b986 + 2b135c6 commit df26b2e
Show file tree
Hide file tree
Showing 13 changed files with 564 additions and 482 deletions.
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@ language: node_js
node_js:
- "node"
- "lts/*"
script:
- "yarn run lint"
- "yarn test"
notifications:
email: false
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
## [1.0.4](https://github.com/svipben/cachimo/releases/tag/1.0.4) (2018-02-17)

### Added

* `typings` property in `package.json`.

### Changed

* `clear()` function to also reject Promise or execute callback to inform if timeout was cleared.
* `README.md` to show how new `clear()` function works.
* Travis CI to also run ESLint before tests.
* Travis CI to disable email notifications.
* Tests to be more isolated.
* Moved all `index.js` code to the `src/cachimo.js`.

### Updated

* ⬆️ ESLint to 4.18.0
* ⬆️ Jest to 22.3.0

## [1.0.3](https://github.com/svipben/cachimo/releases/tag/1.0.3) (2018-02-17)

### Added
Expand Down
30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ yarn add cachimo

# How to use

### `put` function

```js
const cachimo = require('cachimo');

Expand Down Expand Up @@ -59,6 +61,31 @@ cachimo.put('key', 'value', 1000, (err, key, value, timeout) => {
});
```

### `clear` function

```js
const cachimo = require('cachimo');

// Promise
cachimo.put('key', 'value', 1000).catch(err => {
// you will get error because at the end of the code there's `clear()` function which clears all timeouts as well as keys and values
throw err; // "key timeout was cleared"
});

// callback
cachimo.put('key', 'value', 1000, err => {
if (err) {
// you will get error because at the end of the code there's `clear()` function which clears all timeouts as well as keys and values
throw err; // "key timeout was cleared"
}
});

// removes all elements stored in cache and clears all timeouts
cachimo.clear(); // returns number of how much elements was removed from cache
```

### Other functions

```js
const cachimo = require('cachimo');

Expand All @@ -82,7 +109,4 @@ cachimo.values(); // ['value']

// returns all entries (keys and values) stored in cache
cachimo.entries(); // [['key', 'value']]

// removes all elements stored in cache and clears all timeouts
cachimo.clear(); // returns number of how much elements was removed from cache
```
162 changes: 1 addition & 161 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,161 +1 @@
const cache = new Map();
const timeouts = [];

/**
* Returns value from cache by given `key`.
*
* @param {string | number | boolean} key
*
* @returns {any} value from cache
*/
function get(key) {
return cache.get(key);
}

/**
* Removes element from cache by given `key`.
*
* @param {string | number | boolean} key
*
* @returns {boolean} true if element has been removed, false otherwise
*/
function remove(key) {
return cache.delete(key);
}

/**
* Checks if whether an element with given `key` exist.
*
* @param {string | number | boolean} key
*
* @returns {boolean} true if element exist, false otherwise
*/
function has(key) {
return cache.has(key);
}

/**
* Returns the number of elements in cache.
*
* @returns {number} number of elements in cache
*/
function size() {
return cache.size;
}

/**
* Returns all keys stored in cache.
*
* @returns {Array<string | number | boolean>} all keys
*/
function keys() {
return [...cache.keys()];
}

/**
* Returns all values stored in cache.
*
* @returns {Array<any>} all values
*/
function values() {
return [...cache.values()];
}

/**
* Returns all entries (keys and values) stored in cache.
*
* @returns {Array<[string | number | boolean, any]>} all entries (keys and values)
*/
function entries() {
return [...cache.entries()];
}

/**
* Removes all elements stored in cache and clears all timeouts.
*
* @returns {number} how much elements was removed from cache
*/
function clear() {
timeouts.forEach(t => clearTimeout(t));
const length = size();
cache.clear();
return length;
}

/**
* Stores an element in-memory with specified key and value.
*
* If only `key` and `value` is provided it returns boolean.
* true: if element was stored and key doesn't exist.
* false: if key does exist.
*
* If additionally only `timeout` is provided it returns Promise.
* Element will be deleted after given `timeout` and Promise will be resolved.
* Otherwise it will be rejected if element does not exist.
*
* If additionally `timeout` and `callback` is provided it executes given `callback` after given `timeout`.
*
* @param {string | number | boolean} key can be only: `string` | `number` | `boolean`
* @param {any} value can be any type
* @param {number} timeout after how much time in milliseconds element will be deleted
* @param {(err: Error, key: string | number | boolean, value: any, timeout: number)} callback will be executed after given `timeout`
*
* @returns {boolean | Promise<{ key: string | number | boolean, value: any, timeout: number }>} boolean or Promise
*/
function put(key, value, timeout, callback) {
// key type is incorrect
if (typeof key !== 'string' && typeof key !== 'number' && typeof key !== 'boolean') {
throw new TypeError(`key can be only: string | number | boolean instead of ${typeof key}`);
}
// check if key is not NaN
if (typeof key === 'number' && isNaN(key)) {
throw new TypeError('key can be only: string | number | boolean instead of NaN');
}

// timeout type is incorrect and/or timeout is not positive number
if (timeout !== undefined && (typeof timeout !== 'number' || isNaN(timeout) || timeout <= 0)) {
throw new TypeError('timeout should be positive number');
}

// callback type is incorrect
if (callback !== undefined && typeof callback !== 'function') {
throw new TypeError(`callback should be function instead of ${typeof callback}`);
}

// key does exist
if (has(key)) {
return false;
}

cache.set(key, value);

// return Promise
if (timeout !== undefined && callback === undefined) {
return new Promise((resolve, reject) => {
const t = setTimeout(() => {
if (cache.delete(key)) {
resolve({ key, value, timeout });
} else {
reject(new Error(`${key} does not exist`));
}
}, timeout);
timeouts.push(t);
});
}

// execute callback
if (timeout !== undefined && callback !== undefined) {
const t = setTimeout(() => {
if (cache.delete(key)) {
callback(null, key, value, timeout);
} else {
callback(new Error(`${key} does not exist`));
}
}, timeout);
timeouts.push(t);
}

return true;
}

module.exports = { get, remove, has, size, keys, values, entries, clear, put };
module.exports = require('./src/cachimo');
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"name": "cachimo",
"description": "Stores key with value in-memory and can be deleted manually or after given timeout.",
"version": "1.0.3",
"version": "1.0.4",
"main": "index.js",
"typings": "index.d.ts",
"repository": "https://github.com/svipben/cachimo.git",
"author": "svipben <benas.svipas@gmail.com>",
"license": "MIT",
Expand All @@ -11,8 +12,8 @@
"test": "jest tests"
},
"devDependencies": {
"eslint": "^4.16.0",
"jest": "^22.1.4"
"eslint": "^4.18.0",
"jest": "^22.3.0"
},
"keywords": ["cache", "in-memory", "storage"]
}
Loading

0 comments on commit df26b2e

Please sign in to comment.