petty-cache 3.5.0 → 3.6.0

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/CHANGELOG.md CHANGED
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [3.6.0] - 2026-02-12
10
+ ### Changed
11
+ - Added the ability for `pettyCache.get`, `pettyCache.set`, and `pettyCache.patch` functions to support callbacks and promises.
12
+
9
13
  ## [3.5.0] - 2025-05-01
10
14
  ### Changed
11
15
  - Added the ability for `pettyCache.del` functions to support callbacks and promises.
package/LICENSE CHANGED
@@ -1,201 +1,21 @@
1
- Apache License
2
- Version 2.0, January 2004
3
- http://www.apache.org/licenses/
4
-
5
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
-
7
- 1. Definitions.
8
-
9
- "License" shall mean the terms and conditions for use, reproduction,
10
- and distribution as defined by Sections 1 through 9 of this document.
11
-
12
- "Licensor" shall mean the copyright owner or entity authorized by
13
- the copyright owner that is granting the License.
14
-
15
- "Legal Entity" shall mean the union of the acting entity and all
16
- other entities that control, are controlled by, or are under common
17
- control with that entity. For the purposes of this definition,
18
- "control" means (i) the power, direct or indirect, to cause the
19
- direction or management of such entity, whether by contract or
20
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
- outstanding shares, or (iii) beneficial ownership of such entity.
22
-
23
- "You" (or "Your") shall mean an individual or Legal Entity
24
- exercising permissions granted by this License.
25
-
26
- "Source" form shall mean the preferred form for making modifications,
27
- including but not limited to software source code, documentation
28
- source, and configuration files.
29
-
30
- "Object" form shall mean any form resulting from mechanical
31
- transformation or translation of a Source form, including but
32
- not limited to compiled object code, generated documentation,
33
- and conversions to other media types.
34
-
35
- "Work" shall mean the work of authorship, whether in Source or
36
- Object form, made available under the License, as indicated by a
37
- copyright notice that is included in or attached to the work
38
- (an example is provided in the Appendix below).
39
-
40
- "Derivative Works" shall mean any work, whether in Source or Object
41
- form, that is based on (or derived from) the Work and for which the
42
- editorial revisions, annotations, elaborations, or other modifications
43
- represent, as a whole, an original work of authorship. For the purposes
44
- of this License, Derivative Works shall not include works that remain
45
- separable from, or merely link (or bind by name) to the interfaces of,
46
- the Work and Derivative Works thereof.
47
-
48
- "Contribution" shall mean any work of authorship, including
49
- the original version of the Work and any modifications or additions
50
- to that Work or Derivative Works thereof, that is intentionally
51
- submitted to Licensor for inclusion in the Work by the copyright owner
52
- or by an individual or Legal Entity authorized to submit on behalf of
53
- the copyright owner. For the purposes of this definition, "submitted"
54
- means any form of electronic, verbal, or written communication sent
55
- to the Licensor or its representatives, including but not limited to
56
- communication on electronic mailing lists, source code control systems,
57
- and issue tracking systems that are managed by, or on behalf of, the
58
- Licensor for the purpose of discussing and improving the Work, but
59
- excluding communication that is conspicuously marked or otherwise
60
- designated in writing by the copyright owner as "Not a Contribution."
61
-
62
- "Contributor" shall mean Licensor and any individual or Legal Entity
63
- on behalf of whom a Contribution has been received by Licensor and
64
- subsequently incorporated within the Work.
65
-
66
- 2. Grant of Copyright License. Subject to the terms and conditions of
67
- this License, each Contributor hereby grants to You a perpetual,
68
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
- copyright license to reproduce, prepare Derivative Works of,
70
- publicly display, publicly perform, sublicense, and distribute the
71
- Work and such Derivative Works in Source or Object form.
72
-
73
- 3. Grant of Patent License. Subject to the terms and conditions of
74
- this License, each Contributor hereby grants to You a perpetual,
75
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
- (except as stated in this section) patent license to make, have made,
77
- use, offer to sell, sell, import, and otherwise transfer the Work,
78
- where such license applies only to those patent claims licensable
79
- by such Contributor that are necessarily infringed by their
80
- Contribution(s) alone or by combination of their Contribution(s)
81
- with the Work to which such Contribution(s) was submitted. If You
82
- institute patent litigation against any entity (including a
83
- cross-claim or counterclaim in a lawsuit) alleging that the Work
84
- or a Contribution incorporated within the Work constitutes direct
85
- or contributory patent infringement, then any patent licenses
86
- granted to You under this License for that Work shall terminate
87
- as of the date such litigation is filed.
88
-
89
- 4. Redistribution. You may reproduce and distribute copies of the
90
- Work or Derivative Works thereof in any medium, with or without
91
- modifications, and in Source or Object form, provided that You
92
- meet the following conditions:
93
-
94
- (a) You must give any other recipients of the Work or
95
- Derivative Works a copy of this License; and
96
-
97
- (b) You must cause any modified files to carry prominent notices
98
- stating that You changed the files; and
99
-
100
- (c) You must retain, in the Source form of any Derivative Works
101
- that You distribute, all copyright, patent, trademark, and
102
- attribution notices from the Source form of the Work,
103
- excluding those notices that do not pertain to any part of
104
- the Derivative Works; and
105
-
106
- (d) If the Work includes a "NOTICE" text file as part of its
107
- distribution, then any Derivative Works that You distribute must
108
- include a readable copy of the attribution notices contained
109
- within such NOTICE file, excluding those notices that do not
110
- pertain to any part of the Derivative Works, in at least one
111
- of the following places: within a NOTICE text file distributed
112
- as part of the Derivative Works; within the Source form or
113
- documentation, if provided along with the Derivative Works; or,
114
- within a display generated by the Derivative Works, if and
115
- wherever such third-party notices normally appear. The contents
116
- of the NOTICE file are for informational purposes only and
117
- do not modify the License. You may add Your own attribution
118
- notices within Derivative Works that You distribute, alongside
119
- or as an addendum to the NOTICE text from the Work, provided
120
- that such additional attribution notices cannot be construed
121
- as modifying the License.
122
-
123
- You may add Your own copyright statement to Your modifications and
124
- may provide additional or different license terms and conditions
125
- for use, reproduction, or distribution of Your modifications, or
126
- for any such Derivative Works as a whole, provided Your use,
127
- reproduction, and distribution of the Work otherwise complies with
128
- the conditions stated in this License.
129
-
130
- 5. Submission of Contributions. Unless You explicitly state otherwise,
131
- any Contribution intentionally submitted for inclusion in the Work
132
- by You to the Licensor shall be under the terms and conditions of
133
- this License, without any additional terms or conditions.
134
- Notwithstanding the above, nothing herein shall supersede or modify
135
- the terms of any separate license agreement you may have executed
136
- with Licensor regarding such Contributions.
137
-
138
- 6. Trademarks. This License does not grant permission to use the trade
139
- names, trademarks, service marks, or product names of the Licensor,
140
- except as required for reasonable and customary use in describing the
141
- origin of the Work and reproducing the content of the NOTICE file.
142
-
143
- 7. Disclaimer of Warranty. Unless required by applicable law or
144
- agreed to in writing, Licensor provides the Work (and each
145
- Contributor provides its Contributions) on an "AS IS" BASIS,
146
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
- implied, including, without limitation, any warranties or conditions
148
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
- PARTICULAR PURPOSE. You are solely responsible for determining the
150
- appropriateness of using or redistributing the Work and assume any
151
- risks associated with Your exercise of permissions under this License.
152
-
153
- 8. Limitation of Liability. In no event and under no legal theory,
154
- whether in tort (including negligence), contract, or otherwise,
155
- unless required by applicable law (such as deliberate and grossly
156
- negligent acts) or agreed to in writing, shall any Contributor be
157
- liable to You for damages, including any direct, indirect, special,
158
- incidental, or consequential damages of any character arising as a
159
- result of this License or out of the use or inability to use the
160
- Work (including but not limited to damages for loss of goodwill,
161
- work stoppage, computer failure or malfunction, or any and all
162
- other commercial damages or losses), even if such Contributor
163
- has been advised of the possibility of such damages.
164
-
165
- 9. Accepting Warranty or Additional Liability. While redistributing
166
- the Work or Derivative Works thereof, You may choose to offer,
167
- and charge a fee for, acceptance of support, warranty, indemnity,
168
- or other liability obligations and/or rights consistent with this
169
- License. However, in accepting such obligations, You may act only
170
- on Your own behalf and on Your sole responsibility, not on behalf
171
- of any other Contributor, and only if You agree to indemnify,
172
- defend, and hold each Contributor harmless for any liability
173
- incurred by, or claims asserted against, such Contributor by reason
174
- of your accepting any such warranty or additional liability.
175
-
176
- END OF TERMS AND CONDITIONS
177
-
178
- APPENDIX: How to apply the Apache License to your work.
179
-
180
- To apply the Apache License to your work, attach the following
181
- boilerplate notice, with the fields enclosed by brackets "{}"
182
- replaced with your own identifying information. (Don't include
183
- the brackets!) The text should be enclosed in the appropriate
184
- comment syntax for the file format. We also recommend that a
185
- file or class name and description of purpose be included on the
186
- same "printed page" as the copyright notice for easier
187
- identification within third-party archives.
188
-
189
- Copyright {yyyy} {name of copyright owner}
190
-
191
- Licensed under the Apache License, Version 2.0 (the "License");
192
- you may not use this file except in compliance with the License.
193
- You may obtain a copy of the License at
194
-
195
- http://www.apache.org/licenses/LICENSE-2.0
196
-
197
- Unless required by applicable law or agreed to in writing, software
198
- distributed under the License is distributed on an "AS IS" BASIS,
199
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
- See the License for the specific language governing permissions and
201
- limitations under the License.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Stores.com
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # petty-cache
2
2
 
