1 | ![Logo](./logo/logo.png)
|
2 |
|
3 | [![Node.js CI](https://github.com/node-cache/node-cache/workflows/Node.js%20CI/badge.svg?branch=master)](https://github.com/node-cache/node-cache/actions?query=workflow%3A%22Node.js+CI%22+branch%3A%22master%22)
|
4 | ![Dependency status](https://img.shields.io/david/node-cache/node-cache)
|
5 | [![NPM package version](https://img.shields.io/npm/v/node-cache?label=npm%20package)](https://www.npmjs.com/package/node-cache)
|
6 | [![NPM monthly downloads](https://img.shields.io/npm/dm/node-cache)](https://www.npmjs.com/package/node-cache)
|
7 | [![GitHub issues](https://img.shields.io/github/issues/node-cache/node-cache)](https://github.com/node-cache/node-cache/issues)
|
8 | [![Coveralls Coverage](https://img.shields.io/coveralls/node-cache/node-cache.svg)](https://coveralls.io/github/node-cache/node-cache)
|
9 |
|
10 | # Simple and fast NodeJS internal caching.
|
11 |
|
12 | A simple caching module that has `set`, `get` and `delete` methods and works a little bit like memcached.
|
13 | Keys can have a timeout (`ttl`) after which they expire and are deleted from the cache.
|
14 | All keys are stored in a single object so the practical limit is at around 1m keys.
|
15 |
|
16 |
|
17 | ## BREAKING MAJOR RELEASE v5.x
|
18 |
|
19 | The recent 5.x release:
|
20 | * dropped support for node versions before 8.x!
|
21 | * removed the callback-based api from all methods (you can re-enable them with the option `enableLegacyCallbacks`)
|
22 |
|
23 | ## BREAKING MAJOR RELEASE v6.x UPCOMING
|
24 |
|
25 | Although not breaking per definition, our typescript rewrite will change internal functions and their names.
|
26 | Please get in contact with us, if you are using some parts of node-cache's internal api so we can work something out!
|
27 |
|
28 |
|
29 | # Install
|
30 |
|
31 | ```bash
|
32 | npm install node-cache --save
|
33 | ```
|
34 |
|
35 | Or just require the `node_cache.js` file to get the superclass
|
36 |
|
37 | # Examples:
|
38 |
|
39 | ## Initialize (INIT):
|
40 |
|
41 | ```js
|
42 | const NodeCache = require( "node-cache" );
|
43 | const myCache = new NodeCache();
|
44 | ```
|
45 |
|
46 | ### Options
|
47 |
|
48 | - `stdTTL`: *(default: `0`)* the standard ttl as number in seconds for every generated cache element.
|
49 | `0` = unlimited
|
50 | - `checkperiod`: *(default: `600`)* The period in seconds, as a number, used for the automatic delete check interval.
|
51 | `0` = no periodic check.
|
52 | - `useClones`: *(default: `true`)* en/disable cloning of variables. If `true` you'll get a copy of the cached variable. If `false` you'll save and get just the reference.
|
53 | **Note:**
|
54 | - `true` is recommended if you want **simplicity**, because it'll behave like a server-based cache (it caches copies of plain data).
|
55 | - `false` is recommended if you want to achieve **performance** or save mutable objects or other complex types with mutability involved and wanted, because it'll only store references of your data.
|
56 | - _Here's a [simple code example](https://runkit.com/mpneuried/useclones-example-83) showing the different behavior_
|
57 | - `deleteOnExpire`: *(default: `true`)* whether variables will be deleted automatically when they expire.
|
58 | If `true` the variable will be deleted. If `false` the variable will remain. You are encouraged to handle the variable upon the event `expired` by yourself.
|
59 | - `enableLegacyCallbacks`: *(default: `false`)* re-enables the usage of callbacks instead of sync functions. Adds an additional `cb` argument to each function which resolves to `(err, result)`. will be removed in node-cache v6.x.
|
60 | - `maxKeys`: *(default: `-1`)* specifies a maximum amount of keys that can be stored in the cache. If a new item is set and the cache is full, an error is thrown and the key will not be saved in the cache. -1 disables the key limit.
|
61 |
|
62 | ```js
|
63 | const NodeCache = require( "node-cache" );
|
64 | const myCache = new NodeCache( { stdTTL: 100, checkperiod: 120 } );
|
65 | ```
|
66 |
|
67 | **Since `4.1.0`**:
|
68 | *Key-validation*: The keys can be given as either `string` or `number`, but are casted to a `string` internally anyway.
|
69 | All other types will throw an error.
|
70 |
|
71 | ## Store a key (SET):
|
72 |
|
73 | `myCache.set( key, val, [ ttl ] )`
|
74 |
|
75 | Sets a `key` `value` pair. It is possible to define a `ttl` (in seconds).
|
76 | Returns `true` on success.
|
77 |
|
78 | ```js
|
79 | obj = { my: "Special", variable: 42 };
|
80 |
|
81 | success = myCache.set( "myKey", obj, 10000 );
|
82 | // true
|
83 | ```
|
84 |
|
85 | > Note: If the key expires based on it's `ttl` it will be deleted entirely from the internal data object.
|
86 |
|
87 |
|
88 | ## Store multiple keys (MSET):
|
89 |
|
90 | `myCache.mset(Array<{key, val, ttl?}>)`
|
91 |
|
92 | Sets multiple `key` `val` pairs. It is possible to define a `ttl` (seconds).
|
93 | Returns `true` on success.
|
94 |
|
95 | ```js
|
96 | const obj = { my: "Special", variable: 42 };
|
97 | const obj2 = { my: "other special", variable: 1337 };
|
98 |
|
99 | const success = myCache.mset([
|
100 | {key: "myKey", val: obj, ttl: 10000},
|
101 | {key: "myKey2", val: obj2},
|
102 | ])
|
103 | ```
|
104 |
|
105 | ## Retrieve a key (GET):
|
106 |
|
107 | `myCache.get( key )`
|
108 |
|
109 | Gets a saved value from the cache.
|
110 | Returns a `undefined` if not found or expired.
|
111 | If the value was found it returns the `value`.
|
112 |
|
113 | ```js
|
114 | value = myCache.get( "myKey" );
|
115 | if ( value == undefined ){
|
116 | // handle miss!
|
117 | }
|
118 | // { my: "Special", variable: 42 }
|
119 | ```
|
120 |
|
121 | **Since `2.0.0`**:
|
122 |
|
123 | The return format changed to a simple value and a `ENOTFOUND` error if not found *( as result instance of `Error` )
|
124 |
|
125 | **Since `2.1.0`**:
|
126 |
|
127 | The return format changed to a simple value, but a due to discussion in #11 a miss shouldn't return an error.
|
128 | So after 2.1.0 a miss returns `undefined`.
|
129 |
|
130 | ## Take a key (TAKE):
|
131 |
|
132 | `myCache.take( key )`
|
133 |
|
134 | get the cached value and remove the key from the cache.
|
135 | Equivalent to calling `get(key)` + `del(key)`.
|
136 | Useful for implementing `single use` mechanism such as OTP, where once a value is read it will become obsolete.
|
137 |
|
138 | ```js
|
139 | myCache.set( "myKey", "myValue" )
|
140 | myCache.has( "myKey" ) // returns true because the key is cached right now
|
141 | value = myCache.take( "myKey" ) // value === "myValue"; this also deletes the key
|
142 | myCache.has( "myKey" ) // returns false because the key has been deleted
|
143 | ```
|
144 |
|
145 | ## Get multiple keys (MGET):
|
146 |
|
147 | `myCache.mget( [ key1, key2, ..., keyn ] )`
|
148 |
|
149 | Gets multiple saved values from the cache.
|
150 | Returns an empty object `{}` if not found or expired.
|
151 | If the value was found it returns an object with the `key` `value` pair.
|
152 |
|
153 | ```js
|
154 | value = myCache.mget( [ "myKeyA", "myKeyB" ] );
|
155 | /*
|
156 | {
|
157 | "myKeyA": { my: "Special", variable: 123 },
|
158 | "myKeyB": { the: "Glory", answer: 42 }
|
159 | }
|
160 | */
|
161 | ```
|
162 |
|
163 | **Since `2.0.0`**:
|
164 |
|
165 | The method for mget changed from `.get( [ "a", "b" ] )` to `.mget( [ "a", "b" ] )`
|
166 |
|
167 | ## Delete a key (DEL):
|
168 |
|
169 | `myCache.del( key )`
|
170 |
|
171 | Delete a key. Returns the number of deleted entries. A delete will never fail.
|
172 |
|
173 | ```js
|
174 | value = myCache.del( "A" );
|
175 | // 1
|
176 | ```
|
177 |
|
178 | ## Delete multiple keys (MDEL):
|
179 |
|
180 | `myCache.del( [ key1, key2, ..., keyn ] )`
|
181 |
|
182 | Delete multiple keys. Returns the number of deleted entries. A delete will never fail.
|
183 |
|
184 | ```js
|
185 | value = myCache.del( "A" );
|
186 | // 1
|
187 |
|
188 | value = myCache.del( [ "B", "C" ] );
|
189 | // 2
|
190 |
|
191 | value = myCache.del( [ "A", "B", "C", "D" ] );
|
192 | // 1 - because A, B and C not exists
|
193 | ```
|
194 |
|
195 | ## Change TTL (TTL):
|
196 |
|
197 | `myCache.ttl( key, ttl )`
|
198 |
|
199 | Redefine the ttl of a key. Returns true if the key has been found and changed. Otherwise returns false.
|
200 | If the ttl-argument isn't passed the default-TTL will be used.
|
201 |
|
202 | The key will be deleted when passing in a `ttl < 0`.
|
203 |
|
204 | ```js
|
205 | myCache = new NodeCache( { stdTTL: 100 } )
|
206 | changed = myCache.ttl( "existentKey", 100 )
|
207 | // true
|
208 |
|
209 | changed2 = myCache.ttl( "missingKey", 100 )
|
210 | // false
|
211 |
|
212 | changed3 = myCache.ttl( "existentKey" )
|
213 | // true
|
214 | ```
|
215 |
|
216 | ## Get TTL (getTTL):
|
217 |
|
218 | `myCache.getTtl( key )`
|
219 |
|
220 | Receive the ttl of a key.
|
221 | You will get:
|
222 | - `undefined` if the key does not exist
|
223 | - `0` if this key has no ttl
|
224 | - a timestamp in ms representing the time at which the key will expire
|
225 |
|
226 | ```js
|
227 | myCache = new NodeCache( { stdTTL: 100 } )
|
228 |
|
229 | // Date.now() = 1456000500000
|
230 | myCache.set( "ttlKey", "MyExpireData" )
|
231 | myCache.set( "noTtlKey", "NonExpireData", 0 )
|
232 |
|
233 | ts = myCache.getTtl( "ttlKey" )
|
234 | // ts wil be approximately 1456000600000
|
235 |
|
236 | ts = myCache.getTtl( "ttlKey" )
|
237 | // ts wil be approximately 1456000600000
|
238 |
|
239 | ts = myCache.getTtl( "noTtlKey" )
|
240 | // ts = 0
|
241 |
|
242 | ts = myCache.getTtl( "unknownKey" )
|
243 | // ts = undefined
|
244 | ```
|
245 |
|
246 | ## List keys (KEYS)
|
247 |
|
248 | `myCache.keys()`
|
249 |
|
250 | Returns an array of all existing keys.
|
251 |
|
252 | ```js
|
253 | mykeys = myCache.keys();
|
254 |
|
255 | console.log( mykeys );
|
256 | // [ "all", "my", "keys", "foo", "bar" ]
|
257 | ```
|
258 |
|
259 | ## Has key (HAS)
|
260 |
|
261 | `myCache.has( key )`
|
262 |
|
263 | Returns boolean indicating if the key is cached.
|
264 |
|
265 | ```js
|
266 | exists = myCache.has( 'myKey' );
|
267 |
|
268 | console.log( exists );
|
269 | ```
|
270 |
|
271 | ## Statistics (STATS):
|
272 |
|
273 | `myCache.getStats()`
|
274 |
|
275 | Returns the statistics.
|
276 |
|
277 | ```js
|
278 | myCache.getStats();
|
279 | /*
|
280 | {
|
281 | keys: 0, // global key count
|
282 | hits: 0, // global hit count
|
283 | misses: 0, // global miss count
|
284 | ksize: 0, // global key size count in approximately bytes
|
285 | vsize: 0 // global value size count in approximately bytes
|
286 | }
|
287 | */
|
288 | ```
|
289 |
|
290 | ## Flush all data (FLUSH):
|
291 |
|
292 | `myCache.flushAll()`
|
293 |
|
294 | Flush all data.
|
295 |
|
296 | ```js
|
297 | myCache.flushAll();
|
298 | myCache.getStats();
|
299 | /*
|
300 | {
|
301 | keys: 0, // global key count
|
302 | hits: 0, // global hit count
|
303 | misses: 0, // global miss count
|
304 | ksize: 0, // global key size count in approximately bytes
|
305 | vsize: 0 // global value size count in approximately bytes
|
306 | }
|
307 | */
|
308 | ```
|
309 |
|
310 | ## Flush the stats (FLUSH STATS):
|
311 |
|
312 | `myCache.flushStats()`
|
313 |
|
314 | Flush the stats.
|
315 |
|
316 | ```js
|
317 | myCache.flushStats();
|
318 | myCache.getStats();
|
319 | /*
|
320 | {
|
321 | keys: 0, // global key count
|
322 | hits: 0, // global hit count
|
323 | misses: 0, // global miss count
|
324 | ksize: 0, // global key size count in approximately bytes
|
325 | vsize: 0 // global value size count in approximately bytes
|
326 | }
|
327 | */
|
328 | ```
|
329 |
|
330 | ## Close the cache:
|
331 |
|
332 | `myCache.close()`
|
333 |
|
334 | This will clear the interval timeout which is set on check period option.
|
335 |
|
336 | ```js
|
337 | myCache.close();
|
338 | ```
|
339 |
|
340 | # Events
|
341 |
|
342 | ## set
|
343 |
|
344 | Fired when a key has been added or changed.
|
345 | You will get the `key` and the `value` as callback argument.
|
346 |
|
347 | ```js
|
348 | myCache.on( "set", function( key, value ){
|
349 | // ... do something ...
|
350 | });
|
351 | ```
|
352 |
|
353 | ## del
|
354 |
|
355 | Fired when a key has been removed manually or due to expiry.
|
356 | You will get the `key` and the deleted `value` as callback arguments.
|
357 |
|
358 | ```js
|
359 | myCache.on( "del", function( key, value ){
|
360 | // ... do something ...
|
361 | });
|
362 | ```
|
363 |
|
364 | ## expired
|
365 |
|
366 | Fired when a key expires.
|
367 | You will get the `key` and `value` as callback argument.
|
368 |
|
369 | ```js
|
370 | myCache.on( "expired", function( key, value ){
|
371 | // ... do something ...
|
372 | });
|
373 | ```
|
374 |
|
375 | ## flush
|
376 |
|
377 | Fired when the cache has been flushed.
|
378 |
|
379 | ```js
|
380 | myCache.on( "flush", function(){
|
381 | // ... do something ...
|
382 | });
|
383 | ```
|
384 |
|
385 | ## flush_stats
|
386 |
|
387 | Fired when the cache stats has been flushed.
|
388 |
|
389 | ```js
|
390 | myCache.on( "flush_stats", function(){
|
391 | // ... do something ...
|
392 | });
|
393 | ```
|
394 |
|
395 |
|
396 | ## Breaking changes
|
397 |
|
398 | ### version `2.x`
|
399 |
|
400 | Due to the [Issue #11](https://github.com/mpneuried/nodecache/issues/11) the return format of the `.get()` method has been changed!
|
401 |
|
402 | Instead of returning an object with the key `{ "myKey": "myValue" }` it returns the value itself `"myValue"`.
|
403 |
|
404 | ### version `3.x`
|
405 |
|
406 | Due to the [Issue #30](https://github.com/mpneuried/nodecache/issues/30) and [Issue #27](https://github.com/mpneuried/nodecache/issues/27) variables will now be cloned.
|
407 | This could break your code, because for some variable types ( e.g. Promise ) its not possible to clone them.
|
408 | You can disable the cloning by setting the option `useClones: false`. In this case it's compatible with version `2.x`.
|
409 |
|
410 | ### version `5.x`
|
411 |
|
412 | Callbacks are deprecated in this version. They are still useable when enabling the `enableLegacyCallbacks` option when initializing the cache. Callbacks will be completely removed in `6.x`.
|
413 |
|
414 | ## Compatibility
|
415 |
|
416 | Node-Cache supports all node versions >= 8
|
417 |
|
418 | ## Release History
|
419 | |Version|Date|Description|
|
420 | |:--:|:--:|:--|
|
421 | |5.1.1|2020-06-06|[#184], [#183] thanks [Jonah Werre](https://github.com/jwerre) for reporting [#181]!, [#180], Thanks [Titus](https://github.com/tstone) for [#169]!, Thanks [Ianfeather](https://github.com/Ianfeather) for [#168]!, Thanks [Adam Haglund](https://github.com/BeeeQueue) for [#176]|
|
422 | |5.1.0|2019-12-08|Add .take() from PR [#160] and .flushStats from PR [#161]. Thanks to [Sujesh Thekkepatt](https://github.com/sujeshthekkepatt) and [Gopalakrishna Palem](https://github.com/KrishnaPG)!|
|
423 | |5.0.2|2019-11-17|Fixed bug where expired values were deleted even though `deleteOnExpire` was set to `false`. Thanks to [fielding-wilson](https://github.com/fielding-wilson)!|
|
424 | |5.0.1|2019-10-31|Fixed bug where users could not set null values. Thanks to [StefanoSega](https://github.com/StefanoSega), [jwest23](https://github.com/jwest23) and [marudor](https://github.com/marudor)!|
|
425 | |5.0.0|2019-10-23|Remove lodash dependency, add .has(key) and .mset([{key,val,ttl}]) methods to the cache. Thanks to [Regev Brody](https://github.com/regevbr) for PR [#132] and [Sujesh Thekkepatt](https://github.com/sujeshthekkepatt) for PR [#142]! Also thank you, to all other contributors that remain unnamed here!|
|
426 | |4.2.1|2019-07-22|Upgrade lodash to version 4.17.15 to suppress messages about unrelated security vulnerability|
|
427 | |4.2.0|2018-02-01|Add options.promiseValueSize for promise value. Thanks to [Ryan Roemer](https://github.com/ryan-roemer) for the pull [#84]; Added option `deleteOnExpire`; Added DefinitelyTyped Typescript definitions. Thanks to [Ulf Seltmann](https://github.com/useltmann) for the pulls [#90] and [#92]; Thanks to [Daniel Jin](https://github.com/danieljin) for the readme fix in pull [#93]; Optimized test and ci configs.|
|
428 | |4.1.1|2016-12-21|fix internal check interval for node < 0.10.25, thats the default node for ubuntu 14.04. Thanks to [Jimmy Hwang](https://github.com/JimmyHwang) for the pull [#78](https://github.com/mpneuried/nodecache/pull/78); added more docker tests|
|
429 | |4.1.0|2016-09-23|Added tests for different key types; Added key validation (must be `string` or `number`); Fixed `.del` bug where trying to delete a `number` key resulted in no deletion at all.|
|
430 | |4.0.0|2016-09-20|Updated tests to mocha; Fixed `.ttl` bug to not delete key on `.ttl( key, 0 )`. This is also relevant if `stdTTL=0`. *This causes the breaking change to `4.0.0`.*|
|
431 | |3.2.1|2016-03-21|Updated lodash to 4.x.; optimized grunt |
|
432 | |3.2.0|2016-01-29|Added method `getTtl` to get the time when a key expires. See [#49](https://github.com/mpneuried/nodecache/issues/49)|
|
433 | |3.1.0|2016-01-29|Added option `errorOnMissing` to throw/callback an error o a miss during a `.get( "key" )`. Thanks to [David Godfrey](https://github.com/david-byng) for the pull [#45](https://github.com/mpneuried/nodecache/pull/45). Added docker files and a script to run test on different node versions locally|
|
434 | |3.0.1|2016-01-13|Added `.unref()` to the checkTimeout so until node `0.10` it's not necessary to call `.close()` when your script is done. Thanks to [Doug Moscrop](https://github.com/dougmoscrop) for the pull [#44](https://github.com/mpneuried/nodecache/pull/44).|
|
435 | |3.0.0|2015-05-29|Return a cloned version of the cached element and save a cloned version of a variable. This can be disabled by setting the option `useClones:false`. (Thanks for #27 to [cheshirecatalyst](https://github.com/cheshirecatalyst) and for #30 to [Matthieu Sieben](https://github.com/matthieusieben))|
|
436 | |~~2.2.0~~|~~2015-05-27~~|REVOKED VERSION, because of conficts. See [Issue #30](https://github.com/mpneuried/nodecache/issues/30). So `2.2.0` is now `3.0.0`|
|
437 | |2.1.1|2015-04-17|Passed old value to the `del` event. Thanks to [Qix](https://github.com/qix) for the pull.|
|
438 | |2.1.0|2015-04-17|Changed get miss to return `undefined` instead of an error. Thanks to all [#11](https://github.com/mpneuried/nodecache/issues/11) contributors |
|
439 | |2.0.1|2015-04-17|Added close function (Thanks to [ownagedj](https://github.com/ownagedj)). Changed the development environment to use grunt.|
|
440 | |2.0.0|2015-01-05|changed return format of `.get()` with a error return on a miss and added the `.mget()` method. *Side effect: Performance of .get() up to 330 times faster!*|
|
441 | |1.1.0|2015-01-05|added `.keys()` method to list all existing keys|
|
442 | |1.0.3|2014-11-07|fix for setting numeric values. Thanks to [kaspars](https://github.com/kaspars) + optimized key ckeck.|
|
443 | |1.0.2|2014-09-17|Small change for better ttl handling|
|
444 | |1.0.1|2014-05-22|Readme typos. Thanks to [mjschranz](https://github.com/mjschranz)|
|
445 | |1.0.0|2014-04-09|Made `callback`s optional. So it's now possible to use a syncron syntax. The old syntax should also work well. Push : Bugfix for the value `0`|
|
446 | |0.4.1|2013-10-02|Added the value to `expired` event|
|
447 | |0.4.0|2013-10-02|Added nodecache events|
|
448 | |0.3.2|2012-05-31|Added Travis tests|
|
449 |
|
450 | [![NPM](https://nodei.co/npm-dl/node-cache.png?months=6)](https://nodei.co/npm/node-cache/)
|
451 |
|
452 | ## Other projects
|
453 |
|
454 | |Name|Description|
|
455 | |:--|:--|
|
456 | |[**rsmq**](https://github.com/smrchy/rsmq)|A really simple message queue based on redis|
|
457 | |[**redis-heartbeat**](https://github.com/mpneuried/redis-heartbeat)|Pulse a heartbeat to redis. This can be used to detach or attach servers to nginx or similar problems.|
|
458 | |[**systemhealth**](https://github.com/mpneuried/systemhealth)|Node module to run simple custom checks for your machine or it's connections. It will use [redis-heartbeat](https://github.com/mpneuried/redis-heartbeat) to send the current state to redis.|
|
459 | |[**rsmq-cli**](https://github.com/mpneuried/rsmq-cli)|a terminal client for rsmq|
|
460 | |[**rest-rsmq**](https://github.com/smrchy/rest-rsmq)|REST interface for.|
|
461 | |[**redis-sessions**](https://github.com/smrchy/redis-sessions)|An advanced session store for NodeJS and Redis|
|
462 | |[**connect-redis-sessions**](https://github.com/mpneuried/connect-redis-sessions)|A connect or express middleware to simply use the [redis sessions](https://github.com/smrchy/redis-sessions). With [redis sessions](https://github.com/smrchy/redis-sessions) you can handle multiple sessions per user_id.|
|
463 | |[**redis-notifications**](https://github.com/mpneuried/redis-notifications)|A redis based notification engine. It implements the rsmq-worker to safely create notifications and recurring reports.|
|
464 | |[**nsq-logger**](https://github.com/mpneuried/nsq-logger)|Nsq service to read messages from all topics listed within a list of nsqlookupd services.|
|
465 | |[**nsq-topics**](https://github.com/mpneuried/nsq-topics)|Nsq helper to poll a nsqlookupd service for all it's topics and mirror it locally.|
|
466 | |[**nsq-nodes**](https://github.com/mpneuried/nsq-nodes)|Nsq helper to poll a nsqlookupd service for all it's nodes and mirror it locally.|
|
467 | |[**nsq-watch**](https://github.com/mpneuried/nsq-watch)|Watch one or many topics for unprocessed messages.|
|
468 | |[**hyperrequest**](https://github.com/mpneuried/hyperrequest)|A wrapper around [hyperquest](https://github.com/substack/hyperquest) to handle the results|
|
469 | |[**task-queue-worker**](https://github.com/smrchy/task-queue-worker)|A powerful tool for background processing of tasks that are run by making standard http requests
|
470 | |[**soyer**](https://github.com/mpneuried/soyer)|Soyer is small lib for server side use of Google Closure Templates with node.js.|
|
471 | |[**grunt-soy-compile**](https://github.com/mpneuried/grunt-soy-compile)|Compile Goggle Closure Templates ( SOY ) templates including the handling of XLIFF language files.|
|
472 | |[**backlunr**](https://github.com/mpneuried/backlunr)|A solution to bring Backbone Collections together with the browser fulltext search engine Lunr.js|
|
473 | |[**domel**](https://github.com/mpneuried/domel)|A simple dom helper if you want to get rid of jQuery|
|
474 | |[**obj-schema**](https://github.com/mpneuried/obj-schema)|Simple module to validate an object by a predefined schema|
|
475 |
|
476 | # The MIT License (MIT)
|
477 |
|
478 | Copyright © 2019 Mathias Peter and the node-cache maintainers, https://github.com/node-cache/node-cache
|
479 |
|
480 | Permission is hereby granted, free of charge, to any person obtaining
|
481 | a copy of this software and associated documentation files (the
|
482 | 'Software'), to deal in the Software without restriction, including
|
483 | without limitation the rights to use, copy, modify, merge, publish,
|
484 | distribute, sublicense, and/or sell copies of the Software, and to
|
485 | permit persons to whom the Software is furnished to do so, subject to
|
486 | the following conditions:
|
487 |
|
488 | The above copyright notice and this permission notice shall be
|
489 | included in all copies or substantial portions of the Software.
|
490 |
|
491 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
492 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
493 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
494 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
495 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
496 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
497 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
498 |
|
\ | No newline at end of file |