UNPKG

11.1 kBMarkdownView Raw
1<h1 align="center">
2 <img width="250" src="https://jaredwray.com/images/keyv.svg" alt="keyv">
3 <br>
4 <br>
5</h1>
6
7> Simple key-value storage with support for multiple backends
8
9[![build](https://github.com/jaredwray/keyv/actions/workflows/build.yaml/badge.svg)](https://github.com/jaredwray/keyv/actions/workflows/build.yaml)
10[![codecov](https://codecov.io/gh/jaredwray/keyv/branch/master/graph/badge.svg?token=bRzR3RyOXZ)](https://codecov.io/gh/jaredwray/keyv)
11[![npm](https://img.shields.io/npm/dm/keyv.svg)](https://www.npmjs.com/package/keyv)
12[![npm](https://img.shields.io/npm/v/keyv.svg)](https://www.npmjs.com/package/keyv)
13
14Keyv 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.
15
16## Features
17
18There are a few existing modules similar to Keyv, however Keyv is different because it:
19
20- Isn't bloated
21- Has a simple Promise based API
22- Suitable as a TTL based cache or persistent key-value store
23- [Easily embeddable](#add-cache-support-to-your-module) inside another module
24- Works with any storage that implements the [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) API
25- Handles all JSON types plus `Buffer`
26- Supports namespaces
27- Wide range of [**efficient, well tested**](#official-storage-adapters) storage adapters
28- Connection errors are passed through (db failures won't kill your app)
29- Supports the current active LTS version of Node.js or higher
30
31## Usage
32
33Install Keyv.
34
35```
36npm install --save keyv
37```
38
39By default everything is stored in memory, you can optionally also install a storage adapter.
40
41```
42npm install --save @keyv/redis
43npm install --save @keyv/mongo
44npm install --save @keyv/sqlite
45npm install --save @keyv/postgres
46npm install --save @keyv/mysql
47```
48
49Create a new Keyv instance, passing your connection string if applicable. Keyv will automatically load the correct storage adapter.
50
51```js
52const Keyv = require('keyv');
53
54// One of the following
55const keyv = new Keyv();
56const keyv = new Keyv('redis://user:pass@localhost:6379');
57const keyv = new Keyv('mongodb://user:pass@localhost:27017/dbname');
58const keyv = new Keyv('sqlite://path/to/database.sqlite');
59const keyv = new Keyv('postgresql://user:pass@localhost:5432/dbname');
60const keyv = new Keyv('mysql://user:pass@localhost:3306/dbname');
61
62// Handle DB connection errors
63keyv.on('error', err => console.log('Connection Error', err));
64
65await keyv.set('foo', 'expires in 1 second', 1000); // true
66await keyv.set('foo', 'never expires'); // true
67await keyv.get('foo'); // 'never expires'
68await keyv.delete('foo'); // true
69await keyv.clear(); // undefined
70```
71
72### Namespaces
73
74You can namespace your Keyv instance to avoid key collisions and allow you to clear only a certain namespace while using the same database.
75
76```js
77const users = new Keyv('redis://user:pass@localhost:6379', { namespace: 'users' });
78const cache = new Keyv('redis://user:pass@localhost:6379', { namespace: 'cache' });
79
80await users.set('foo', 'users'); // true
81await cache.set('foo', 'cache'); // true
82await users.get('foo'); // 'users'
83await cache.get('foo'); // 'cache'
84await users.clear(); // undefined
85await users.get('foo'); // undefined
86await cache.get('foo'); // 'cache'
87```
88
89### Custom Serializers
90
91Keyv uses [`json-buffer`](https://github.com/dominictarr/json-buffer) for data serialization to ensure consistency across different backends.
92
93You can optionally provide your own serialization functions to support extra data types or to serialize to something other than JSON.
94
95```js
96const keyv = new Keyv({ serialize: JSON.stringify, deserialize: JSON.parse });
97```
98
99**Warning:** Using custom serializers means you lose any guarantee of data consistency. You should do extensive testing with your serialisation functions and chosen storage engine.
100
101## Official Storage Adapters
102
103The official storage adapters are covered by [over 150 integration tests](https://github.com/jaredwray/keyv/actions/workflows/build.yaml) to guarantee consistent behaviour. They are lightweight, efficient wrappers over the DB clients making use of indexes and native TTLs where available.
104
105Database | Adapter | Native TTL | Status
106---|---|---|---
107Redis | [@keyv/redis](https://github.com/lukechilds/keyv-redis) | Yes | [![build](https://github.com/lukechilds/keyv-redis/actions/workflows/build.yaml/badge.svg)](https://github.com/lukechilds/keyv-redis/actions/workflows/build.yaml) [![Coverage Status](https://coveralls.io/repos/github/lukechilds/keyv-redis/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/keyv-redis?branch=master)
108MongoDB | [@keyv/mongo](https://github.com/lukechilds/keyv-mongo) | Yes | [![build](https://github.com/lukechilds/keyv-mongo/actions/workflows/build.yaml/badge.svg)](https://github.com/lukechilds/keyv-mongo/actions/workflows/build.yaml) [![Coverage Status](https://coveralls.io/repos/github/lukechilds/keyv-mongo/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/keyv-mongo?branch=master)
109SQLite | [@keyv/sqlite](https://github.com/lukechilds/keyv-sqlite) | No | [![build](https://github.com/lukechilds/keyv-sqlite/actions/workflows/build.yaml/badge.svg)](https://github.com/lukechilds/keyv-sqlite/actions/workflows/build.yaml) [![Coverage Status](https://coveralls.io/repos/github/lukechilds/keyv-sqlite/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/keyv-sqlite?branch=master)
110PostgreSQL | [@keyv/postgres](https://github.com/lukechilds/keyv-postgres) | No | [![build](https://github.com/lukechilds/keyv-postgres/actions/workflows/build.yaml/badge.svg)](https://github.com/lukechilds/keyv-postgres/actions/workflows/build.yaml) [![Coverage Status](https://coveralls.io/repos/github/lukechilds/keyv-postgres/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/keyv-postgres?branch=master)
111MySQL | [@keyv/mysql](https://github.com/lukechilds/keyv-mysql) | No | [![build](https://github.com/jaredwray/keyv-mysql/actions/workflows/build.yaml/badge.svg)](https://github.com/jaredwray/keyv-mysql/actions/workflows/build.yaml) [![Coverage Status](https://coveralls.io/repos/github/lukechilds/keyv-mysql/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/keyv-mysql?branch=master)
112
113## Third-party Storage Adapters
114
115You 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.
116
117```js
118const Keyv = require('keyv');
119const myAdapter = require('./my-storage-adapter');
120
121const keyv = new Keyv({ store: myAdapter });
122```
123
124Any store that follows the [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) api will work.
125
126```js
127new Keyv({ store: new Map() });
128```
129
130For example, [`quick-lru`](https://github.com/sindresorhus/quick-lru) is a completely unrelated module that implements the Map API.
131
132```js
133const Keyv = require('keyv');
134const QuickLRU = require('quick-lru');
135
136const lru = new QuickLRU({ maxSize: 1000 });
137const keyv = new Keyv({ store: lru });
138```
139
140The following are third-party storage adapters compatible with Keyv:
141
142- [quick-lru](https://github.com/sindresorhus/quick-lru) - Simple "Least Recently Used" (LRU) cache
143- [keyv-file](https://github.com/zaaack/keyv-file) - File system storage adapter for Keyv
144- [keyv-dynamodb](https://www.npmjs.com/package/keyv-dynamodb) - DynamoDB storage adapter for Keyv
145- [keyv-lru](https://www.npmjs.com/package/keyv-lru) - LRU storage adapter for Keyv
146- [keyv-null](https://www.npmjs.com/package/keyv-null) - Null storage adapter for Keyv
147- [keyv-firestore ](https://github.com/goto-bus-stop/keyv-firestore) – Firebase Cloud Firestore adapter for Keyv
148- [keyv-mssql](https://github.com/pmorgan3/keyv-mssql) - Microsoft Sql Server adapter for Keyv
149- [keyv-memcache](https://github.com/jaredwray/keyv-memcache) - Memcache storage adapter for Keyv
150
151## Add Cache Support to your Module
152
153Keyv 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.
154
155You should also set a namespace for your module so you can safely call `.clear()` without clearing unrelated app data.
156
157Inside your module:
158
159```js
160class AwesomeModule {
161 constructor(opts) {
162 this.cache = new Keyv({
163 uri: typeof opts.cache === 'string' && opts.cache,
164 store: typeof opts.cache !== 'string' && opts.cache,
165 namespace: 'awesome-module'
166 });
167 }
168}
169```
170
171Now it can be consumed like this:
172
173```js
174const AwesomeModule = require('awesome-module');
175
176// Caches stuff in memory by default
177const awesomeModule = new AwesomeModule();
178
179// After npm install --save keyv-redis
180const awesomeModule = new AwesomeModule({ cache: 'redis://localhost' });
181
182// Some third-party module that implements the Map API
183const awesomeModule = new AwesomeModule({ cache: some3rdPartyStore });
184```
185
186## API
187
188### new Keyv([uri], [options])
189
190Returns a new Keyv instance.
191
192The Keyv instance is also an `EventEmitter` that will emit an `'error'` event if the storage adapter connection fails.
193
194### uri
195
196Type: `String`<br>
197Default: `undefined`
198
199The connection string URI.
200
201Merged into the options object as options.uri.
202
203### options
204
205Type: `Object`
206
207The options object is also passed through to the storage adapter. Check your storage adapter docs for any extra options.
208
209#### options.namespace
210
211Type: `String`<br>
212Default: `'keyv'`
213
214Namespace for the current instance.
215
216#### options.ttl
217
218Type: `Number`<br>
219Default: `undefined`
220
221Default TTL. Can be overridden by specififying a TTL on `.set()`.
222
223#### options.serialize
224
225Type: `Function`<br>
226Default: `JSONB.stringify`
227
228A custom serialization function.
229
230#### options.deserialize
231
232Type: `Function`<br>
233Default: `JSONB.parse`
234
235A custom deserialization function.
236
237#### options.store
238
239Type: `Storage adapter instance`<br>
240Default: `new Map()`
241
242The storage adapter instance to be used by Keyv.
243
244#### options.adapter
245
246Type: `String`<br>
247Default: `undefined`
248
249Specify an adapter to use. e.g `'redis'` or `'mongodb'`.
250
251### Instance
252
253Keys must always be strings. Values can be of any type.
254
255#### .set(key, value, [ttl])
256
257Set a value.
258
259By default keys are persistent. You can set an expiry TTL in milliseconds.
260
261Returns a promise which resolves to `true`.
262
263#### .get(key, [options])
264
265Returns a promise which resolves to the retrieved value.
266
267##### options.raw
268
269Type: `Boolean`<br>
270Default: `false`
271
272If set to true the raw DB object Keyv stores internally will be returned instead of just the value.
273
274This contains the TTL timestamp.
275
276#### .delete(key)
277
278Deletes an entry.
279
280Returns a promise which resolves to `true` if the key existed, `false` if not.
281
282#### .clear()
283
284Delete all entries in the current namespace.
285
286Returns a promise which is resolved when the entries have been cleared.
287
288## License
289
290MIT © Jared Wray & Luke Childs