3
- [![Build Status](https://github.com/mediocre/petty-cache/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/mediocre/petty-cache/actions?query=workflow%3Abuild+branch%3Amain)
4
- [![Coverage Status](https://coveralls.io/repos/github/mediocre/petty-cache/badge.svg?branch=main)](https://coveralls.io/github/mediocre/petty-cache?branch=main)
3
+ [![Build Status](https://github.com/stores-com/petty-cache/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/stores-com/petty-cache/actions?query=workflow%3Abuild+branch%3Amain)
4
+ [![Coverage Status](https://coveralls.io/repos/github/stores-com/petty-cache/badge.svg?branch=main)](https://coveralls.io/github/stores-com/petty-cache?branch=main)
5
5
 
6
6
  A cache module for Node.js that uses a two-level cache (in-memory cache for recently accessed data plus Redis for distributed caching) with automatic serialization plus some extra features to avoid cache stampedes and thundering herds.
7
7
 
@@ -28,8 +28,8 @@ Provides a pool of distributed locks with the ability to release a slot back to
28
28
 
29
29
  ```javascript
30
30
  // Setup petty-cache
31
- var PettyCache = require('petty-cache');
32
- var pettyCache = new PettyCache();
31
+ const PettyCache = require('petty-cache');
32
+ const pettyCache = new PettyCache();
33
33
 
34
34
  // Fetch some data
35
35
  pettyCache.fetch('key', function(callback) {
@@ -71,7 +71,7 @@ Attempts to retrieve the values of the keys specified in the `keys` array. Any k
71
71
  ```javascript
72
72
  // Let's assume a and b are already cached as 1 and 2
73
73
  pettyCache.bulkFetch(['a', 'b', 'c', 'd'], function(keys, callback) {
74
- var results = {};
74
+ const results = {};
75
75
 
76
76
  keys.forEach(function(key) {
77
77
  results[key] = key.toUpperCase();
@@ -145,6 +145,24 @@ pettyCache.set({ key1: 'one', key2: 2, key3: 'three' }, function(err) {
145
145
  }
146
146
  ```
147
147
 
148
+ ### pettyCache.del(key, [callback])
149
+
150
+ Deletes a value from both the in-memory cache and Redis. Supports both callbacks and promises.
151
+
152
+ **Example**
153
+
154
+ ```javascript
155
+ pettyCache.del('key', function(err) {
156
+ if (err) {
157
+ // Handle redis error
158
+ }
159
+ });
160
+ ```
161
+
162
+ ```javascript
163
+ await pettyCache.del('key');
164
+ ```
165
+
148
166
  ### pettyCache.fetch(key, cacheMissFunction, [options,] callback)
149
167
 
150
168
  Attempts to retrieve the value from cache at the specified key. If it doesn't exist, it executes the specified cacheMissFunction that takes two parameters: an error and a value. `cacheMissFunction` should retrieve the expected value for the key from another source and pass it to the given callback. Either way, the resulting error or value is passed to `callback`.
@@ -222,9 +240,9 @@ pettyCache.fetchAndRefresh('key', function(callback) {
222
240
  }
223
241
  ```
224
242
 
225
- ### pettyCache.get(key, callback)
243
+ ### pettyCache.get(key, [callback])
226
244
 
227
- Attempts to retrieve the value from cache at the specified key. Returns `null` if the key doesn't exist.
245
+ Attempts to retrieve the value from cache at the specified key. Returns `null` if the key doesn't exist. Supports both callbacks and promises.
228
246
 
229
247
  **Example**
230
248
 
@@ -235,14 +253,18 @@ pettyCache.get('key', function(err, value) {
235
253
  });
236
254
  ```
237
255
 
238
- ### pettyCache.patch(key, value, [options,] callback)
256
+ ```javascript
257
+ const value = await pettyCache.get('key');
258
+ ```
259
+
260
+ ### pettyCache.patch(key, value, [options, [callback]])
239
261
 
240
- Updates an object at the given key with the property values provided. Sends an error to the callback if the key does not exist.
262
+ Updates an object at the given key with the property values provided. Sends an error to the callback if the key does not exist. Supports both callbacks and promises.
241
263
 
242
264
  **Example**
243
265
 
244
266
  ```javascript
245
- pettyCache.patch('key', { a: 1 }, function(callback) {
267
+ pettyCache.patch('key', { a: 1 }, function(err) {
246
268
  if (err) {
247
269
  // Handle redis or key not found error
248
270
  }
@@ -251,6 +273,10 @@ pettyCache.patch('key', { a: 1 }, function(callback) {
251
273
  });
252
274
  ```
253
275
 
276
+ ```javascript
277
+ await pettyCache.patch('key', { a: 1 });
278
+ ```
279
+
254
280
  **Options**
255
281
 
256
282
  ```
@@ -269,9 +295,9 @@ pettyCache.patch('key', { a: 1 }, function(callback) {
269
295
  }
270
296
  ```
271
297
 
272
- ### pettyCache.set(key, value, [options,] callback)
298
+ ### pettyCache.set(key, value, [options, [callback]])
273
299
 
274
- Unconditionally sets a value for a given key.
300
+ Unconditionally sets a value for a given key. Supports both callbacks and promises.
275
301
 
276
302
  **Example**
277
303
 
@@ -283,6 +309,10 @@ pettyCache.set('key', { a: 'b' }, function(err) {
283
309
  });
284
310
  ```
285
311
 
312
+ ```javascript
313
+ await pettyCache.set('key', { a: 'b' });
314
+ ```
315
+
286
316
  **Options**
287
317
 
288
318
  ```
@@ -305,7 +335,7 @@ pettyCache.set('key', { a: 'b' }, function(err) {
305
335
 
306
336
  ### pettyCache.mutex.lock(key, [options, [callback]])
307
337
 
308
- Attempts to acquire a distributed lock for the specified key. Optionally retries a specified number of times by waiting a specified amount of time between attempts.
338
+ Attempts to acquire a distributed lock for the specified key. Optionally retries a specified number of times by waiting a specified amount of time between attempts. Supports both callbacks and promises.
309
339
 
310
340
  ```javascript
311
341
  pettyCache.mutex.lock('key', { retry: { interval: 100, times: 5 }, ttl: 1000 }, function(err) {
@@ -318,6 +348,13 @@ pettyCache.mutex.lock('key', { retry: { interval: 100, times: 5 }, ttl: 1000 },
318
348
  });
319
349
  ```
320
350
 
351
+ ```javascript
352
+ await pettyCache.mutex.lock('key', { retry: { interval: 100, times: 5 }, ttl: 1000 });
353
+
354
+ // We were able to acquire the lock. Do work and then unlock.
355
+ await pettyCache.mutex.unlock('key');
356
+ ```
357
+
321
358
  **Options**
322
359
 
323
360
  ```javascript
@@ -332,7 +369,7 @@ pettyCache.mutex.lock('key', { retry: { interval: 100, times: 5 }, ttl: 1000 },
332
369
 
333
370
  ### pettyCache.mutex.unlock(key, [callback])
334
371
 
335
- Releases the distributed lock for the specified key.
372
+ Releases the distributed lock for the specified key. Supports both callbacks and promises.
336
373
 
337
374
  ```javascript
338
375
  pettyCache.mutex.unlock('key', function(err) {
@@ -342,6 +379,10 @@ pettyCache.mutex.unlock('key', function(err) {
342
379
  });
343
380
  ```
344
381
 
382
+ ```javascript
383
+ await pettyCache.mutex.unlock('key');
384
+ ```
385
+
345
386
  ## Semaphore
346
387
 
347
388
  Provides a pool of distributed locks. Once a consumer acquires a lock they have the ability to release the lock back to the pool or mark the lock as "consumed" so that it's not used again.
@@ -471,6 +512,6 @@ pettyCache.semaphore.retrieveOrCreate('key', { size: 10 }, function(err) {
471
512
 
472
513
  ```javascript
473
514
  {
474
- size: 1 || function() { var x = 1 + 1; callback(null, x); } // The number of locks to create in the semaphore's pool. Optionally, size can be a `callback(err, size)` function.
515
+ size: 1 || function() { const x = 1 + 1; callback(null, x); } // The number of locks to create in the semaphore's pool. Optionally, size can be a `callback(err, size)` function.
475
516
  }
476
517
  ```
package/eslint.config.js CHANGED
@@ -4,30 +4,16 @@ const js = require('@eslint/js');
4
4
  module.exports = [
5
5
  js.configs.recommended,
6
6
  {
7
- ignores: ['node_modules/*'],
8
7
  languageOptions: {
9
- ecmaVersion: 2020,
10
- sourceType: 'module',
11
- parserOptions: {
12
- ecmaFeatures: {
13
- jsx: true
14
- }
15
- },
16
8
  globals: {
17
- ...globals.es2020,
18
- ...globals.mocha,
19
- ...globals.node,
20
- //added for 'fetch()' access
21
- ...globals.serviceworker
9
+ ...globals.node
22
10
  }
23
11
  },
24
12
  rules: {
25
13
  'brace-style': ['error', '1tbs', { allowSingleLine: true }],
26
14
  'comma-dangle': ['error', 'never'],
27
15
  'dot-notation': 'error',
28
- 'no-array-constructor': 'error',
29
16
  'no-console': 'error',
30
- 'no-fallthrough': 'off',
31
17
  'no-inline-comments': 'warn',
32
18
  'no-trailing-spaces': 'error',
33
19
  'no-unused-vars': ['error', { caughtErrors: 'none' }],
package/index.js CHANGED
@@ -18,16 +18,16 @@ function PettyCache() {
18
18
 
19
19
  function bulkGetFromRedis(keys, callback) {
20
20
  // Try to get values from Redis
21
- redisClient.mget(keys, function(err, data) {
21
+ redisClient.mget(keys, (err, data) => {
22
22
  if (err) {
23
23
  return callback(err);
24
24
  }
25
25
 
26
26
  const values = {};
27
27
 
28
- for (var i = 0; i < keys.length; i++) {
29
- var key = keys[i];
30
- var value = data[i];
28
+ for (let i = 0; i < keys.length; i++) {
29
+ const key = keys[i];
30
+ const value = data[i];
31
31
 
32
32
  if (value === null) {
33
33
  values[key] = { exists: false };
@@ -61,7 +61,7 @@ function PettyCache() {
61
61
 
62
62
  function getFromRedis(key, callback) {
63
63
  // Try to get value from Redis
64
- redisClient.get(key, function(err, data) {
64
+ redisClient.get(key, (err, data) => {
65
65
  if (err) {
66
66
  return callback(err);
67
67
  }
@@ -103,7 +103,7 @@ function PettyCache() {
103
103
  /**
104
104
  * @param {Array} keys - An array of keys.
105
105
  */
106
- this.bulkFetch = function(keys, func, options, callback) {
106
+ this.bulkFetch = (keys, func, options, callback) => {
107
107
  // Options are optional
108
108
  if (!callback) {
109
109
  callback = options;
@@ -119,7 +119,7 @@ function PettyCache() {
119
119
  const values = {};
120
120
 
121
121
  // Try to get values from memory cache
122
- for (var i = _keys.length - 1; i >= 0; i--) {
122
+ for (let i = _keys.length - 1; i >= 0; i--) {
123
123
  const key = _keys[i];
124
124
  const result = getFromMemoryCache(key);
125
125
 
@@ -137,12 +137,12 @@ function PettyCache() {
137
137
  const _this = this;
138
138
 
139
139
  // Try to get values from Redis
140
- bulkGetFromRedis(_keys, function(err, results) {
140
+ bulkGetFromRedis(_keys, (err, results) => {
141
141
  if (err) {
142
142
  return callback(err);
143
143
  }
144
144
 
145
- for (var i = _keys.length - 1; i >= 0; i--) {
145
+ for (let i = _keys.length - 1; i >= 0; i--) {
146
146
  const key = _keys[i];
147
147
  const result = results[key];
148
148
 
@@ -161,7 +161,7 @@ function PettyCache() {
161
161
  }
162
162
 
163
163
  // Execute the specified function for remaining keys
164
- func(_keys, function(err, data) {
164
+ func(_keys, (err, data) => {
165
165
  if (err) {
166
166
  return callback(err);
167
167
  }
@@ -176,7 +176,7 @@ function PettyCache() {
176
176
  /**
177
177
  * @param {Array} keys - An array of keys.
178
178
  */
179
- this.bulkGet = function(keys, callback) {
179
+ this.bulkGet = (keys, callback) => {
180
180
  // If there aren't any keys, return
181
181
  if (!keys.length) {
182
182
  return callback(null, {});
@@ -186,7 +186,7 @@ function PettyCache() {
186
186
  const values = {};
187
187
 
188
188
  // Try to get values from memory cache
189
- for (var i = _keys.length - 1; i >= 0; i--) {
189
+ for (let i = _keys.length - 1; i >= 0; i--) {
190
190
  const key = _keys[i];
191
191
  const result = getFromMemoryCache(key);
192
192
 
@@ -202,14 +202,14 @@ function PettyCache() {
202
202
  }
203
203
 
204
204
  // Try to get values from Redis
205
- bulkGetFromRedis(_keys, function(err, results) {
205
+ bulkGetFromRedis(_keys, (err, results) => {
206
206
  if (err) {
207
207
  return callback(err);
208
208
  }
209
209
 
210
- for (var i = 0; i < _keys.length; i++) {
211
- var key = _keys[i];
212
- var result = results[key];
210
+ for (let i = 0; i < _keys.length; i++) {
211
+ const key = _keys[i];
212
+ const result = results[key];
213
213
 
214
214
  if (!result.exists) {
215
215
  values[key] = null;
@@ -226,7 +226,7 @@ function PettyCache() {
226
226
  });
227
227
  };
228
228
 
229
- this.bulkSet = function(values, options, callback) {
229
+ this.bulkSet = (values, options, callback) => {
230
230
  // Options are optional
231
231
  if (!callback) {
232
232
  callback = options;
@@ -249,15 +249,15 @@ function PettyCache() {
249
249
  batch.psetex(key, random(ttl.min, ttl.max), PettyCache.stringify(value));
250
250
  });
251
251
 
252
- batch.exec(function(err) {
252
+ batch.exec((err) => {
253
253
  callback(err);
254
254
  });
255
255
  };
256
256
 
257
- this.del = function(key, callback) {
257
+ this.del = (key, callback) => {
258
258
  const executor = () => {
259
259
  return new Promise((resolve, reject) => {
260
- redisClient.del(key, function(err) {
260
+ redisClient.del(key, (err) => {
261
261
  if (err) {
262
262
  return reject(err);
263
263
  }
@@ -277,7 +277,7 @@ function PettyCache() {
277
277
 
278
278
  // Returns data from cache if available;
279
279
  // otherwise executes the specified function and places the results in cache before returning the data.
280
- this.fetch = function(key, func, options, callback) {
280
+ this.fetch = (key, func, options, callback) => {
281
281
  options = options || {};
282
282
 
283
283
  if (typeof options === 'function') {
@@ -286,10 +286,10 @@ function PettyCache() {
286
286
  }
287
287
 
288
288
  // Default callback is a noop
289
- callback = callback || function() {};
289
+ callback = callback || (() => {});
290
290
 
291
291
  // Try to get value from memory cache
292
- var result = getFromMemoryCache(key);
292
+ let result = getFromMemoryCache(key);
293
293
 
294
294
  // Return value from memory cache if it exists
295
295
  if (result.exists) {
@@ -299,8 +299,8 @@ function PettyCache() {
299
299
  const _this = this;
300
300
 
301
301
  // Double-checked locking: http://en.wikipedia.org/wiki/Double-checked_locking
302
- lock(`fetch-memory-cache-lock-${key}`, function(releaseMemoryCacheLock) {
303
- async.reflect(function(callback) {
302
+ lock(`fetch-memory-cache-lock-${key}`, (releaseMemoryCacheLock) => {
303
+ async.reflect((callback) => {
304
304
  // Try to get value from memory cache
305
305
  result = getFromMemoryCache(key);
306
306
 
@@ -310,7 +310,7 @@ function PettyCache() {
310
310
  }
311
311
 
312
312
  // Try to get value from Redis
313
- getFromRedis(key, function(err, result) {
313
+ getFromRedis(key, (err, result) => {
314
314
  if (err) {
315
315
  return callback(err);
316
316
  }
@@ -322,8 +322,8 @@ function PettyCache() {
322
322
  }
323
323
 
324
324
  // Double-checked locking: http://en.wikipedia.org/wiki/Double-checked_locking
325
- lock(`fetch-redis-lock-${key}`, function(releaseRedisLock) {
326
- async.reflect(function(callback) {
325
+ lock(`fetch-redis-lock-${key}`, (releaseRedisLock) => {
326
+ async.reflect((callback) => {
327
327
  // Try to get value from memory cache
328
328
  result = getFromMemoryCache(key);
329
329
 
@@ -333,7 +333,7 @@ function PettyCache() {
333
333
  }
334
334
 
335
335
  // Try to get value from Redis
336
- getFromRedis(key, async function(err, result) {
336
+ getFromRedis(key, async (err, result) => {
337
337
  if (err) {
338
338
  return callback(err);
339
339
  }
@@ -350,7 +350,7 @@ function PettyCache() {
350
350
  try {
351
351
  const data = await func();
352
352
 
353
- _this.set(key, data, options, function(err) {
353
+ _this.set(key, data, options, (err) => {
354
354
  callback(err, data);
355
355
  });
356
356
  } catch(err) {
@@ -358,18 +358,18 @@ function PettyCache() {
358
358
  }
359
359
  } else {
360
360
  // If the function has arguments, there was a callback provided
361
- func(function(err, data) {
361
+ func((err, data) => {
362
362
  if (err) {
363
363
  return callback(err);
364
364
  }
365
365
 
366
- _this.set(key, data, options, function(err) {
366
+ _this.set(key, data, options, (err) => {
367
367
  callback(err, data);
368
368
  });
369
369
  });
370
370
  }
371
371
  });
372
- })(releaseRedisLock(function(err, result) {
372
+ })(releaseRedisLock((err, result) => {
373
373
  if (result.error) {
374
374
  return callback(result.error);
375
375
  }
@@ -378,7 +378,7 @@ function PettyCache() {
378
378
  }));
379
379
  });
380
380
  });
381
- })(releaseMemoryCacheLock(function(err, result) {
381
+ })(releaseMemoryCacheLock((err, result) => {
382
382
  if (result.error) {
383
383
  return callback(result.error);
384
384
  }
@@ -388,7 +388,7 @@ function PettyCache() {
388
388
  });
389
389
  };
390
390
 
391
- this.fetchAndRefresh = function(key, func, options, callback) {
391
+ this.fetchAndRefresh = (key, func, options, callback) => {
392
392
  options = options || {};
393
393
 
394
394
  if (typeof options === 'function') {
@@ -400,22 +400,22 @@ function PettyCache() {
400
400
  const ttl = getTtl(options);
401
401
 
402
402
  // Default callback is a noop
403
- callback = callback || function() {};
403
+ callback = callback || (() => {});
404
404
 
405
405
  const _this = this;
406
406
 
407
407
  if (!intervals[key]) {
408
408
  const delay = ttl.min / 2;
409
409
 
410
- intervals[key] = setInterval(function() {
410
+ intervals[key] = setInterval(() => {
411
411
  // This distributed lock prevents multiple clients from executing func at the same time
412
- _this.mutex.lock(`interval-${key}`, { ttl: delay - 100 }, function(err) {
412
+ _this.mutex.lock(`interval-${key}`, { ttl: delay - 100 }, (err) => {
413
413
  if (err) {
414
414
  return;
415
415
  }
416
416
 
417
417
  // Execute the specified function and update cache
418
- func(function(err, data) {
418
+ func((err, data) => {
419
419
  if (err) {
420
420
  return;
421
421
  }
@@ -429,46 +429,56 @@ function PettyCache() {
429
429
  this.fetch(key, func, options, callback);
430
430
  };
431
431
 
432
- this.get = function(key, callback) {
433
- // Try to get value from memory cache
434
- let result = getFromMemoryCache(key);
435
-
436
- // Return value from memory cache if it exists
437
- if (result.exists) {
438
- return callback(null, result.value);
439
- }
440
-
441
- // Double-checked locking: http://en.wikipedia.org/wiki/Double-checked_locking
442
- lock(`get-memory-cache-lock-${key}`, function(releaseMemoryCacheLock) {
443
- async.reflect(function(callback) {
432
+ this.get = (key, callback) => {
433
+ const executor = () => {
434
+ return new Promise((resolve, reject) => {
444
435
  // Try to get value from memory cache
445
- result = getFromMemoryCache(key);
436
+ let result = getFromMemoryCache(key);
446
437
 
447
438
  // Return value from memory cache if it exists
448
439
  if (result.exists) {
449
- return callback(null, result.value);
440
+ return resolve(result.value);
450
441
  }
451
442
 
452
- getFromRedis(key, function(err, result) {
453
- if (err) {
454
- return callback(err);
455
- }
443
+ // Double-checked locking: http://en.wikipedia.org/wiki/Double-checked_locking
444
+ lock(`get-memory-cache-lock-${key}`, (releaseMemoryCacheLock) => {
445
+ async.reflect((callback) => {
446
+ // Try to get value from memory cache
447
+ result = getFromMemoryCache(key);
456
448
 
457
- if (!result.exists) {
458
- return callback(null, null);
459
- }
449
+ // Return value from memory cache if it exists
450
+ if (result.exists) {
451
+ return callback(null, result.value);
452
+ }
460
453
 
461
- memoryCache.put(key, result.value, random(2000, 5000));
462
- callback(null, result.value);
454
+ getFromRedis(key, (err, result) => {
455
+ if (err) {
456
+ return callback(err);
457
+ }
458
+
459
+ if (!result.exists) {
460
+ return callback(null, null);
461
+ }
462
+
463
+ memoryCache.put(key, result.value, random(2000, 5000));
464
+ callback(null, result.value);
465
+ });
466
+ })(releaseMemoryCacheLock((err, result) => {
467
+ if (result.error) {
468
+ return reject(result.error);
469
+ }
470
+
471
+ resolve(result.value);
472
+ }));
463
473
  });
464
- })(releaseMemoryCacheLock(function(err, result) {
465
- if (result.error) {
466
- return callback(result.error);
467
- }
474
+ });
475
+ };
468
476
 
469
- callback(null, result.value);
470
- }));
471
- });
477
+ if (callback) {
478
+ executor().then(result => callback(null, result)).catch(callback);
479
+ } else {
480
+ return executor();
481
+ }
472
482
  };
473
483
 
474
484
  this.mutex = {
@@ -489,7 +499,7 @@ function PettyCache() {
489
499
  const executor = () => {
490
500
  return new Promise((resolve, reject) => {
491
501
  async.retry({ interval: options.retry.interval, times: options.retry.times }, callback => {
492
- redisClient.set(key, '1', 'NX', 'PX', options.ttl, function(err, res) {
502
+ redisClient.set(key, '1', 'NX', 'PX', options.ttl, (err, res) => {
493
503
  if (err) {
494
504
  return callback(err);
495
505
  }
@@ -504,7 +514,7 @@ function PettyCache() {
504
514
 
505
515
  callback();
506
516
  });
507
- }, function(err) {
517
+ }, (err) => {
508
518
  if (err) {
509
519
  return reject(err);
510
520
  }
@@ -523,7 +533,7 @@ function PettyCache() {
523
533
  unlock: (key, callback) => {
524
534
  const executor = () => {
525
535
  return new Promise((resolve, reject) => {
526
- redisClient.del(key, function(err) {
536
+ redisClient.del(key, (err) => {
527
537
  if (err) {
528
538
  return reject(err);
529
539
  }
@@ -541,33 +551,51 @@ function PettyCache() {
541
551
  }
542
552
  };
543
553
 
544
- this.patch = function(key, value, options, callback) {
545
- if (!callback) {
554
+ this.patch = (key, value, options, callback) => {
555
+ if (!callback && typeof options === 'function') {
546
556
  callback = options;
547
557
  options = {};
548
558
  }
549
559
 
560
+ options = options || {};
561
+
550
562
  const _this = this;
551
563
 
552
- this.get(key, function(err, data) {
553
- if (err) {
554
- return callback(err);
555
- }
564
+ const executor = () => {
565
+ return new Promise((resolve, reject) => {
566
+ _this.get(key, (err, data) => {
567
+ if (err) {
568
+ return reject(err);
569
+ }
556
570
 
557
- if (!data) {
558
- return callback(new Error(`Key ${key} does not exist`));
559
- }
571
+ if (!data) {
572
+ return reject(new Error(`Key ${key} does not exist`));
573
+ }
560
574
 
561
- for (var k in value) {
562
- data[k] = value[k];
563
- }
575
+ for (let k in value) {
576
+ data[k] = value[k];
577
+ }
564
578
 
565
- _this.set(key, data, options, callback);
566
- });
579
+ _this.set(key, data, options, (err) => {
580
+ if (err) {
581
+ return reject(err);
582
+ }
583
+
584
+ resolve();
585
+ });
586
+ });
587
+ });
588
+ };
589
+
590
+ if (callback) {
591
+ executor().then(result => callback(null, result)).catch(callback);
592
+ } else {
593
+ return executor();
594
+ }
567
595
  };
568
596
 
569
597
  this.semaphore = {
570
- acquireLock: function(key, options, callback) {
598
+ acquireLock: (key, options, callback) => {
571
599
  // Options are optional
572
600
  if (!callback && typeof options === 'function') {
573
601
  callback = options;
@@ -583,14 +611,14 @@ function PettyCache() {
583
611
 
584
612
  const _this = this;
585
613
 
586
- async.retry({ interval: options.retry.interval, times: options.retry.times }, function(callback) {
614
+ async.retry({ interval: options.retry.interval, times: options.retry.times }, (callback) => {
587
615
  // Mutex lock around semaphore
588
- _this.mutex.lock(`lock:${key}`, { retry: { times: 100 } }, function(err) {
616
+ _this.mutex.lock(`lock:${key}`, { retry: { times: 100 } }, (err) => {
589
617
  if (err) {
590
618
  return callback(err);
591
619
  }
592
620
 
593
- redisClient.get(key, function(err, data) {
621
+ redisClient.get(key, (err, data) => {
594
622
  // If we encountered an error, unlock the mutex lock and return error
595
623
  if (err) {
596
624
  return _this.mutex.unlock(`lock:${key}`, () => { callback(err); });
@@ -601,10 +629,10 @@ function PettyCache() {
601
629
  return _this.mutex.unlock(`lock:${key}`, () => { callback(new Error(`Semaphore ${key} doesn't exist.`)); });
602
630
  }
603
631
 
604
- var pool = JSON.parse(data);
632
+ const pool = JSON.parse(data);
605
633
 
606
634
  // Try to find a slot that's available.
607
- var index = pool.findIndex(s => s.status === 'available');
635
+ let index = pool.findIndex(s => s.status === 'available');
608
636
 
609
637
  if (index === -1) {
610
638
  index = pool.findIndex(s => s.ttl <= Date.now());
@@ -617,7 +645,7 @@ function PettyCache() {
617
645
 
618
646
  pool[index] = { status: 'acquired', ttl: Date.now() + options.ttl };
619
647
 
620
- redisClient.set(key, JSON.stringify(pool), function(err) {
648
+ redisClient.set(key, JSON.stringify(pool), (err) => {
621
649
  if (err) {
622
650
  return _this.mutex.unlock(`lock:${key}`, () => { callback(err); });
623
651
  }
@@ -628,18 +656,18 @@ function PettyCache() {
628
656
  });
629
657
  }, callback);
630
658
  },
631
- consumeLock: function(key, index, callback) {
632
- callback = callback || function() {};
659
+ consumeLock: (key, index, callback) => {
660
+ callback = callback || (() => {});
633
661
 
634
662
  const _this = this;
635
663
 
636
664
  // Mutex lock around semaphore
637
- _this.mutex.lock(`lock:${key}`, { retry: { times: 100 } }, function(err) {
665
+ _this.mutex.lock(`lock:${key}`, { retry: { times: 100 } }, (err) => {
638
666
  if (err) {
639
667
  return callback(err);
640
668
  }
641
669
 
642
- redisClient.get(key, function(err, data) {
670
+ redisClient.get(key, (err, data) => {
643
671
  // If we encountered an error, unlock the mutex lock and return error
644
672
  if (err) {
645
673
  return _this.mutex.unlock(`lock:${key}`, () => { callback(err); });
@@ -650,7 +678,7 @@ function PettyCache() {
650
678
  return _this.mutex.unlock(`lock:${key}`, () => { callback(new Error(`Semaphore ${key} doesn't exist.`)); });
651
679
  }
652
680
 
653
- var pool = JSON.parse(data);
681
+ const pool = JSON.parse(data);
654
682
 
655
683
  // Ensure index exists.
656
684
  if (pool.length <= index) {
@@ -664,7 +692,7 @@ function PettyCache() {
664
692
  pool[index] = { status: 'available' };
665
693
  }
666
694
 
667
- redisClient.set(key, JSON.stringify(pool), function(err) {
695
+ redisClient.set(key, JSON.stringify(pool), (err) => {
668
696
  if (err) {
669
697
  return _this.mutex.unlock(`lock:${key}`, () => { callback(err); });
670
698
  }
@@ -674,17 +702,17 @@ function PettyCache() {
674
702
  });
675
703
  });
676
704
  },
677
- expand: function(key, size, callback) {
678
- callback = callback || function() {};
705
+ expand: (key, size, callback) => {
706
+ callback = callback || (() => {});
679
707
 
680
708
  const _this = this;
681
709
 
682
- _this.mutex.lock(`lock:${key}`, { retry: { times: 100 } }, function(err) {
710
+ _this.mutex.lock(`lock:${key}`, { retry: { times: 100 } }, (err) => {
683
711
  if (err) {
684
712
  return callback(err);
685
713
  }
686
714
 
687
- redisClient.get(key, function(err, data) {
715
+ redisClient.get(key, (err, data) => {
688
716
  // If we encountered an error, unlock the mutex lock and return error
689
717
  if (err) {
690
718
  return _this.mutex.unlock(`lock:${key}`, () => { callback(err); });
@@ -695,7 +723,7 @@ function PettyCache() {
695
723
  return _this.mutex.unlock(`lock:${key}`, () => { callback(new Error(`Semaphore ${key} doesn't exist.`)); });
696
724
  }
697
725
 
698
- var pool = JSON.parse(data);
726
+ let pool = JSON.parse(data);
699
727
 
700
728
  if (pool.length > size) {
701
729
  return _this.mutex.unlock(`lock:${key}`, () => { callback(new Error(`Cannot shrink pool, size is ${pool.length} and you requested a size of ${size}.`)); });
@@ -707,7 +735,7 @@ function PettyCache() {
707
735
 
708
736
  pool = pool.concat(Array(size - pool.length).fill({ status: 'available' }));
709
737
 
710
- redisClient.set(key, JSON.stringify(pool), function(err) {
738
+ redisClient.set(key, JSON.stringify(pool), (err) => {
711
739
  if (err) {
712
740
  return _this.mutex.unlock(`lock:${key}`, () => { callback(err); });
713
741
  }
@@ -717,18 +745,18 @@ function PettyCache() {
717
745
  });
718
746
  });
719
747
  },
720
- releaseLock: function(key, index, callback) {
721
- callback = callback || function() {};
748
+ releaseLock: (key, index, callback) => {
749
+ callback = callback || (() => {});
722
750
 
723
751
  const _this = this;
724
752
 
725
753
  // Mutex lock around semaphore
726
- _this.mutex.lock(`lock:${key}`, { retry: { times: 100 } }, function(err) {
754
+ _this.mutex.lock(`lock:${key}`, { retry: { times: 100 } }, (err) => {
727
755
  if (err) {
728
756
  return callback(err);
729
757
  }
730
758
 
731
- redisClient.get(key, function(err, data) {
759
+ redisClient.get(key, (err, data) => {
732
760
  // If we encountered an error, unlock the mutex lock and return error
733
761
  if (err) {
734
762
  return _this.mutex.unlock(`lock:${key}`, () => { callback(err); });
@@ -739,7 +767,7 @@ function PettyCache() {
739
767
  return _this.mutex.unlock(`lock:${key}`, () => { callback(new Error(`Semaphore ${key} doesn't exist.`)); });
740
768
  }
741
769
 
742
- var pool = JSON.parse(data);
770
+ const pool = JSON.parse(data);
743
771
 
744
772
  // Ensure index exists.
745
773
  if (pool.length <= index) {
@@ -748,7 +776,7 @@ function PettyCache() {
748
776
 
749
777
  pool[index] = { status: 'available' };
750
778
 
751
- redisClient.set(key, JSON.stringify(pool), function(err) {
779
+ redisClient.set(key, JSON.stringify(pool), (err) => {
752
780
  if (err) {
753
781
  return _this.mutex.unlock(`lock:${key}`, () => { callback(err); });
754
782
  }
@@ -758,19 +786,19 @@ function PettyCache() {
758
786
  });
759
787
  });
760
788
  },
761
- reset: function(key, callback) {
762
- callback = callback || function() {};
789
+ reset: (key, callback) => {
790
+ callback = callback || (() => {});
763
791
 
764
792
  const _this = this;
765
793
 
766
794
  // Mutex lock around semaphore
767
- this.mutex.lock(`lock:${key}`, { retry: { times: 100 } }, function(err) {
795
+ this.mutex.lock(`lock:${key}`, { retry: { times: 100 } }, (err) => {
768
796
  if (err) {
769
797
  return callback(err);
770
798
  }
771
799
 
772
800
  // Try to get previously created semaphore
773
- redisClient.get(key, function(err, data) {
801
+ redisClient.get(key, (err, data) => {
774
802
  // If we encountered an error, unlock the mutex lock and return error
775
803
  if (err) {
776
804
  return _this.mutex.unlock(`lock:${key}`, () => { callback(err); });
@@ -781,10 +809,10 @@ function PettyCache() {
781
809
  return _this.mutex.unlock(`lock:${key}`, () => { callback(new Error(`Semaphore ${key} doesn't exist.`)); });
782
810
  }
783
811
 
784
- var pool = JSON.parse(data);
812
+ let pool = JSON.parse(data);
785
813
  pool = Array(pool.length).fill({ status: 'available' });
786
814
 
787
- redisClient.set(key, JSON.stringify(pool), function(err) {
815
+ redisClient.set(key, JSON.stringify(pool), (err) => {
788
816
  if (err) {
789
817
  return _this.mutex.unlock(`lock:${key}`, () => { callback(err); });
790
818
  }
@@ -794,26 +822,26 @@ function PettyCache() {
794
822
  });
795
823
  });
796
824
  },
797
- retrieveOrCreate: function(key, options, callback) {
825
+ retrieveOrCreate: (key, options, callback) => {
798
826
  // Options are optional
799
827
  if (!callback && typeof options === 'function') {
800
828
  callback = options;
801
829
  options = {};
802
830
  }
803
831
 
804
- callback = callback || function() {};
832
+ callback = callback || (() => {});
805
833
  options = options || {};
806
834
 
807
835
  const _this = this;
808
836
 
809
837
  // Mutex lock around semaphore retrival or creation
810
- this.mutex.lock(`lock:${key}`, { retry: { times: 100 } }, function(err) {
838
+ this.mutex.lock(`lock:${key}`, { retry: { times: 100 } }, (err) => {
811
839
  if (err) {
812
840
  return callback(err);
813
841
  }
814
842
 
815
843
  // Try to get previously created semaphore
816
- redisClient.get(key, function(err, data) {
844
+ redisClient.get(key, (err, data) => {
817
845
  // If we encountered an error, unlock the mutex lock and return error
818
846
  if (err) {
819
847
  return _this.mutex.unlock(`lock:${key}`, () => { callback(err); });
@@ -824,7 +852,7 @@ function PettyCache() {
824
852
  return _this.mutex.unlock(`lock:${key}`, () => { callback(null, JSON.parse(data)); });
825
853
  }
826
854
 
827
- var getSize = function(callback) {
855
+ const getSize = (callback) => {
828
856
  if (typeof options.size === 'function') {
829
857
  return options.size(callback);
830
858
  }
@@ -832,15 +860,15 @@ function PettyCache() {
832
860
  callback(null, Object.prototype.hasOwnProperty.call(options, 'size') ? options.size : 1);
833
861
  };
834
862
 
835
- getSize(function(err, size) {
863
+ getSize((err, size) => {
836
864
  // If we encountered an error, unlock the mutex lock and return error
837
865
  if (err) {
838
866
  return _this.mutex.unlock(`lock:${key}`, () => { callback(err); });
839
867
  }
840
868
 
841
- var pool = Array(Math.max(size, 1)).fill({ status: 'available' });
869
+ const pool = Array(Math.max(size, 1)).fill({ status: 'available' });
842
870
 
843
- redisClient.set(key, JSON.stringify(pool), function(err) {
871
+ redisClient.set(key, JSON.stringify(pool), (err) => {
844
872
  if (err) {
845
873
  return _this.mutex.unlock(`lock:${key}`, () => { callback(err); });
846
874
  }
@@ -853,7 +881,7 @@ function PettyCache() {
853
881
  }
854
882
  };
855
883
 
856
- this.set = function(key, value, options, callback) {
884
+ this.set = (key, value, options, callback) => {
857
885
  options = options || {};
858
886
 
859
887
  if (typeof options === 'function') {
@@ -864,18 +892,31 @@ function PettyCache() {
864
892
  // Get TTL based on specified options
865
893
  const ttl = getTtl(options);
866
894
 
867
- // Default callback is a noop
868
- callback = callback || function() {};
895
+ const executor = () => {
896
+ return new Promise((resolve, reject) => {
897
+ // Store value in memory cache with a short expiration
898
+ memoryCache.put(key, value, random(2000, 5000));
869
899
 
870
- // Store value in memory cache with a short expiration
871
- memoryCache.put(key, value, random(2000, 5000));
900
+ // Store value in Redis
901
+ redisClient.psetex(key, random(ttl.min, ttl.max), PettyCache.stringify(value), (err) => {
902
+ if (err) {
903
+ return reject(err);
904
+ }
905
+
906
+ resolve();
907
+ });
908
+ });
909
+ };
872
910
 
873
- // Store value is Redis
874
- redisClient.psetex(key, random(ttl.min, ttl.max), PettyCache.stringify(value), callback);
911
+ if (callback) {
912
+ executor().then(result => callback(null, result)).catch(callback);
913
+ } else {
914
+ return executor();
915
+ }
875
916
  };
876
917
 
877
918
  // Semaphore functions need to be bound to the main PettyCache object
878
- for (var method in this.semaphore) {
919
+ for (const method in this.semaphore) {
879
920
  this.semaphore[method] = this.semaphore[method].bind(this);
880
921
  }
881
922
  }
@@ -888,8 +929,8 @@ function random(min, max) {
888
929
  return Math.floor(Math.random() * (max - min + 1) + min);
889
930
  }
890
931
 
891
- PettyCache.parse = function(text) {
892
- return JSON.parse(text, function(k, v) {
932
+ PettyCache.parse = (text) => {
933
+ return JSON.parse(text, (k, v) => {
893
934
  if (v === '__NaN') {
894
935
  return NaN;
895
936
  } else if (v === '__null') {
@@ -902,8 +943,8 @@ PettyCache.parse = function(text) {
902
943
  });
903
944
  };
904
945
 
905
- PettyCache.stringify = function(value) {
906
- return JSON.stringify(value, function(k, v) {
946
+ PettyCache.stringify = (value) => {
947
+ return JSON.stringify(value, (k, v) => {
907
948
  if (typeof v === 'number' && isNaN(v)) {
908
949
  return '__NaN';
909
950
  } else if (v === null) {
package/package.json CHANGED
@@ -1,36 +1,30 @@
1
1
  {
2
- "description": "A cache module for node.js that uses a two-level cache (in-memory cache for recently accessed data plus Redis for distributed caching) with some extra features to avoid cache stampedes and thundering herds.",
3
- "dependencies": {
4
- "async": "~3.2.6",
5
- "lock": "~1.1.0",
6
- "memory-cache": "~0.2.0",
7
- "redis": "~3.1.0"
8
- },
9
- "devDependencies": {
10
- "@eslint/js": "*",
11
- "globals": "*",
12
- "coveralls": "*",
13
- "mocha": "*",
14
- "nyc": "*"
15
- },
16
- "homepage": "https://github.com/mediocre/petty-cache",
17
- "keywords": [
18
- "cache",
19
- "lock",
20
- "mutex",
21
- "redis",
22
- "semaphore"
23
- ],
24
- "license": "Apache-2.0",
25
- "main": "index.js",
26
- "name": "petty-cache",
27
- "scripts": {
28
- "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls",
29
- "test": "mocha --exit --reporter spec"
30
- },
31
- "repository": {
32
- "type": "git",
33
- "url": "https://github.com/mediocre/petty-cache.git"
34
- },
35
- "version": "3.5.0"
2
+ "dependencies": {
3
+ "async": "~3.2.6",
4
+ "lock": "~1.1.0",
5
+ "memory-cache": "~0.2.0",
6
+ "redis": "~3.1.0"
7
+ },
8
+ "description": "A cache module for node.js that uses a two-level cache (in-memory cache for recently accessed data plus Redis for distributed caching) with some extra features to avoid cache stampedes and thundering herds.",
9
+ "devDependencies": {
10
+ "@eslint/js": "*",
11
+ "globals": "*"
12
+ },
13
+ "homepage": "https://github.com/stores-com/petty-cache",
14
+ "keywords": [
15
+ "cache",
16
+ "lock",
17
+ "mutex",
18
+ "redis",
19
+ "semaphore"
20
+ ],
21
+ "license": "MIT",
22
+ "main": "index.js",
23
+ "name": "petty-cache",
24
+ "repository": "https://github.com/stores-com/petty-cache",
25
+ "scripts": {
26
+ "coveralls": "node --test --test-concurrency=true --test-force-exit --experimental-test-coverage --test-reporter=spec --test-reporter-destination=stdout --test-reporter=lcov --test-reporter-destination=lcov.info && coveralls < lcov.info",
27
+ "test": "node --test --test-concurrency=true --test-force-exit --test-reporter=spec"
28
+ },
29
+ "version": "3.6.0"
36
30
  }