cacheable 1.7.1 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -21
- package/dist/index.cjs +464 -5
- package/dist/index.d.cts +422 -6
- package/dist/index.d.ts +422 -6
- package/dist/index.js +452 -4
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -8,23 +8,25 @@
|
|
|
8
8
|
[](https://github.com/jaredwray/cacheable/actions/workflows/tests.yml)
|
|
9
9
|
[](https://www.npmjs.com/package/cacheable)
|
|
10
10
|
[](https://www.npmjs.com/package/cacheable)
|
|
11
|
+
[](https://github.com/jaredwray/cacheable/blob/main/LICENSE)
|
|
11
12
|
|
|
12
13
|
`cacheable` is a high performance layer 1 / layer 2 caching engine that is focused on distributed caching with enterprise features such as `CacheSync` (coming soon). It is built on top of the robust storage engine [Keyv](https://keyv.org) and provides a simple API to cache and retrieve data.
|
|
13
14
|
|
|
14
15
|
* Simple to use with robust API
|
|
15
16
|
* Not bloated with additional modules
|
|
16
|
-
* Extendable to your own caching engine
|
|
17
17
|
* Scalable and trusted storage engine by Keyv
|
|
18
18
|
* Memory Caching with LRU and Expiration `CacheableMemory`
|
|
19
19
|
* Resilient to failures with try/catch and offline
|
|
20
|
+
* Wrap / Memoization for Sync and Async Functions
|
|
20
21
|
* Hooks and Events to extend functionality
|
|
21
|
-
* Comprehensive testing and code coverage
|
|
22
22
|
* Shorthand for ttl in milliseconds `(1m = 60000) (1h = 3600000) (1d = 86400000)`
|
|
23
|
+
* Non-blocking operations for layer 2 caching
|
|
23
24
|
* Distributed Caching Sync via Pub/Sub (coming soon)
|
|
24
|
-
*
|
|
25
|
+
* Comprehensive testing and code coverage
|
|
26
|
+
* ESM and CommonJS support with Typescript
|
|
25
27
|
* Maintained and supported regularly
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
# Table of Contents
|
|
28
30
|
* [Getting Started](#getting-started)
|
|
29
31
|
* [Basic Usage](#basic-usage)
|
|
30
32
|
* [Hooks and Events](#hooks-and-events)
|
|
@@ -34,12 +36,16 @@
|
|
|
34
36
|
* [CacheSync - Distributed Updates](#cachesync---distributed-updates)
|
|
35
37
|
* [Cacheable Options](#cacheable-options)
|
|
36
38
|
* [Cacheable Statistics (Instance Only)](#cacheable-statistics-instance-only)
|
|
37
|
-
* [API](#api)
|
|
39
|
+
* [Cacheable - API](#cacheable---api)
|
|
38
40
|
* [CacheableMemory - In-Memory Cache](#cacheablememory---in-memory-cache)
|
|
41
|
+
* [CacheableMemory Options](#cacheablememory-options)
|
|
42
|
+
* [CacheableMemory - API](#cacheablememory---api)
|
|
43
|
+
* [Wrap / Memoization for Sync and Async Functions](#wrap--memoization-for-sync-and-async-functions)
|
|
44
|
+
* [Keyv Storage Adapter - KeyvCacheableMemory](#keyv-storage-adapter---keyvcacheablememory)
|
|
39
45
|
* [How to Contribute](#how-to-contribute)
|
|
40
46
|
* [License and Copyright](#license-and-copyright)
|
|
41
47
|
|
|
42
|
-
|
|
48
|
+
# Getting Started
|
|
43
49
|
|
|
44
50
|
`cacheable` is primarily used as an extension to you caching engine with a robust storage backend [Keyv](https://keyv.org), Memonization (Wrap), Hooks, Events, and Statistics.
|
|
45
51
|
|
|
@@ -47,7 +53,7 @@
|
|
|
47
53
|
npm install cacheable
|
|
48
54
|
```
|
|
49
55
|
|
|
50
|
-
|
|
56
|
+
# Basic Usage
|
|
51
57
|
|
|
52
58
|
```javascript
|
|
53
59
|
import { Cacheable } from 'cacheable';
|
|
@@ -82,7 +88,7 @@ const cache = new Cacheable({primary, secondary});
|
|
|
82
88
|
|
|
83
89
|
This is a more advanced example and not needed for most use cases.
|
|
84
90
|
|
|
85
|
-
|
|
91
|
+
# Hooks and Events
|
|
86
92
|
|
|
87
93
|
The following hooks are available for you to extend the functionality of `cacheable` via `CacheableHooks` enum:
|
|
88
94
|
|
|
@@ -106,7 +112,7 @@ cacheable.onHook(CacheableHooks.BEFORE_SET, (data) => {
|
|
|
106
112
|
});
|
|
107
113
|
```
|
|
108
114
|
|
|
109
|
-
|
|
115
|
+
# Storage Tiering and Caching
|
|
110
116
|
|
|
111
117
|
`cacheable` is built as a layer 1 and layer 2 caching engine by default. The purpose is to have your layer 1 be fast and your layer 2 be more persistent. The primary store is the layer 1 cache and the secondary store is the layer 2 cache. By adding the secondary store you are enabling layer 2 caching. By default the operations are blocking but fault tolerant:
|
|
112
118
|
|
|
@@ -153,7 +159,7 @@ cache.ttl = -1; // sets the default ttl to 0 which is disabled
|
|
|
153
159
|
console.log(cache.ttl); // undefined
|
|
154
160
|
```
|
|
155
161
|
|
|
156
|
-
|
|
162
|
+
# Non-Blocking Operations
|
|
157
163
|
|
|
158
164
|
If you want your layer 2 (secondary) store to be non-blocking you can set the `nonBlocking` property to `true` in the options. This will make the secondary store non-blocking and will not wait for the secondary store to respond on `setting data`, `deleting data`, or `clearing data`. This is useful if you want to have a faster response time and not wait for the secondary store to respond.
|
|
159
165
|
|
|
@@ -165,7 +171,7 @@ const secondary = new KeyvRedis('redis://user:pass@localhost:6379');
|
|
|
165
171
|
const cache = new Cacheable({secondary, nonBlocking: true});
|
|
166
172
|
```
|
|
167
173
|
|
|
168
|
-
|
|
174
|
+
# CacheSync - Distributed Updates
|
|
169
175
|
|
|
170
176
|
`cacheable` has a feature called `CacheSync` that is coming soon. This feature will allow you to have distributed caching with Pub/Sub. This will allow you to have multiple instances of `cacheable` running and when a value is set, deleted, or cleared it will update all instances of `cacheable` with the same value. Current plan is to support the following:
|
|
171
177
|
|
|
@@ -177,7 +183,7 @@ const cache = new Cacheable({secondary, nonBlocking: true});
|
|
|
177
183
|
|
|
178
184
|
This feature should be live by end of year.
|
|
179
185
|
|
|
180
|
-
|
|
186
|
+
# Cacheable Options
|
|
181
187
|
|
|
182
188
|
The following options are available for you to configure `cacheable`:
|
|
183
189
|
|
|
@@ -187,7 +193,7 @@ The following options are available for you to configure `cacheable`:
|
|
|
187
193
|
* `stats`: To enable statistics for this instance. Default is `false`.
|
|
188
194
|
* `ttl`: The default time to live for the cache in milliseconds. Default is `undefined` which is disabled.
|
|
189
195
|
|
|
190
|
-
|
|
196
|
+
# Cacheable Statistics (Instance Only)
|
|
191
197
|
|
|
192
198
|
If you want to enable statistics for your instance you can set the `.stats.enabled` property to `true` in the options. This will enable statistics for your instance and you can get the statistics by calling the `stats` property. Here are the following property statistics:
|
|
193
199
|
|
|
@@ -205,7 +211,7 @@ You can clear / reset the stats by calling the `.stats.reset()` method.
|
|
|
205
211
|
|
|
206
212
|
_This does not enable statistics for your layer 2 cache as that is a distributed cache_.
|
|
207
213
|
|
|
208
|
-
|
|
214
|
+
# Cacheable - API
|
|
209
215
|
|
|
210
216
|
* `set(key, value, ttl?)`: Sets a value in the cache.
|
|
211
217
|
* `setMany([{key, value, ttl?}])`: Sets multiple values in the cache.
|
|
@@ -218,18 +224,19 @@ _This does not enable statistics for your layer 2 cache as that is a distributed
|
|
|
218
224
|
* `delete(key)`: Deletes a value from the cache.
|
|
219
225
|
* `deleteMany([keys])`: Deletes multiple values from the cache.
|
|
220
226
|
* `clear()`: Clears the cache stores. Be careful with this as it will clear both layer 1 and layer 2.
|
|
221
|
-
* `wrap(function,
|
|
227
|
+
* `wrap(function, WrapOptions)`: Wraps an `async` function in a cache.
|
|
222
228
|
* `disconnect()`: Disconnects from the cache stores.
|
|
223
229
|
* `onHook(hook, callback)`: Sets a hook.
|
|
224
230
|
* `removeHook(hook)`: Removes a hook.
|
|
225
231
|
* `on(event, callback)`: Listens for an event.
|
|
226
232
|
* `removeListener(event, callback)`: Removes a listener.
|
|
233
|
+
* `hash(object: any, algorithm = 'sha256'): string`: Hashes an object with the algorithm. Default is `sha256`.
|
|
227
234
|
* `primary`: The primary store for the cache (layer 1) defaults to in-memory by Keyv.
|
|
228
235
|
* `secondary`: The secondary store for the cache (layer 2) usually a persistent cache by Keyv.
|
|
229
236
|
* `nonBlocking`: If the secondary store is non-blocking. Default is `false`.
|
|
230
237
|
* `stats`: The statistics for this instance which includes `hits`, `misses`, `sets`, `deletes`, `clears`, `errors`, `count`, `vsize`, `ksize`.
|
|
231
238
|
|
|
232
|
-
|
|
239
|
+
# CacheableMemory - In-Memory Cache
|
|
233
240
|
|
|
234
241
|
`cacheable` comes with a built-in in-memory cache called `CacheableMemory`. This is a simple in-memory cache that is used as the primary store for `cacheable`. You can use this as a standalone cache or as a primary store for `cacheable`. Here is an example of how to use `CacheableMemory`:
|
|
235
242
|
|
|
@@ -251,26 +258,28 @@ This simple in-memory cache uses multiple Map objects and a with `expiration` an
|
|
|
251
258
|
|
|
252
259
|
By default we use lazy expiration deletion which means on `get` and `getMany` type functions we look if it is expired and then delete it. If you want to have a more aggressive expiration policy you can set the `checkInterval` property to a value greater than `0` which will check for expired keys at the interval you set.
|
|
253
260
|
|
|
254
|
-
|
|
261
|
+
## CacheableMemory Options
|
|
255
262
|
|
|
256
263
|
* `ttl`: The time to live for the cache in milliseconds. Default is `undefined` which is means indefinitely.
|
|
257
264
|
* `useClones`: If the cache should use clones for the values. Default is `true`.
|
|
258
265
|
* `lruSize`: The size of the LRU cache. Default is `0` which is unlimited.
|
|
259
266
|
* `checkInterval`: The interval to check for expired keys in milliseconds. Default is `0` which is disabled.
|
|
260
267
|
|
|
261
|
-
|
|
268
|
+
## CacheableMemory - API
|
|
262
269
|
|
|
263
270
|
* `set(key, value, ttl?)`: Sets a value in the cache.
|
|
264
|
-
* `setMany([{key, value, ttl?}])`: Sets multiple values in the cache from `
|
|
271
|
+
* `setMany([{key, value, ttl?}])`: Sets multiple values in the cache from `CacheableItem`.
|
|
265
272
|
* `get(key)`: Gets a value from the cache.
|
|
266
273
|
* `getMany([keys])`: Gets multiple values from the cache.
|
|
267
274
|
* `getRaw(key)`: Gets a value from the cache as `CacheableStoreItem`.
|
|
268
275
|
* `getManyRaw([keys])`: Gets multiple values from the cache as `CacheableStoreItem`.
|
|
269
276
|
* `has(key)`: Checks if a value exists in the cache.
|
|
277
|
+
* `hasMany([keys])`: Checks if multiple values exist in the cache.
|
|
270
278
|
* `delete(key)`: Deletes a value from the cache.
|
|
271
279
|
* `deleteMany([keys])`: Deletes multiple values from the cache.
|
|
272
280
|
* `take(key)`: Takes a value from the cache and deletes it.
|
|
273
281
|
* `takeMany([keys])`: Takes multiple values from the cache and deletes them.
|
|
282
|
+
* `wrap(function, WrapSyncOptions)`: Wraps a `sync` function in a cache.
|
|
274
283
|
* `clear()`: Clears the cache.
|
|
275
284
|
* `size()`: The number of keys in the cache.
|
|
276
285
|
* `keys()`: The keys in the cache.
|
|
@@ -278,11 +287,58 @@ By default we use lazy expiration deletion which means on `get` and `getMany` ty
|
|
|
278
287
|
* `checkExpired()`: Checks for expired keys in the cache. This is used by the `checkInterval` property.
|
|
279
288
|
* `startIntervalCheck()`: Starts the interval check for expired keys if `checkInterval` is above 0 ms.
|
|
280
289
|
* `stopIntervalCheck()`: Stops the interval check for expired keys.
|
|
290
|
+
* `hash(object: any, algorithm = 'sha256'): string`: Hashes an object with the algorithm. Default is `sha256`.
|
|
281
291
|
|
|
292
|
+
# Wrap / Memoization for Sync and Async Functions
|
|
293
|
+
|
|
294
|
+
`Cacheable` and `CacheableMemory` has a feature called `wrap` that allows you to wrap a function in a cache. This is useful for memoization and caching the results of a function. You can wrap a `sync` or `async` function in a cache. Here is an example of how to use the `wrap` function:
|
|
295
|
+
|
|
296
|
+
```javascript
|
|
297
|
+
import { Cacheable } from 'cacheable';
|
|
298
|
+
const asyncFunction = async (value: number) => {
|
|
299
|
+
return value * 2;
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
const cache = new Cacheable();
|
|
303
|
+
const wrappedFunction = cache.wrap(asyncFunction, { ttl: '1h' });
|
|
304
|
+
console.log(await wrappedFunction(2)); // 4
|
|
305
|
+
console.log(await wrappedFunction(2)); // 4 from cache
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
In this example we are wrapping an `async` function in a cache with a `ttl` of `1 hour`. This will cache the result of the function for `1 hour` and then expire the value. You can also wrap a `sync` function in a cache:
|
|
309
|
+
|
|
310
|
+
```javascript
|
|
311
|
+
import { CacheableMemory } from 'cacheable';
|
|
312
|
+
const syncFunction = (value: number) => {
|
|
313
|
+
return value * 2;
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
const cache = new CacheableMemory();
|
|
317
|
+
const wrappedFunction = cache.wrap(syncFunction, { ttl: '1h', key: 'syncFunction' });
|
|
318
|
+
console.log(wrappedFunction(2)); // 4
|
|
319
|
+
console.log(wrappedFunction(2)); // 4 from cache
|
|
320
|
+
console.log(cache.get('syncFunction')); // 4
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
In this example we are wrapping a `sync` function in a cache with a `ttl` of `1 hour`. This will cache the result of the function for `1 hour` and then expire the value. You can also set the `key` property in the `wrap()` options to set a custom key for the cache.
|
|
324
|
+
|
|
325
|
+
# Keyv Storage Adapter - KeyvCacheableMemory
|
|
326
|
+
|
|
327
|
+
`cacheable` comes with a built-in storage adapter for Keyv called `KeyvCacheableMemory`. This takes `CacheableMemory` and creates a storage adapter for Keyv. This is useful if you want to use `CacheableMemory` as a storage adapter for Keyv. Here is an example of how to use `KeyvCacheableMemory`:
|
|
328
|
+
|
|
329
|
+
```javascript
|
|
330
|
+
import { Keyv } from 'keyv';
|
|
331
|
+
import { KeyvCacheableMemory } from 'cacheable';
|
|
332
|
+
|
|
333
|
+
const keyv = new Keyv({ store: new KeyvCacheableMemory() });
|
|
334
|
+
await keyv.set('foo', 'bar');
|
|
335
|
+
const value = await keyv.get('key');
|
|
336
|
+
console.log(value); // bar
|
|
337
|
+
```
|
|
282
338
|
|
|
283
|
-
|
|
339
|
+
# How to Contribute
|
|
284
340
|
|
|
285
341
|
You can contribute by forking the repo and submitting a pull request. Please make sure to add tests and update the documentation. To learn more about how to contribute go to our main README [https://github.com/jaredwray/cacheable](https://github.com/jaredwray/cacheable). This will talk about how to `Open a Pull Request`, `Ask a Question`, or `Post an Issue`.
|
|
286
342
|
|
|
287
|
-
|
|
343
|
+
# License and Copyright
|
|
288
344
|
[MIT © Jared Wray](./LICENSE)
|