cacheable 1.7.1 → 1.8.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/README.md +32 -1
- package/dist/index.cjs +84 -5
- package/dist/index.d.cts +29 -4
- package/dist/index.d.ts +29 -4
- package/dist/index.js +72 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
* [Cacheable Statistics (Instance Only)](#cacheable-statistics-instance-only)
|
|
37
37
|
* [API](#api)
|
|
38
38
|
* [CacheableMemory - In-Memory Cache](#cacheablememory---in-memory-cache)
|
|
39
|
+
* [Wrap / Memoization for Sync and Async Functions](#wrap--memoization-for-sync-and-async-functions)
|
|
39
40
|
* [How to Contribute](#how-to-contribute)
|
|
40
41
|
* [License and Copyright](#license-and-copyright)
|
|
41
42
|
|
|
@@ -218,12 +219,13 @@ _This does not enable statistics for your layer 2 cache as that is a distributed
|
|
|
218
219
|
* `delete(key)`: Deletes a value from the cache.
|
|
219
220
|
* `deleteMany([keys])`: Deletes multiple values from the cache.
|
|
220
221
|
* `clear()`: Clears the cache stores. Be careful with this as it will clear both layer 1 and layer 2.
|
|
221
|
-
* `wrap(function,
|
|
222
|
+
* `wrap(function, WrapOptions)`: Wraps an `async` function in a cache.
|
|
222
223
|
* `disconnect()`: Disconnects from the cache stores.
|
|
223
224
|
* `onHook(hook, callback)`: Sets a hook.
|
|
224
225
|
* `removeHook(hook)`: Removes a hook.
|
|
225
226
|
* `on(event, callback)`: Listens for an event.
|
|
226
227
|
* `removeListener(event, callback)`: Removes a listener.
|
|
228
|
+
* `hash(object: any, algorithm = 'sha256'): string`: Hashes an object with the algorithm. Default is `sha256`.
|
|
227
229
|
* `primary`: The primary store for the cache (layer 1) defaults to in-memory by Keyv.
|
|
228
230
|
* `secondary`: The secondary store for the cache (layer 2) usually a persistent cache by Keyv.
|
|
229
231
|
* `nonBlocking`: If the secondary store is non-blocking. Default is `false`.
|
|
@@ -271,6 +273,7 @@ By default we use lazy expiration deletion which means on `get` and `getMany` ty
|
|
|
271
273
|
* `deleteMany([keys])`: Deletes multiple values from the cache.
|
|
272
274
|
* `take(key)`: Takes a value from the cache and deletes it.
|
|
273
275
|
* `takeMany([keys])`: Takes multiple values from the cache and deletes them.
|
|
276
|
+
* `wrap(function, WrapSyncOptions)`: Wraps a `sync` function in a cache.
|
|
274
277
|
* `clear()`: Clears the cache.
|
|
275
278
|
* `size()`: The number of keys in the cache.
|
|
276
279
|
* `keys()`: The keys in the cache.
|
|
@@ -278,7 +281,35 @@ By default we use lazy expiration deletion which means on `get` and `getMany` ty
|
|
|
278
281
|
* `checkExpired()`: Checks for expired keys in the cache. This is used by the `checkInterval` property.
|
|
279
282
|
* `startIntervalCheck()`: Starts the interval check for expired keys if `checkInterval` is above 0 ms.
|
|
280
283
|
* `stopIntervalCheck()`: Stops the interval check for expired keys.
|
|
284
|
+
* `hash(object: any, algorithm = 'sha256'): string`: Hashes an object with the algorithm. Default is `sha256`.
|
|
281
285
|
|
|
286
|
+
## Wrap / Memoization for Sync and Async Functions
|
|
287
|
+
|
|
288
|
+
`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:
|
|
289
|
+
|
|
290
|
+
```javascript
|
|
291
|
+
import { Cacheable } from 'cacheable';
|
|
292
|
+
const asyncFunction = async (value: number) => {
|
|
293
|
+
return value * 2;
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
const cache = new Cacheable();
|
|
297
|
+
const wrappedFunction = cache.wrap(asyncFunction, { ttl: '1h' });
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
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:
|
|
301
|
+
|
|
302
|
+
```javascript
|
|
303
|
+
import { CacheableMemory } from 'cacheable';
|
|
304
|
+
const syncFunction = (value: number) => {
|
|
305
|
+
return value * 2;
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
const cache = new CacheableMemory();
|
|
309
|
+
const wrappedFunction = cache.wrap(syncFunction, { ttl: '1h' });
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
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.
|
|
282
313
|
|
|
283
314
|
## How to Contribute
|
|
284
315
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -25,9 +35,13 @@ __export(src_exports, {
|
|
|
25
35
|
CacheableHooks: () => CacheableHooks,
|
|
26
36
|
CacheableMemory: () => CacheableMemory,
|
|
27
37
|
CacheableStats: () => CacheableStats,
|
|
38
|
+
Keyv: () => import_keyv2.Keyv,
|
|
28
39
|
KeyvCacheableMemory: () => KeyvCacheableMemory,
|
|
40
|
+
KeyvHooks: () => import_keyv2.KeyvHooks,
|
|
29
41
|
shorthandToMilliseconds: () => shorthandToMilliseconds,
|
|
30
|
-
shorthandToTime: () => shorthandToTime
|
|
42
|
+
shorthandToTime: () => shorthandToTime,
|
|
43
|
+
wrap: () => wrap,
|
|
44
|
+
wrapSync: () => wrapSync
|
|
31
45
|
});
|
|
32
46
|
module.exports = __toCommonJS(src_exports);
|
|
33
47
|
var import_keyv = require("keyv");
|
|
@@ -100,6 +114,32 @@ var shorthandToTime = (shorthand, fromDate) => {
|
|
|
100
114
|
return fromDate.getTime() + milliseconds;
|
|
101
115
|
};
|
|
102
116
|
|
|
117
|
+
// src/wrap.ts
|
|
118
|
+
function wrapSync(function_, options) {
|
|
119
|
+
const { ttl, key, cache } = options;
|
|
120
|
+
return function(...arguments_) {
|
|
121
|
+
const cacheKey = key ?? cache.hash(arguments_);
|
|
122
|
+
let value = cache.get(cacheKey);
|
|
123
|
+
if (value === void 0) {
|
|
124
|
+
value = function_(...arguments_);
|
|
125
|
+
cache.set(cacheKey, value, ttl);
|
|
126
|
+
}
|
|
127
|
+
return value;
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function wrap(function_, options) {
|
|
131
|
+
const { ttl, key, cache } = options;
|
|
132
|
+
return async function(...arguments_) {
|
|
133
|
+
const cacheKey = key ?? cache.hash(arguments_);
|
|
134
|
+
let value = await cache.get(cacheKey);
|
|
135
|
+
if (value === void 0) {
|
|
136
|
+
value = await function_(...arguments_);
|
|
137
|
+
await cache.set(cacheKey, value, ttl);
|
|
138
|
+
}
|
|
139
|
+
return value;
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
103
143
|
// src/memory-lru.ts
|
|
104
144
|
var ListNode = class {
|
|
105
145
|
// eslint-disable-next-line @typescript-eslint/parameter-properties
|
|
@@ -173,6 +213,18 @@ var DoublyLinkedList = class {
|
|
|
173
213
|
}
|
|
174
214
|
};
|
|
175
215
|
|
|
216
|
+
// src/hash.ts
|
|
217
|
+
var crypto = __toESM(require("crypto"), 1);
|
|
218
|
+
function hash(object, algorithm = "sha256") {
|
|
219
|
+
const objectString = JSON.stringify(object);
|
|
220
|
+
if (!crypto.getHashes().includes(algorithm)) {
|
|
221
|
+
throw new Error(`Unsupported hash algorithm: '${algorithm}'`);
|
|
222
|
+
}
|
|
223
|
+
const hasher = crypto.createHash(algorithm);
|
|
224
|
+
hasher.update(objectString);
|
|
225
|
+
return hasher.digest("hex");
|
|
226
|
+
}
|
|
227
|
+
|
|
176
228
|
// src/memory.ts
|
|
177
229
|
var CacheableMemory = class {
|
|
178
230
|
_hashCache = /* @__PURE__ */ new Map();
|
|
@@ -370,12 +422,12 @@ var CacheableMemory = class {
|
|
|
370
422
|
if (cacheHashNumber) {
|
|
371
423
|
return cacheHashNumber;
|
|
372
424
|
}
|
|
373
|
-
let
|
|
425
|
+
let hash2 = 0;
|
|
374
426
|
const primeMultiplier = 31;
|
|
375
427
|
for (let i = 0; i < key.length; i++) {
|
|
376
|
-
|
|
428
|
+
hash2 = hash2 * primeMultiplier + key.charCodeAt(i);
|
|
377
429
|
}
|
|
378
|
-
const result = Math.abs(
|
|
430
|
+
const result = Math.abs(hash2) % 10;
|
|
379
431
|
this._hashCache.set(key, result);
|
|
380
432
|
return result;
|
|
381
433
|
}
|
|
@@ -466,6 +518,17 @@ var CacheableMemory = class {
|
|
|
466
518
|
this._interval = 0;
|
|
467
519
|
this._checkInterval = 0;
|
|
468
520
|
}
|
|
521
|
+
hash(object, algorithm = "sha256") {
|
|
522
|
+
return hash(object, algorithm);
|
|
523
|
+
}
|
|
524
|
+
wrap(function_, options = {}) {
|
|
525
|
+
const wrapOptions = {
|
|
526
|
+
ttl: options.ttl,
|
|
527
|
+
key: options.key,
|
|
528
|
+
cache: this
|
|
529
|
+
};
|
|
530
|
+
return wrapSync(function_, wrapOptions);
|
|
531
|
+
}
|
|
469
532
|
isPrimitive(value) {
|
|
470
533
|
const result = false;
|
|
471
534
|
if (value === null || value === void 0) {
|
|
@@ -719,6 +782,7 @@ var CacheableStats = class {
|
|
|
719
782
|
};
|
|
720
783
|
|
|
721
784
|
// src/index.ts
|
|
785
|
+
var import_keyv2 = require("keyv");
|
|
722
786
|
var CacheableHooks = /* @__PURE__ */ ((CacheableHooks2) => {
|
|
723
787
|
CacheableHooks2["BEFORE_SET"] = "BEFORE_SET";
|
|
724
788
|
CacheableHooks2["AFTER_SET"] = "AFTER_SET";
|
|
@@ -1014,6 +1078,17 @@ var Cacheable = class extends import_hookified.Hookified {
|
|
|
1014
1078
|
}
|
|
1015
1079
|
await (this._nonBlocking ? Promise.race(promises) : Promise.all(promises));
|
|
1016
1080
|
}
|
|
1081
|
+
wrap(function_, options = {}) {
|
|
1082
|
+
const wrapOptions = {
|
|
1083
|
+
ttl: options.ttl,
|
|
1084
|
+
key: options.key,
|
|
1085
|
+
cache: this
|
|
1086
|
+
};
|
|
1087
|
+
return wrap(function_, wrapOptions);
|
|
1088
|
+
}
|
|
1089
|
+
hash(object, algorithm = "sha256") {
|
|
1090
|
+
return hash(object, algorithm);
|
|
1091
|
+
}
|
|
1017
1092
|
async deleteManyKeyv(keyv, keys) {
|
|
1018
1093
|
const promises = [];
|
|
1019
1094
|
for (const key of keys) {
|
|
@@ -1055,7 +1130,11 @@ var Cacheable = class extends import_hookified.Hookified {
|
|
|
1055
1130
|
CacheableHooks,
|
|
1056
1131
|
CacheableMemory,
|
|
1057
1132
|
CacheableStats,
|
|
1133
|
+
Keyv,
|
|
1058
1134
|
KeyvCacheableMemory,
|
|
1135
|
+
KeyvHooks,
|
|
1059
1136
|
shorthandToMilliseconds,
|
|
1060
|
-
shorthandToTime
|
|
1137
|
+
shorthandToTime,
|
|
1138
|
+
wrap,
|
|
1139
|
+
wrapSync
|
|
1061
1140
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { KeyvStoreAdapter, StoredData, Keyv } from 'keyv';
|
|
2
|
+
export { Keyv, KeyvHooks, KeyvOptions, KeyvStoreAdapter } from 'keyv';
|
|
2
3
|
import { Hookified } from 'hookified';
|
|
3
4
|
|
|
4
5
|
type CacheableOptions$1 = {
|
|
@@ -93,8 +94,8 @@ declare class CacheableMemory {
|
|
|
93
94
|
get size(): number;
|
|
94
95
|
get keys(): IterableIterator<string>;
|
|
95
96
|
get items(): IterableIterator<CacheableStoreItem>;
|
|
96
|
-
get<T>(key: string):
|
|
97
|
-
getMany<T>(keys: string[]):
|
|
97
|
+
get<T>(key: string): T | undefined;
|
|
98
|
+
getMany<T>(keys: string[]): T[];
|
|
98
99
|
getRaw(key: string): CacheableStoreItem | undefined;
|
|
99
100
|
getManyRaw(keys: string[]): Array<CacheableStoreItem | undefined>;
|
|
100
101
|
set(key: string, value: any, ttl?: number | string): void;
|
|
@@ -114,6 +115,11 @@ declare class CacheableMemory {
|
|
|
114
115
|
checkExpiration(): void;
|
|
115
116
|
startIntervalCheck(): void;
|
|
116
117
|
stopIntervalCheck(): void;
|
|
118
|
+
hash(object: any, algorithm?: string): string;
|
|
119
|
+
wrap<T>(function_: (...arguments_: any[]) => T, options?: {
|
|
120
|
+
ttl?: number;
|
|
121
|
+
key?: string;
|
|
122
|
+
}): (...arguments_: any[]) => T;
|
|
117
123
|
private isPrimitive;
|
|
118
124
|
private concatStores;
|
|
119
125
|
private setTtl;
|
|
@@ -142,6 +148,20 @@ declare class KeyvCacheableMemory implements KeyvStoreAdapter {
|
|
|
142
148
|
declare const shorthandToMilliseconds: (shorthand?: string | number) => number | undefined;
|
|
143
149
|
declare const shorthandToTime: (shorthand?: string | number, fromDate?: Date) => number;
|
|
144
150
|
|
|
151
|
+
type WrapOptions = {
|
|
152
|
+
ttl?: number | string;
|
|
153
|
+
key?: string;
|
|
154
|
+
cache: Cacheable;
|
|
155
|
+
};
|
|
156
|
+
type WrapSyncOptions = {
|
|
157
|
+
ttl?: number | string;
|
|
158
|
+
key?: string;
|
|
159
|
+
cache: CacheableMemory;
|
|
160
|
+
};
|
|
161
|
+
type AnyFunction = (...arguments_: any[]) => any;
|
|
162
|
+
declare function wrapSync<T>(function_: AnyFunction, options: WrapSyncOptions): AnyFunction;
|
|
163
|
+
declare function wrap<T>(function_: AnyFunction, options: WrapOptions): AnyFunction;
|
|
164
|
+
|
|
145
165
|
declare enum CacheableHooks {
|
|
146
166
|
BEFORE_SET = "BEFORE_SET",
|
|
147
167
|
AFTER_SET = "AFTER_SET",
|
|
@@ -182,7 +202,7 @@ declare class Cacheable extends Hookified {
|
|
|
182
202
|
setSecondary(secondary: Keyv | KeyvStoreAdapter): void;
|
|
183
203
|
get<T>(key: string): Promise<T | undefined>;
|
|
184
204
|
getMany<T>(keys: string[]): Promise<Array<T | undefined>>;
|
|
185
|
-
set<T>(key: string, value: T, ttl?: number): Promise<boolean>;
|
|
205
|
+
set<T>(key: string, value: T, ttl?: number | string): Promise<boolean>;
|
|
186
206
|
setMany(items: CacheableItem[]): Promise<boolean>;
|
|
187
207
|
take<T>(key: string): Promise<T | undefined>;
|
|
188
208
|
takeMany<T>(keys: string[]): Promise<Array<T | undefined>>;
|
|
@@ -192,10 +212,15 @@ declare class Cacheable extends Hookified {
|
|
|
192
212
|
deleteMany(keys: string[]): Promise<boolean>;
|
|
193
213
|
clear(): Promise<void>;
|
|
194
214
|
disconnect(): Promise<void>;
|
|
215
|
+
wrap<T>(function_: (...arguments_: any[]) => T, options?: {
|
|
216
|
+
ttl?: number;
|
|
217
|
+
key?: string;
|
|
218
|
+
}): (...arguments_: any[]) => T;
|
|
219
|
+
hash(object: any, algorithm?: string): string;
|
|
195
220
|
private deleteManyKeyv;
|
|
196
221
|
private setManyKeyv;
|
|
197
222
|
private hasManyKeyv;
|
|
198
223
|
private setTtl;
|
|
199
224
|
}
|
|
200
225
|
|
|
201
|
-
export { Cacheable, CacheableEvents, CacheableHooks, type CacheableItem, CacheableMemory, type CacheableOptions, CacheableStats, KeyvCacheableMemory, shorthandToMilliseconds, shorthandToTime };
|
|
226
|
+
export { Cacheable, CacheableEvents, CacheableHooks, type CacheableItem, CacheableMemory, type CacheableOptions, CacheableStats, KeyvCacheableMemory, type WrapOptions, type WrapSyncOptions, shorthandToMilliseconds, shorthandToTime, wrap, wrapSync };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { KeyvStoreAdapter, StoredData, Keyv } from 'keyv';
|
|
2
|
+
export { Keyv, KeyvHooks, KeyvOptions, KeyvStoreAdapter } from 'keyv';
|
|
2
3
|
import { Hookified } from 'hookified';
|
|
3
4
|
|
|
4
5
|
type CacheableOptions$1 = {
|
|
@@ -93,8 +94,8 @@ declare class CacheableMemory {
|
|
|
93
94
|
get size(): number;
|
|
94
95
|
get keys(): IterableIterator<string>;
|
|
95
96
|
get items(): IterableIterator<CacheableStoreItem>;
|
|
96
|
-
get<T>(key: string):
|
|
97
|
-
getMany<T>(keys: string[]):
|
|
97
|
+
get<T>(key: string): T | undefined;
|
|
98
|
+
getMany<T>(keys: string[]): T[];
|
|
98
99
|
getRaw(key: string): CacheableStoreItem | undefined;
|
|
99
100
|
getManyRaw(keys: string[]): Array<CacheableStoreItem | undefined>;
|
|
100
101
|
set(key: string, value: any, ttl?: number | string): void;
|
|
@@ -114,6 +115,11 @@ declare class CacheableMemory {
|
|
|
114
115
|
checkExpiration(): void;
|
|
115
116
|
startIntervalCheck(): void;
|
|
116
117
|
stopIntervalCheck(): void;
|
|
118
|
+
hash(object: any, algorithm?: string): string;
|
|
119
|
+
wrap<T>(function_: (...arguments_: any[]) => T, options?: {
|
|
120
|
+
ttl?: number;
|
|
121
|
+
key?: string;
|
|
122
|
+
}): (...arguments_: any[]) => T;
|
|
117
123
|
private isPrimitive;
|
|
118
124
|
private concatStores;
|
|
119
125
|
private setTtl;
|
|
@@ -142,6 +148,20 @@ declare class KeyvCacheableMemory implements KeyvStoreAdapter {
|
|
|
142
148
|
declare const shorthandToMilliseconds: (shorthand?: string | number) => number | undefined;
|
|
143
149
|
declare const shorthandToTime: (shorthand?: string | number, fromDate?: Date) => number;
|
|
144
150
|
|
|
151
|
+
type WrapOptions = {
|
|
152
|
+
ttl?: number | string;
|
|
153
|
+
key?: string;
|
|
154
|
+
cache: Cacheable;
|
|
155
|
+
};
|
|
156
|
+
type WrapSyncOptions = {
|
|
157
|
+
ttl?: number | string;
|
|
158
|
+
key?: string;
|
|
159
|
+
cache: CacheableMemory;
|
|
160
|
+
};
|
|
161
|
+
type AnyFunction = (...arguments_: any[]) => any;
|
|
162
|
+
declare function wrapSync<T>(function_: AnyFunction, options: WrapSyncOptions): AnyFunction;
|
|
163
|
+
declare function wrap<T>(function_: AnyFunction, options: WrapOptions): AnyFunction;
|
|
164
|
+
|
|
145
165
|
declare enum CacheableHooks {
|
|
146
166
|
BEFORE_SET = "BEFORE_SET",
|
|
147
167
|
AFTER_SET = "AFTER_SET",
|
|
@@ -182,7 +202,7 @@ declare class Cacheable extends Hookified {
|
|
|
182
202
|
setSecondary(secondary: Keyv | KeyvStoreAdapter): void;
|
|
183
203
|
get<T>(key: string): Promise<T | undefined>;
|
|
184
204
|
getMany<T>(keys: string[]): Promise<Array<T | undefined>>;
|
|
185
|
-
set<T>(key: string, value: T, ttl?: number): Promise<boolean>;
|
|
205
|
+
set<T>(key: string, value: T, ttl?: number | string): Promise<boolean>;
|
|
186
206
|
setMany(items: CacheableItem[]): Promise<boolean>;
|
|
187
207
|
take<T>(key: string): Promise<T | undefined>;
|
|
188
208
|
takeMany<T>(keys: string[]): Promise<Array<T | undefined>>;
|
|
@@ -192,10 +212,15 @@ declare class Cacheable extends Hookified {
|
|
|
192
212
|
deleteMany(keys: string[]): Promise<boolean>;
|
|
193
213
|
clear(): Promise<void>;
|
|
194
214
|
disconnect(): Promise<void>;
|
|
215
|
+
wrap<T>(function_: (...arguments_: any[]) => T, options?: {
|
|
216
|
+
ttl?: number;
|
|
217
|
+
key?: string;
|
|
218
|
+
}): (...arguments_: any[]) => T;
|
|
219
|
+
hash(object: any, algorithm?: string): string;
|
|
195
220
|
private deleteManyKeyv;
|
|
196
221
|
private setManyKeyv;
|
|
197
222
|
private hasManyKeyv;
|
|
198
223
|
private setTtl;
|
|
199
224
|
}
|
|
200
225
|
|
|
201
|
-
export { Cacheable, CacheableEvents, CacheableHooks, type CacheableItem, CacheableMemory, type CacheableOptions, CacheableStats, KeyvCacheableMemory, shorthandToMilliseconds, shorthandToTime };
|
|
226
|
+
export { Cacheable, CacheableEvents, CacheableHooks, type CacheableItem, CacheableMemory, type CacheableOptions, CacheableStats, KeyvCacheableMemory, type WrapOptions, type WrapSyncOptions, shorthandToMilliseconds, shorthandToTime, wrap, wrapSync };
|
package/dist/index.js
CHANGED
|
@@ -69,6 +69,32 @@ var shorthandToTime = (shorthand, fromDate) => {
|
|
|
69
69
|
return fromDate.getTime() + milliseconds;
|
|
70
70
|
};
|
|
71
71
|
|
|
72
|
+
// src/wrap.ts
|
|
73
|
+
function wrapSync(function_, options) {
|
|
74
|
+
const { ttl, key, cache } = options;
|
|
75
|
+
return function(...arguments_) {
|
|
76
|
+
const cacheKey = key ?? cache.hash(arguments_);
|
|
77
|
+
let value = cache.get(cacheKey);
|
|
78
|
+
if (value === void 0) {
|
|
79
|
+
value = function_(...arguments_);
|
|
80
|
+
cache.set(cacheKey, value, ttl);
|
|
81
|
+
}
|
|
82
|
+
return value;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function wrap(function_, options) {
|
|
86
|
+
const { ttl, key, cache } = options;
|
|
87
|
+
return async function(...arguments_) {
|
|
88
|
+
const cacheKey = key ?? cache.hash(arguments_);
|
|
89
|
+
let value = await cache.get(cacheKey);
|
|
90
|
+
if (value === void 0) {
|
|
91
|
+
value = await function_(...arguments_);
|
|
92
|
+
await cache.set(cacheKey, value, ttl);
|
|
93
|
+
}
|
|
94
|
+
return value;
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
72
98
|
// src/memory-lru.ts
|
|
73
99
|
var ListNode = class {
|
|
74
100
|
// eslint-disable-next-line @typescript-eslint/parameter-properties
|
|
@@ -142,6 +168,18 @@ var DoublyLinkedList = class {
|
|
|
142
168
|
}
|
|
143
169
|
};
|
|
144
170
|
|
|
171
|
+
// src/hash.ts
|
|
172
|
+
import * as crypto from "node:crypto";
|
|
173
|
+
function hash(object, algorithm = "sha256") {
|
|
174
|
+
const objectString = JSON.stringify(object);
|
|
175
|
+
if (!crypto.getHashes().includes(algorithm)) {
|
|
176
|
+
throw new Error(`Unsupported hash algorithm: '${algorithm}'`);
|
|
177
|
+
}
|
|
178
|
+
const hasher = crypto.createHash(algorithm);
|
|
179
|
+
hasher.update(objectString);
|
|
180
|
+
return hasher.digest("hex");
|
|
181
|
+
}
|
|
182
|
+
|
|
145
183
|
// src/memory.ts
|
|
146
184
|
var CacheableMemory = class {
|
|
147
185
|
_hashCache = /* @__PURE__ */ new Map();
|
|
@@ -339,12 +377,12 @@ var CacheableMemory = class {
|
|
|
339
377
|
if (cacheHashNumber) {
|
|
340
378
|
return cacheHashNumber;
|
|
341
379
|
}
|
|
342
|
-
let
|
|
380
|
+
let hash2 = 0;
|
|
343
381
|
const primeMultiplier = 31;
|
|
344
382
|
for (let i = 0; i < key.length; i++) {
|
|
345
|
-
|
|
383
|
+
hash2 = hash2 * primeMultiplier + key.charCodeAt(i);
|
|
346
384
|
}
|
|
347
|
-
const result = Math.abs(
|
|
385
|
+
const result = Math.abs(hash2) % 10;
|
|
348
386
|
this._hashCache.set(key, result);
|
|
349
387
|
return result;
|
|
350
388
|
}
|
|
@@ -435,6 +473,17 @@ var CacheableMemory = class {
|
|
|
435
473
|
this._interval = 0;
|
|
436
474
|
this._checkInterval = 0;
|
|
437
475
|
}
|
|
476
|
+
hash(object, algorithm = "sha256") {
|
|
477
|
+
return hash(object, algorithm);
|
|
478
|
+
}
|
|
479
|
+
wrap(function_, options = {}) {
|
|
480
|
+
const wrapOptions = {
|
|
481
|
+
ttl: options.ttl,
|
|
482
|
+
key: options.key,
|
|
483
|
+
cache: this
|
|
484
|
+
};
|
|
485
|
+
return wrapSync(function_, wrapOptions);
|
|
486
|
+
}
|
|
438
487
|
isPrimitive(value) {
|
|
439
488
|
const result = false;
|
|
440
489
|
if (value === null || value === void 0) {
|
|
@@ -688,6 +737,10 @@ var CacheableStats = class {
|
|
|
688
737
|
};
|
|
689
738
|
|
|
690
739
|
// src/index.ts
|
|
740
|
+
import {
|
|
741
|
+
KeyvHooks,
|
|
742
|
+
Keyv as Keyv2
|
|
743
|
+
} from "keyv";
|
|
691
744
|
var CacheableHooks = /* @__PURE__ */ ((CacheableHooks2) => {
|
|
692
745
|
CacheableHooks2["BEFORE_SET"] = "BEFORE_SET";
|
|
693
746
|
CacheableHooks2["AFTER_SET"] = "AFTER_SET";
|
|
@@ -983,6 +1036,17 @@ var Cacheable = class extends Hookified {
|
|
|
983
1036
|
}
|
|
984
1037
|
await (this._nonBlocking ? Promise.race(promises) : Promise.all(promises));
|
|
985
1038
|
}
|
|
1039
|
+
wrap(function_, options = {}) {
|
|
1040
|
+
const wrapOptions = {
|
|
1041
|
+
ttl: options.ttl,
|
|
1042
|
+
key: options.key,
|
|
1043
|
+
cache: this
|
|
1044
|
+
};
|
|
1045
|
+
return wrap(function_, wrapOptions);
|
|
1046
|
+
}
|
|
1047
|
+
hash(object, algorithm = "sha256") {
|
|
1048
|
+
return hash(object, algorithm);
|
|
1049
|
+
}
|
|
986
1050
|
async deleteManyKeyv(keyv, keys) {
|
|
987
1051
|
const promises = [];
|
|
988
1052
|
for (const key of keys) {
|
|
@@ -1023,7 +1087,11 @@ export {
|
|
|
1023
1087
|
CacheableHooks,
|
|
1024
1088
|
CacheableMemory,
|
|
1025
1089
|
CacheableStats,
|
|
1090
|
+
Keyv2 as Keyv,
|
|
1026
1091
|
KeyvCacheableMemory,
|
|
1092
|
+
KeyvHooks,
|
|
1027
1093
|
shorthandToMilliseconds,
|
|
1028
|
-
shorthandToTime
|
|
1094
|
+
shorthandToTime,
|
|
1095
|
+
wrap,
|
|
1096
|
+
wrapSync
|
|
1029
1097
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cacheable",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Simple Caching Engine using Keyv",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"private": false,
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@keyv/redis": "^3.0.1",
|
|
21
|
-
"@types/node": "^22.
|
|
21
|
+
"@types/node": "^22.7.4",
|
|
22
22
|
"@vitest/coverage-v8": "^2.1.1",
|
|
23
23
|
"lru-cache": "^11.0.1",
|
|
24
24
|
"rimraf": "^6.0.1",
|