You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <h1 align="center">
  2. <img width="250" src="https://rawgit.com/lukechilds/keyv/master/media/logo.svg" alt="keyv">
  3. <br>
  4. <br>
  5. </h1>
  6. > Simple key-value storage with support for multiple backends
  7. [![Build Status](https://travis-ci.org/lukechilds/keyv.svg?branch=master)](https://travis-ci.org/lukechilds/keyv)
  8. [![Coverage Status](https://coveralls.io/repos/github/lukechilds/keyv/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/keyv?branch=master)
  9. [![npm](https://img.shields.io/npm/v/keyv.svg)](https://www.npmjs.com/package/keyv)
  10. Keyv provides a consistent interface for key-value storage across multiple backends via storage adapters. It supports TTL based expiry, making it suitable as a cache or a persistent key-value store.
  11. ## Features
  12. There are a few existing modules similar to Keyv, however Keyv is different because it:
  13. - Isn't bloated
  14. - Has a simple Promise based API
  15. - Suitable as a TTL based cache or persistent key-value store
  16. - [Easily embeddable](#add-cache-support-to-your-module) inside another module
  17. - Works with any storage that implements the [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) API
  18. - Handles all JavaScript types (values can be `Buffer`/`null`/`undefined`)
  19. - Supports namespaces
  20. - Wide range of [**efficient, well tested**](#official-storage-adapters) storage adapters
  21. - Connection errors are passed through (db failures won't kill your app)
  22. - Supports the current active LTS version of Node.js or higher
  23. ## Usage
  24. Install Keyv.
  25. ```
  26. npm install --save keyv
  27. ```
  28. By default everything is stored in memory, you can optionally also install a storage adapter.
  29. ```
  30. npm install --save @keyv/redis
  31. npm install --save @keyv/mongo
  32. npm install --save @keyv/sqlite
  33. npm install --save @keyv/postgres
  34. npm install --save @keyv/mysql
  35. ```
  36. Create a new Keyv instance, passing your connection string if applicable. Keyv will automatically load the correct storage adapter.
  37. ```js
  38. const Keyv = require('keyv');
  39. // One of the following
  40. const keyv = new Keyv();
  41. const keyv = new Keyv('redis://user:pass@localhost:6379');
  42. const keyv = new Keyv('mongodb://user:pass@localhost:27017/dbname');
  43. const keyv = new Keyv('sqlite://path/to/database.sqlite');
  44. const keyv = new Keyv('postgresql://user:pass@localhost:5432/dbname');
  45. const keyv = new Keyv('mysql://user:pass@localhost:3306/dbname');
  46. // Handle DB connection errors
  47. keyv.on('error' err => console.log('Connection Error', err));
  48. await keyv.set('foo', 'expires in 1 second', 1000); // true
  49. await keyv.set('foo', 'never expires'); // true
  50. await keyv.get('foo'); // 'never expires'
  51. await keyv.delete('foo'); // true
  52. await keyv.clear(); // undefined
  53. ```
  54. ### Namespaces
  55. You can namespace your Keyv instance to avoid key collisions and allow you to clear only a certain namespace while using the same database.
  56. ```js
  57. const users = new Keyv('redis://user:pass@localhost:6379', { namespace: 'users' });
  58. const cache = new Keyv('redis://user:pass@localhost:6379', { namespace: 'cache' });
  59. await users.set('foo', 'users'); // true
  60. await cache.set('foo', 'cache'); // true
  61. await users.get('foo'); // 'users'
  62. await cache.get('foo'); // 'cache'
  63. await users.clear(); // undefined
  64. await users.get('foo'); // undefined
  65. await cache.get('foo'); // 'cache'
  66. ```
  67. ## Official Storage Adapters
  68. The official storage adapters are covered by [over 150 integration tests](https://travis-ci.org/lukechilds/keyv/jobs/260418145) to guarantee consistent behaviour. They are lightweight, efficient wrappers over the DB clients making use of indexes and native TTLs where available.
  69. Database | Adapter | Native TTL | Status
  70. ---|---|---|---
  71. Redis | [@keyv/redis](https://github.com/lukechilds/keyv-redis) | Yes | [![Build Status](https://travis-ci.org/lukechilds/keyv-redis.svg?branch=master)](https://travis-ci.org/lukechilds/keyv-redis) [![Coverage Status](https://coveralls.io/repos/github/lukechilds/keyv-redis/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/keyv-redis?branch=master)
  72. MongoDB | [@keyv/mongo](https://github.com/lukechilds/keyv-mongo) | Yes | [![Build Status](https://travis-ci.org/lukechilds/keyv-mongo.svg?branch=master)](https://travis-ci.org/lukechilds/keyv-mongo) [![Coverage Status](https://coveralls.io/repos/github/lukechilds/keyv-mongo/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/keyv-mongo?branch=master)
  73. SQLite | [@keyv/sqlite](https://github.com/lukechilds/keyv-sqlite) | No | [![Build Status](https://travis-ci.org/lukechilds/keyv-sqlite.svg?branch=master)](https://travis-ci.org/lukechilds/keyv-sqlite) [![Coverage Status](https://coveralls.io/repos/github/lukechilds/keyv-sqlite/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/keyv-sqlite?branch=master)
  74. PostgreSQL | [@keyv/postgres](https://github.com/lukechilds/keyv-postgres) | No | [![Build Status](https://travis-ci.org/lukechilds/keyv-postgres.svg?branch=master)](https://travis-ci.org/lukechildskeyv-postgreskeyv) [![Coverage Status](https://coveralls.io/repos/github/lukechilds/keyv-postgres/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/keyv-postgres?branch=master)
  75. MySQL | [@keyv/mysql](https://github.com/lukechilds/keyv-mysql) | No | [![Build Status](https://travis-ci.org/lukechilds/keyv-mysql.svg?branch=master)](https://travis-ci.org/lukechilds/keyv-mysql) [![Coverage Status](https://coveralls.io/repos/github/lukechilds/keyv-mysql/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/keyv-mysql?branch=master)
  76. ## Third-party Storage Adapters
  77. You can also use third-party storage adapters or build your own. Keyv will wrap these storage adapters in TTL functionality and handle complex types internally.
  78. ```js
  79. const Keyv = require('keyv');
  80. const myAdapter = require('./my-storage-adapter');
  81. const keyv = new Keyv({ store: myAdapter });
  82. ```
  83. Any store that follows the [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) api will work.
  84. ```js
  85. new Keyv({ store: new Map() });
  86. ```
  87. For example, [`quick-lru`](https://github.com/sindresorhus/quick-lru) is a completely unrelated module that implements the Map API.
  88. ```js
  89. const Keyv = require('keyv');
  90. const QuickLRU = require('quick-lru');
  91. const lru = new QuickLRU({ maxSize: 1000 });
  92. const keyv = new Keyv({ store: lru });
  93. ```
  94. ## Add Cache Support to your Module
  95. Keyv is designed to be easily embedded into other modules to add cache support. The recommended pattern is to expose a `cache` option in your modules options which is passed through to Keyv. Caching will work in memory by default and users have the option to also install a Keyv storage adapter and pass in a connection string, or any other storage that implements the `Map` API.
  96. You should also set a namespace for your module so you can safely call `.clear()` without clearing unrelated app data.
  97. Inside your module:
  98. ```js
  99. class AwesomeModule {
  100. constructor(opts) {
  101. this.cache = new Keyv({
  102. uri: typeof opts.cache === 'string' && opts.cache,
  103. store: typeof opts.cache !== 'string' && opts.cache,
  104. namespace: 'awesome-module'
  105. });
  106. }
  107. }
  108. ```
  109. Now it can be consumed like this:
  110. ```js
  111. const AwesomeModule = require('awesome-module');
  112. // Caches stuff in memory by default
  113. const awesomeModule = new AwesomeModule();
  114. // After npm install --save keyv-redis
  115. const awesomeModule = new AwesomeModule({ cache: 'redis://localhost' });
  116. // Some third-party module that implements the Map API
  117. const awesomeModule = new AwesomeModule({ cache: some3rdPartyStore });
  118. ```
  119. ## API
  120. ### new Keyv([uri], [options])
  121. Returns a new Keyv instance.
  122. The Keyv instance is also an `EventEmitter` that will emit an `'error'` event if the storage adapter connection fails.
  123. ### uri
  124. Type: `String`<br>
  125. Default: `undefined`
  126. The connection string URI.
  127. Merged into the options object as options.uri.
  128. ### options
  129. Type: `Object`
  130. The options object is also passed through to the storage adapter. Check your storage adapter docs for any extra options.
  131. #### options.namespace
  132. Type: `String`<br>
  133. Default: `'keyv'`
  134. Namespace for the current instance.
  135. #### options.ttl
  136. Type: `Number`<br>
  137. Default: `undefined`
  138. Default TTL. Can be overridden by specififying a TTL on `.set()`.
  139. #### options.store
  140. Type: `Storage adapter instance`<br>
  141. Default: `new Map()`
  142. The storage adapter instance to be used by Keyv.
  143. #### options.adapter
  144. Type: `String`<br>
  145. Default: `undefined`
  146. Specify an adapter to use. e.g `'redis'` or `'mongodb'`.
  147. ### Instance
  148. Keys must always be strings. Values can be of any type.
  149. #### .set(key, value, [ttl])
  150. Set a value.
  151. By default keys are persistent. You can set an expiry TTL in milliseconds.
  152. Returns `true`.
  153. #### .get(key)
  154. Returns the value.
  155. #### .delete(key)
  156. Deletes an entry.
  157. Returns `true` if the key existed, `false` if not.
  158. #### .clear()
  159. Delete all entries in the current namespace.
  160. Returns `undefined`.
  161. ## License
  162. MIT © Luke Childs