inray 0.0.2 → 0.0.4
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/LICENSE.md +1 -0
- package/README.md +220 -36
- package/dist/async/abortable.d.ts +2 -2
- package/dist/async/abortable.d.ts.map +1 -1
- package/dist/async/abortable.js.map +1 -1
- package/dist/caching/mod.d.ts +2 -0
- package/dist/caching/mod.d.ts.map +1 -0
- package/dist/caching/mod.js +2 -0
- package/dist/caching/mod.js.map +1 -0
- package/dist/caching/src/cache.d.ts +89 -0
- package/dist/caching/src/cache.d.ts.map +1 -0
- package/dist/caching/src/cache.js +309 -0
- package/dist/caching/src/cache.js.map +1 -0
- package/dist/caching/src/hashing/cache.d.ts +92 -0
- package/dist/caching/src/hashing/cache.d.ts.map +1 -0
- package/dist/caching/src/hashing/cache.js +119 -0
- package/dist/caching/src/hashing/cache.js.map +1 -0
- package/dist/caching/src/hashing/hooks/eventified.d.ts +157 -0
- package/dist/caching/src/hashing/hooks/eventified.d.ts.map +1 -0
- package/dist/caching/src/hashing/hooks/eventified.js +333 -0
- package/dist/caching/src/hashing/hooks/eventified.js.map +1 -0
- package/dist/caching/src/hashing/hooks/index.d.ts +199 -0
- package/dist/caching/src/hashing/hooks/index.d.ts.map +1 -0
- package/dist/caching/src/hashing/hooks/index.js +383 -0
- package/dist/caching/src/hashing/hooks/index.js.map +1 -0
- package/dist/caching/src/hashing/hooks/types.d.ts +217 -0
- package/dist/caching/src/hashing/hooks/types.d.ts.map +1 -0
- package/dist/caching/src/hashing/hooks/types.js +10 -0
- package/dist/caching/src/hashing/hooks/types.js.map +1 -0
- package/dist/caching/src/hashing/index.d.ts +236 -0
- package/dist/caching/src/hashing/index.d.ts.map +1 -0
- package/dist/caching/src/hashing/index.js +447 -0
- package/dist/caching/src/hashing/index.js.map +1 -0
- package/dist/caching/src/hashing/providers/crc.d.ts +15 -0
- package/dist/caching/src/hashing/providers/crc.d.ts.map +1 -0
- package/dist/caching/src/hashing/providers/crc.js +49 -0
- package/dist/caching/src/hashing/providers/crc.js.map +1 -0
- package/dist/caching/src/hashing/providers/crypto.d.ts +19 -0
- package/dist/caching/src/hashing/providers/crypto.d.ts.map +1 -0
- package/dist/caching/src/hashing/providers/crypto.js +28 -0
- package/dist/caching/src/hashing/providers/crypto.js.map +1 -0
- package/dist/caching/src/hashing/providers/djb2.d.ts +60 -0
- package/dist/caching/src/hashing/providers/djb2.d.ts.map +1 -0
- package/dist/caching/src/hashing/providers/djb2.js +92 -0
- package/dist/caching/src/hashing/providers/djb2.js.map +1 -0
- package/dist/caching/src/hashing/providers/fnv1.d.ts +33 -0
- package/dist/caching/src/hashing/providers/fnv1.d.ts.map +1 -0
- package/dist/caching/src/hashing/providers/fnv1.js +68 -0
- package/dist/caching/src/hashing/providers/fnv1.js.map +1 -0
- package/dist/caching/src/hashing/providers/murmur.d.ts +81 -0
- package/dist/caching/src/hashing/providers/murmur.d.ts.map +1 -0
- package/dist/caching/src/hashing/providers/murmur.js +173 -0
- package/dist/caching/src/hashing/providers/murmur.js.map +1 -0
- package/dist/caching/src/hashing/providers.d.ts +126 -0
- package/dist/caching/src/hashing/providers.d.ts.map +1 -0
- package/dist/caching/src/hashing/providers.js +163 -0
- package/dist/caching/src/hashing/providers.js.map +1 -0
- package/dist/caching/src/hashing/types.d.ts +340 -0
- package/dist/caching/src/hashing/types.d.ts.map +1 -0
- package/dist/caching/src/hashing/types.js +10 -0
- package/dist/caching/src/hashing/types.js.map +1 -0
- package/dist/caching/src/keyValue/capabilities.d.ts +161 -0
- package/dist/caching/src/keyValue/capabilities.d.ts.map +1 -0
- package/dist/caching/src/keyValue/capabilities.js +334 -0
- package/dist/caching/src/keyValue/capabilities.js.map +1 -0
- package/dist/caching/src/keyValue/event-manager.d.ts +27 -0
- package/dist/caching/src/keyValue/event-manager.d.ts.map +1 -0
- package/dist/caching/src/keyValue/event-manager.js +88 -0
- package/dist/caching/src/keyValue/event-manager.js.map +1 -0
- package/dist/caching/src/keyValue/generic-store.d.ts +243 -0
- package/dist/caching/src/keyValue/generic-store.d.ts.map +1 -0
- package/dist/caching/src/keyValue/generic-store.js +295 -0
- package/dist/caching/src/keyValue/generic-store.js.map +1 -0
- package/dist/caching/src/keyValue/hooks-manager.d.ts +21 -0
- package/dist/caching/src/keyValue/hooks-manager.d.ts.map +1 -0
- package/dist/caching/src/keyValue/hooks-manager.js +59 -0
- package/dist/caching/src/keyValue/hooks-manager.js.map +1 -0
- package/dist/caching/src/keyValue/index.d.ts +334 -0
- package/dist/caching/src/keyValue/index.d.ts.map +1 -0
- package/dist/caching/src/keyValue/index.js +796 -0
- package/dist/caching/src/keyValue/index.js.map +1 -0
- package/dist/caching/src/keyValue/serialize/serialize.d.ts +12 -0
- package/dist/caching/src/keyValue/serialize/serialize.d.ts.map +1 -0
- package/dist/caching/src/keyValue/serialize/serialize.js +64 -0
- package/dist/caching/src/keyValue/serialize/serialize.js.map +1 -0
- package/dist/caching/src/keyValue/stats-manager.d.ts +27 -0
- package/dist/caching/src/keyValue/stats-manager.d.ts.map +1 -0
- package/dist/caching/src/keyValue/stats-manager.js +64 -0
- package/dist/caching/src/keyValue/stats-manager.js.map +1 -0
- package/dist/caching/src/keyValue/types.d.ts +22 -0
- package/dist/caching/src/keyValue/types.d.ts.map +1 -0
- package/dist/caching/src/keyValue/types.js +11 -0
- package/dist/caching/src/keyValue/types.js.map +1 -0
- package/dist/caching/src/keyv-adapter.d.ts +40 -0
- package/dist/caching/src/keyv-adapter.d.ts.map +1 -0
- package/dist/caching/src/keyv-adapter.js +56 -0
- package/dist/caching/src/keyv-adapter.js.map +1 -0
- package/dist/caching/src/utils/cache-tags.d.ts +275 -0
- package/dist/caching/src/utils/cache-tags.d.ts.map +1 -0
- package/dist/caching/src/utils/cache-tags.js +407 -0
- package/dist/caching/src/utils/cache-tags.js.map +1 -0
- package/dist/caching/src/utils/cacheable-item-types.d.ts +35 -0
- package/dist/caching/src/utils/cacheable-item-types.d.ts.map +1 -0
- package/dist/caching/src/utils/cacheable-item-types.js +10 -0
- package/dist/caching/src/utils/cacheable-item-types.js.map +1 -0
- package/dist/caching/src/utils/coalesce-async.d.ts +29 -0
- package/dist/caching/src/utils/coalesce-async.d.ts.map +1 -0
- package/dist/caching/src/utils/coalesce-async.js +88 -0
- package/dist/caching/src/utils/coalesce-async.js.map +1 -0
- package/dist/caching/src/utils/hash.d.ts +55 -0
- package/dist/caching/src/utils/hash.d.ts.map +1 -0
- package/dist/caching/src/utils/hash.js +116 -0
- package/dist/caching/src/utils/hash.js.map +1 -0
- package/dist/caching/src/utils/index.d.ts +24 -0
- package/dist/caching/src/utils/index.d.ts.map +1 -0
- package/dist/caching/src/utils/index.js +21 -0
- package/dist/caching/src/utils/index.js.map +1 -0
- package/dist/caching/src/utils/is-keyv-instance.d.ts +10 -0
- package/dist/caching/src/utils/is-keyv-instance.d.ts.map +1 -0
- package/dist/caching/src/utils/is-keyv-instance.js +37 -0
- package/dist/caching/src/utils/is-keyv-instance.js.map +1 -0
- package/dist/caching/src/utils/is-object.d.ts +10 -0
- package/dist/caching/src/utils/is-object.d.ts.map +1 -0
- package/dist/caching/src/utils/is-object.js +13 -0
- package/dist/caching/src/utils/is-object.js.map +1 -0
- package/dist/caching/src/utils/less-than.d.ts +10 -0
- package/dist/caching/src/utils/less-than.d.ts.map +1 -0
- package/dist/caching/src/utils/less-than.js +13 -0
- package/dist/caching/src/utils/less-than.js.map +1 -0
- package/dist/caching/src/utils/memoize.d.ts +107 -0
- package/dist/caching/src/utils/memoize.d.ts.map +1 -0
- package/dist/caching/src/utils/memoize.js +201 -0
- package/dist/caching/src/utils/memoize.js.map +1 -0
- package/dist/caching/src/utils/mock-cacheable.d.ts +28 -0
- package/dist/caching/src/utils/mock-cacheable.d.ts.map +1 -0
- package/dist/caching/src/utils/mock-cacheable.js +87 -0
- package/dist/caching/src/utils/mock-cacheable.js.map +1 -0
- package/dist/caching/src/utils/run-if-fn.d.ts +12 -0
- package/dist/caching/src/utils/run-if-fn.d.ts.map +1 -0
- package/dist/caching/src/utils/run-if-fn.js +12 -0
- package/dist/caching/src/utils/run-if-fn.js.map +1 -0
- package/dist/caching/src/utils/shorthand-time.d.ts +27 -0
- package/dist/caching/src/utils/shorthand-time.d.ts.map +1 -0
- package/dist/caching/src/utils/shorthand-time.js +96 -0
- package/dist/caching/src/utils/shorthand-time.js.map +1 -0
- package/dist/caching/src/utils/sleep.d.ts +10 -0
- package/dist/caching/src/utils/sleep.d.ts.map +1 -0
- package/dist/caching/src/utils/sleep.js +11 -0
- package/dist/caching/src/utils/sleep.js.map +1 -0
- package/dist/caching/src/utils/stats.d.ts +354 -0
- package/dist/caching/src/utils/stats.d.ts.map +1 -0
- package/dist/caching/src/utils/stats.js +593 -0
- package/dist/caching/src/utils/stats.js.map +1 -0
- package/dist/caching/src/utils/ttl.d.ts +58 -0
- package/dist/caching/src/utils/ttl.d.ts.map +1 -0
- package/dist/caching/src/utils/ttl.js +77 -0
- package/dist/caching/src/utils/ttl.js.map +1 -0
- package/dist/logtape/logtape/level.d.ts +1 -2
- package/dist/logtape/logtape/level.d.ts.map +1 -1
- package/dist/logtape/logtape/level.js +1 -1
- package/dist/logtape/logtape/level.js.map +1 -1
- package/dist/logtape/logtape/mod.d.ts +1 -1
- package/dist/logtape/logtape/mod.d.ts.map +1 -1
- package/dist/logtape/logtape/mod.js +1 -1
- package/dist/logtape/logtape/mod.js.map +1 -1
- package/dist/utils/mod.d.ts +1 -1
- package/dist/utils/mod.d.ts.map +1 -1
- package/dist/utils/mod.js.map +1 -1
- package/dist/utils/validation/inRangeOfMaxInt32.d.ts +2 -0
- package/dist/utils/validation/inRangeOfMaxInt32.d.ts.map +1 -0
- package/dist/utils/validation/inRangeOfMaxInt32.js +4 -0
- package/dist/utils/validation/inRangeOfMaxInt32.js.map +1 -0
- package/dist/utils/validation/isEmail.d.ts +2 -0
- package/dist/utils/validation/isEmail.d.ts.map +1 -0
- package/dist/utils/validation/isEmail.js +7 -0
- package/dist/utils/validation/isEmail.js.map +1 -0
- package/dist/utils/validation/isEmptyObject.d.ts +9 -0
- package/dist/utils/validation/isEmptyObject.d.ts.map +1 -0
- package/dist/utils/validation/isEmptyObject.js +16 -0
- package/dist/utils/validation/isEmptyObject.js.map +1 -0
- package/dist/utils/validation/isNotEmptyString.d.ts +7 -0
- package/dist/utils/validation/isNotEmptyString.d.ts.map +1 -0
- package/dist/utils/validation/isNotEmptyString.js +17 -0
- package/dist/utils/validation/isNotEmptyString.js.map +1 -0
- package/dist/utils/validation/isPositiveInteger.d.ts +2 -0
- package/dist/utils/validation/isPositiveInteger.d.ts.map +1 -0
- package/dist/utils/validation/isPositiveInteger.js +7 -0
- package/dist/utils/validation/isPositiveInteger.js.map +1 -0
- package/dist/utils/validation/isUuid.d.ts +2 -0
- package/dist/utils/validation/isUuid.d.ts.map +1 -0
- package/dist/utils/validation/isUuid.js +7 -0
- package/dist/utils/validation/isUuid.js.map +1 -0
- package/dist/utils/validation/isUuidArray.d.ts +2 -0
- package/dist/utils/validation/isUuidArray.d.ts.map +1 -0
- package/dist/utils/validation/isUuidArray.js +7 -0
- package/dist/utils/validation/isUuidArray.js.map +1 -0
- package/dist/utils/validation/isValidFileName.d.ts +2 -0
- package/dist/utils/validation/isValidFileName.d.ts.map +1 -0
- package/dist/utils/validation/isValidFileName.js +33 -0
- package/dist/utils/validation/isValidFileName.js.map +1 -0
- package/dist/utils/validation/isValidUrlLike.d.ts +6 -0
- package/dist/utils/validation/isValidUrlLike.d.ts.map +1 -0
- package/dist/utils/validation/isValidUrlLike.js +8 -0
- package/dist/utils/validation/isValidUrlLike.js.map +1 -0
- package/dist/utils/validation/mod.d.ts +21 -0
- package/dist/utils/validation/mod.d.ts.map +1 -0
- package/dist/utils/validation/mod.js +21 -0
- package/dist/utils/validation/mod.js.map +1 -0
- package/dist/utils/validation/vEnvBoolean.d.ts +3 -0
- package/dist/utils/validation/vEnvBoolean.d.ts.map +1 -0
- package/dist/utils/validation/vEnvBoolean.js +5 -0
- package/dist/utils/validation/vEnvBoolean.js.map +1 -0
- package/dist/utils/validation/vEnvBooleanOrUndefined.d.ts +3 -0
- package/dist/utils/validation/vEnvBooleanOrUndefined.d.ts.map +1 -0
- package/dist/utils/validation/vEnvBooleanOrUndefined.js +5 -0
- package/dist/utils/validation/vEnvBooleanOrUndefined.js.map +1 -0
- package/dist/utils/validation/vEnvLogLevel.d.ts +4 -0
- package/dist/utils/validation/vEnvLogLevel.d.ts.map +1 -0
- package/dist/utils/validation/vEnvLogLevel.js +6 -0
- package/dist/utils/validation/vEnvLogLevel.js.map +1 -0
- package/dist/utils/validation/vFileName.d.ts +4 -0
- package/dist/utils/validation/vFileName.d.ts.map +1 -0
- package/dist/utils/validation/vFileName.js +21 -0
- package/dist/utils/validation/vFileName.js.map +1 -0
- package/dist/utils/validation/vISO8601DateTime.d.ts +5 -0
- package/dist/utils/validation/vISO8601DateTime.d.ts.map +1 -0
- package/dist/utils/validation/vISO8601DateTime.js +37 -0
- package/dist/utils/validation/vISO8601DateTime.js.map +1 -0
- package/dist/utils/validation/vLatinInput.d.ts +3 -0
- package/dist/utils/validation/vLatinInput.d.ts.map +1 -0
- package/dist/utils/validation/vLatinInput.js +3 -0
- package/dist/utils/validation/vLatinInput.js.map +1 -0
- package/dist/utils/validation/vOmniBoolean.d.ts +3 -0
- package/dist/utils/validation/vOmniBoolean.d.ts.map +1 -0
- package/dist/utils/validation/vOmniBoolean.js +10 -0
- package/dist/utils/validation/vOmniBoolean.js.map +1 -0
- package/dist/utils/validation/vQueryBoolean.d.ts +3 -0
- package/dist/utils/validation/vQueryBoolean.d.ts.map +1 -0
- package/dist/utils/validation/vQueryBoolean.js +7 -0
- package/dist/utils/validation/vQueryBoolean.js.map +1 -0
- package/dist/utils/validation/vQueryEmailArray.d.ts +9 -0
- package/dist/utils/validation/vQueryEmailArray.d.ts.map +1 -0
- package/dist/utils/validation/vQueryEmailArray.js +29 -0
- package/dist/utils/validation/vQueryEmailArray.js.map +1 -0
- package/dist/utils/validation/vQueryNumberArray.d.ts +10 -0
- package/dist/utils/validation/vQueryNumberArray.d.ts.map +1 -0
- package/dist/utils/validation/vQueryNumberArray.js +32 -0
- package/dist/utils/validation/vQueryNumberArray.js.map +1 -0
- package/dist/utils/validation/vQueryStringifiedEnumArray.d.ts +3 -0
- package/dist/utils/validation/vQueryStringifiedEnumArray.d.ts.map +1 -0
- package/dist/utils/validation/vQueryStringifiedEnumArray.js +25 -0
- package/dist/utils/validation/vQueryStringifiedEnumArray.js.map +1 -0
- package/dist/utils/validation/vQueryUuidArray.d.ts +9 -0
- package/dist/utils/validation/vQueryUuidArray.d.ts.map +1 -0
- package/dist/utils/validation/vQueryUuidArray.js +27 -0
- package/dist/utils/validation/vQueryUuidArray.js.map +1 -0
- package/package.json +19 -3
|
@@ -0,0 +1,796 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Original library: keyv (v5.6.0)
|
|
3
|
+
* - Copyright (c) 2017-2021 Luke Childs
|
|
4
|
+
* - Copyright (c) 2021-2022 Jared Wray
|
|
5
|
+
*
|
|
6
|
+
* Modified and integrated in "Inray":
|
|
7
|
+
* - Evgeniy Bushin
|
|
8
|
+
*/
|
|
9
|
+
/***/
|
|
10
|
+
import { defaultDeserialize, defaultSerialize } from "./serialize/serialize.js";
|
|
11
|
+
import EventManager from './event-manager.js';
|
|
12
|
+
import HooksManager from './hooks-manager.js';
|
|
13
|
+
import StatsManager from './stats-manager.js';
|
|
14
|
+
const iterableAdapters = ['sqlite', 'postgres', 'mysql', 'mongo', 'redis', 'valkey', 'etcd'];
|
|
15
|
+
export class Keyv extends EventManager {
|
|
16
|
+
opts;
|
|
17
|
+
iterator;
|
|
18
|
+
hooks = new HooksManager();
|
|
19
|
+
stats = new StatsManager(false);
|
|
20
|
+
/**
|
|
21
|
+
* Time to live in milliseconds
|
|
22
|
+
*/
|
|
23
|
+
_ttl;
|
|
24
|
+
/**
|
|
25
|
+
* Namespace
|
|
26
|
+
*/
|
|
27
|
+
_namespace;
|
|
28
|
+
/**
|
|
29
|
+
* Store
|
|
30
|
+
*/
|
|
31
|
+
_store = new Map();
|
|
32
|
+
_serialize = defaultSerialize;
|
|
33
|
+
_deserialize = defaultDeserialize;
|
|
34
|
+
_compression;
|
|
35
|
+
_useKeyPrefix = true;
|
|
36
|
+
_throwOnErrors = false;
|
|
37
|
+
/**
|
|
38
|
+
* Keyv Constructor
|
|
39
|
+
* @param {KeyvStoreAdapter | KeyvOptions} store
|
|
40
|
+
* @param {Omit<KeyvOptions, 'store'>} [options] if you provide the store you can then provide the Keyv Options
|
|
41
|
+
*/
|
|
42
|
+
constructor(store, options) {
|
|
43
|
+
super();
|
|
44
|
+
options ??= {};
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
46
|
+
store ??= {};
|
|
47
|
+
this.opts = {
|
|
48
|
+
namespace: 'keyv',
|
|
49
|
+
serialize: defaultSerialize,
|
|
50
|
+
deserialize: defaultDeserialize,
|
|
51
|
+
emitErrors: true,
|
|
52
|
+
// @ts-expect-error - Map is not a KeyvStoreAdapter
|
|
53
|
+
store: new Map(),
|
|
54
|
+
...options
|
|
55
|
+
};
|
|
56
|
+
if (store && store.get) {
|
|
57
|
+
this.opts.store = store;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
this.opts = {
|
|
61
|
+
...this.opts,
|
|
62
|
+
...store
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
this._store = this.opts.store ?? new Map();
|
|
66
|
+
this._compression = this.opts.compression;
|
|
67
|
+
// biome-ignore lint/style/noNonNullAssertion: need to fix
|
|
68
|
+
this._serialize = this.opts.serialize;
|
|
69
|
+
// biome-ignore lint/style/noNonNullAssertion: need to fix
|
|
70
|
+
this._deserialize = this.opts.deserialize;
|
|
71
|
+
/* v8 ignore next -- @preserve */
|
|
72
|
+
if (this.opts.namespace) {
|
|
73
|
+
this._namespace = this.opts.namespace;
|
|
74
|
+
}
|
|
75
|
+
/* v8 ignore next -- @preserve */
|
|
76
|
+
if (this._store) {
|
|
77
|
+
if (!this._isValidStorageAdapter(this._store)) {
|
|
78
|
+
throw new Error('Invalid storage adapter');
|
|
79
|
+
}
|
|
80
|
+
if (typeof this._store.on === 'function') {
|
|
81
|
+
this._store.on('error', (error) => this.emit('error', error));
|
|
82
|
+
}
|
|
83
|
+
this._store.namespace = this._namespace;
|
|
84
|
+
// Attach iterators
|
|
85
|
+
if (typeof this._store[Symbol.iterator] === 'function' && this._store instanceof Map) {
|
|
86
|
+
this.iterator = this.generateIterator(this._store);
|
|
87
|
+
}
|
|
88
|
+
else if ('iterator' in this._store && this._store.opts && this._checkIterableAdapter()) {
|
|
89
|
+
this.iterator = this.generateIterator(
|
|
90
|
+
// biome-ignore lint/style/noNonNullAssertion: need to fix
|
|
91
|
+
this._store.iterator.bind(this._store));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (this.opts.stats) {
|
|
95
|
+
this.stats.enabled = this.opts.stats;
|
|
96
|
+
}
|
|
97
|
+
if (this.opts.ttl) {
|
|
98
|
+
this._ttl = this.opts.ttl;
|
|
99
|
+
}
|
|
100
|
+
if (this.opts.useKeyPrefix !== undefined) {
|
|
101
|
+
this._useKeyPrefix = this.opts.useKeyPrefix;
|
|
102
|
+
}
|
|
103
|
+
if (this.opts.throwOnErrors !== undefined) {
|
|
104
|
+
this._throwOnErrors = this.opts.throwOnErrors;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get the current store
|
|
109
|
+
*/
|
|
110
|
+
get store() {
|
|
111
|
+
return this._store;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Set the current store. This will also set the namespace, event error handler, and generate the iterator. If the store is not valid it will throw an error.
|
|
115
|
+
* @param {KeyvStoreAdapter | Map<any, any> | any} store the store to set
|
|
116
|
+
*/
|
|
117
|
+
set store(store) {
|
|
118
|
+
if (this._isValidStorageAdapter(store)) {
|
|
119
|
+
this._store = store;
|
|
120
|
+
this.opts.store = store;
|
|
121
|
+
if (typeof store.on === 'function') {
|
|
122
|
+
store.on('error', (error) => this.emit('error', error));
|
|
123
|
+
}
|
|
124
|
+
/* v8 ignore next -- @preserve */
|
|
125
|
+
if (this._namespace) {
|
|
126
|
+
this._store.namespace = this._namespace;
|
|
127
|
+
}
|
|
128
|
+
if (typeof store[Symbol.iterator] === 'function' && store instanceof Map) {
|
|
129
|
+
this.iterator = this.generateIterator(store);
|
|
130
|
+
/* v8 ignore next -- @preserve */
|
|
131
|
+
}
|
|
132
|
+
else if ('iterator' in store && store.opts && this._checkIterableAdapter()) {
|
|
133
|
+
this.iterator = this.generateIterator(store.iterator?.bind(store));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
throw new Error('Invalid storage adapter');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get the current compression function
|
|
142
|
+
* @returns {CompressionAdapter} The current compression function
|
|
143
|
+
*/
|
|
144
|
+
get compression() {
|
|
145
|
+
return this._compression;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Set the current compression function
|
|
149
|
+
* @param {CompressionAdapter} compress The compression function to set
|
|
150
|
+
*/
|
|
151
|
+
set compression(compress) {
|
|
152
|
+
this._compression = compress;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get the current namespace.
|
|
156
|
+
* @returns {string | undefined} The current namespace.
|
|
157
|
+
*/
|
|
158
|
+
get namespace() {
|
|
159
|
+
return this._namespace;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Set the current namespace.
|
|
163
|
+
* @param {string | undefined} namespace The namespace to set.
|
|
164
|
+
*/
|
|
165
|
+
set namespace(namespace) {
|
|
166
|
+
this._namespace = namespace;
|
|
167
|
+
this.opts.namespace = namespace;
|
|
168
|
+
this._store.namespace = namespace;
|
|
169
|
+
/* v8 ignore next -- @preserve */
|
|
170
|
+
if (this.opts.store) {
|
|
171
|
+
this.opts.store.namespace = namespace;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Get the current TTL.
|
|
176
|
+
* @returns {number} The current TTL in milliseconds.
|
|
177
|
+
*/
|
|
178
|
+
get ttl() {
|
|
179
|
+
return this._ttl;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Set the current TTL.
|
|
183
|
+
* @param {number} ttl The TTL to set in milliseconds.
|
|
184
|
+
*/
|
|
185
|
+
set ttl(ttl) {
|
|
186
|
+
this.opts.ttl = ttl;
|
|
187
|
+
this._ttl = ttl;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Get the current serialize function.
|
|
191
|
+
* @returns {Serialize} The current serialize function.
|
|
192
|
+
*/
|
|
193
|
+
get serialize() {
|
|
194
|
+
return this._serialize;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Set the current serialize function.
|
|
198
|
+
* @param {Serialize} serialize The serialize function to set.
|
|
199
|
+
*/
|
|
200
|
+
set serialize(serialize) {
|
|
201
|
+
this.opts.serialize = serialize;
|
|
202
|
+
this._serialize = serialize;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Get the current deserialize function.
|
|
206
|
+
* @returns {Deserialize} The current deserialize function.
|
|
207
|
+
*/
|
|
208
|
+
get deserialize() {
|
|
209
|
+
return this._deserialize;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Set the current deserialize function.
|
|
213
|
+
* @param {Deserialize} deserialize The deserialize function to set.
|
|
214
|
+
*/
|
|
215
|
+
set deserialize(deserialize) {
|
|
216
|
+
this.opts.deserialize = deserialize;
|
|
217
|
+
this._deserialize = deserialize;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get the current useKeyPrefix value. This will enable or disable key prefixing.
|
|
221
|
+
* @returns {boolean} The current useKeyPrefix value.
|
|
222
|
+
* @default true
|
|
223
|
+
*/
|
|
224
|
+
get useKeyPrefix() {
|
|
225
|
+
return this._useKeyPrefix;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Set the current useKeyPrefix value. This will enable or disable key prefixing.
|
|
229
|
+
* @param {boolean} value The useKeyPrefix value to set.
|
|
230
|
+
*/
|
|
231
|
+
set useKeyPrefix(value) {
|
|
232
|
+
this._useKeyPrefix = value;
|
|
233
|
+
this.opts.useKeyPrefix = value;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Get the current throwErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
237
|
+
* @return {boolean} The current throwOnErrors value.
|
|
238
|
+
*/
|
|
239
|
+
get throwOnErrors() {
|
|
240
|
+
return this._throwOnErrors;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Set the current throwOnErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
244
|
+
* @param {boolean} value The throwOnErrors value to set.
|
|
245
|
+
*/
|
|
246
|
+
set throwOnErrors(value) {
|
|
247
|
+
this._throwOnErrors = value;
|
|
248
|
+
this.opts.throwOnErrors = value;
|
|
249
|
+
}
|
|
250
|
+
generateIterator(iterator) {
|
|
251
|
+
const function_ = async function* () {
|
|
252
|
+
for await (const [key, raw] of typeof iterator === 'function' ? iterator(this._store.namespace) : iterator) {
|
|
253
|
+
const data = await this.deserializeData(raw);
|
|
254
|
+
if (this._useKeyPrefix && this._store.namespace && !key.includes(this._store.namespace)) {
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
if (typeof data.expires === 'number' && Date.now() > data.expires) {
|
|
258
|
+
await this.delete(key);
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
yield [this._getKeyUnprefix(key), data.value];
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
return function_.bind(this);
|
|
265
|
+
}
|
|
266
|
+
_checkIterableAdapter() {
|
|
267
|
+
return (iterableAdapters.includes(this._store.opts.dialect) ||
|
|
268
|
+
iterableAdapters.some((element) => this._store.opts.url.includes(element)));
|
|
269
|
+
}
|
|
270
|
+
_getKeyPrefix(key) {
|
|
271
|
+
if (!this._useKeyPrefix) {
|
|
272
|
+
return key;
|
|
273
|
+
}
|
|
274
|
+
if (!this._namespace) {
|
|
275
|
+
return key;
|
|
276
|
+
}
|
|
277
|
+
// If the key is already prefixed, return it
|
|
278
|
+
if (key.startsWith(`${this._namespace}:`)) {
|
|
279
|
+
return key;
|
|
280
|
+
}
|
|
281
|
+
return `${this._namespace}:${key}`;
|
|
282
|
+
}
|
|
283
|
+
_getKeyPrefixArray(keys) {
|
|
284
|
+
if (!this._useKeyPrefix) {
|
|
285
|
+
return keys;
|
|
286
|
+
}
|
|
287
|
+
if (!this._namespace) {
|
|
288
|
+
return keys;
|
|
289
|
+
}
|
|
290
|
+
return keys.map((key) => `${this._namespace}:${key}`);
|
|
291
|
+
}
|
|
292
|
+
_getKeyUnprefix(key) {
|
|
293
|
+
if (!this._useKeyPrefix) {
|
|
294
|
+
return key;
|
|
295
|
+
}
|
|
296
|
+
return key.split(':').splice(1).join(':');
|
|
297
|
+
}
|
|
298
|
+
_isValidStorageAdapter(store) {
|
|
299
|
+
return (store instanceof Map ||
|
|
300
|
+
(typeof store.get === 'function' &&
|
|
301
|
+
typeof store.set === 'function' &&
|
|
302
|
+
typeof store.delete === 'function' &&
|
|
303
|
+
typeof store.clear === 'function'));
|
|
304
|
+
}
|
|
305
|
+
async get(key, options) {
|
|
306
|
+
const { store } = this.opts;
|
|
307
|
+
const isArray = Array.isArray(key);
|
|
308
|
+
const keyPrefixed = isArray ? this._getKeyPrefixArray(key) : this._getKeyPrefix(key);
|
|
309
|
+
const isDataExpired = (data) => typeof data.expires === 'number' && Date.now() > data.expires;
|
|
310
|
+
if (isArray) {
|
|
311
|
+
if (options?.raw === true) {
|
|
312
|
+
return this.getMany(key, { raw: true });
|
|
313
|
+
}
|
|
314
|
+
return this.getMany(key, { raw: false });
|
|
315
|
+
}
|
|
316
|
+
this.hooks.trigger('preGet', { key: keyPrefixed });
|
|
317
|
+
let rawData;
|
|
318
|
+
try {
|
|
319
|
+
rawData = await store.get(keyPrefixed);
|
|
320
|
+
}
|
|
321
|
+
catch (error) {
|
|
322
|
+
if (this.throwOnErrors) {
|
|
323
|
+
throw error;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
const deserializedData = typeof rawData === 'string' || this.opts.compression
|
|
327
|
+
? await this.deserializeData(rawData)
|
|
328
|
+
: rawData;
|
|
329
|
+
if (deserializedData === undefined || deserializedData === null) {
|
|
330
|
+
this.hooks.trigger('postGet', {
|
|
331
|
+
key: keyPrefixed,
|
|
332
|
+
value: undefined
|
|
333
|
+
});
|
|
334
|
+
this.stats.miss();
|
|
335
|
+
return undefined;
|
|
336
|
+
}
|
|
337
|
+
if (isDataExpired(deserializedData)) {
|
|
338
|
+
await this.delete(key);
|
|
339
|
+
this.hooks.trigger('postGet', {
|
|
340
|
+
key: keyPrefixed,
|
|
341
|
+
value: undefined
|
|
342
|
+
});
|
|
343
|
+
this.stats.miss();
|
|
344
|
+
return undefined;
|
|
345
|
+
}
|
|
346
|
+
this.hooks.trigger('postGet', {
|
|
347
|
+
key: keyPrefixed,
|
|
348
|
+
value: deserializedData
|
|
349
|
+
});
|
|
350
|
+
this.stats.hit();
|
|
351
|
+
return options?.raw ? deserializedData : deserializedData.value;
|
|
352
|
+
}
|
|
353
|
+
async getMany(keys, options) {
|
|
354
|
+
const { store } = this.opts;
|
|
355
|
+
const keyPrefixed = this._getKeyPrefixArray(keys);
|
|
356
|
+
const isDataExpired = (data) => typeof data.expires === 'number' && Date.now() > data.expires;
|
|
357
|
+
this.hooks.trigger('preGetMany', { keys: keyPrefixed });
|
|
358
|
+
if (store.getMany === undefined) {
|
|
359
|
+
const promises = keyPrefixed.map(async (key) => {
|
|
360
|
+
const rawData = await store.get(key);
|
|
361
|
+
const deserializedRow = typeof rawData === 'string' || this.opts.compression
|
|
362
|
+
? await this.deserializeData(rawData)
|
|
363
|
+
: rawData;
|
|
364
|
+
if (deserializedRow === undefined || deserializedRow === null) {
|
|
365
|
+
return undefined;
|
|
366
|
+
}
|
|
367
|
+
if (isDataExpired(deserializedRow)) {
|
|
368
|
+
await this.delete(key);
|
|
369
|
+
return undefined;
|
|
370
|
+
}
|
|
371
|
+
return options?.raw
|
|
372
|
+
? deserializedRow
|
|
373
|
+
: deserializedRow.value;
|
|
374
|
+
});
|
|
375
|
+
const deserializedRows = await Promise.allSettled(promises);
|
|
376
|
+
const result = deserializedRows.map((row) => row.value);
|
|
377
|
+
this.hooks.trigger('postGetMany', result);
|
|
378
|
+
if (result.length > 0) {
|
|
379
|
+
this.stats.hit();
|
|
380
|
+
}
|
|
381
|
+
return result;
|
|
382
|
+
}
|
|
383
|
+
const rawData = await store.getMany(keyPrefixed);
|
|
384
|
+
const result = [];
|
|
385
|
+
const expiredKeys = [];
|
|
386
|
+
for (const index in rawData) {
|
|
387
|
+
let row = rawData[index];
|
|
388
|
+
if (typeof row === 'string') {
|
|
389
|
+
row = await this.deserializeData(row);
|
|
390
|
+
}
|
|
391
|
+
if (row === undefined || row === null) {
|
|
392
|
+
result.push(undefined);
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
if (isDataExpired(row)) {
|
|
396
|
+
expiredKeys.push(keys[index]);
|
|
397
|
+
result.push(undefined);
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
const value = options?.raw
|
|
401
|
+
? row
|
|
402
|
+
: row.value;
|
|
403
|
+
result.push(value);
|
|
404
|
+
}
|
|
405
|
+
if (expiredKeys.length > 0) {
|
|
406
|
+
await this.deleteMany(expiredKeys);
|
|
407
|
+
}
|
|
408
|
+
this.hooks.trigger('postGetMany', result);
|
|
409
|
+
/* v8 ignore next -- @preserve */
|
|
410
|
+
if (result.length > 0) {
|
|
411
|
+
this.stats.hit();
|
|
412
|
+
}
|
|
413
|
+
return result;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Get the raw value of a key. This is the replacement for setting raw to true in the get() method.
|
|
417
|
+
* @param {string} key the key to get
|
|
418
|
+
* @returns {Promise<StoredDataRaw<Value> | undefined>} will return a StoredDataRaw<Value> or undefined if the key does not exist or is expired.
|
|
419
|
+
*/
|
|
420
|
+
async getRaw(key) {
|
|
421
|
+
const { store } = this.opts;
|
|
422
|
+
const keyPrefixed = this._getKeyPrefix(key);
|
|
423
|
+
this.hooks.trigger('preGetRaw', { key: keyPrefixed });
|
|
424
|
+
const rawData = await store.get(keyPrefixed);
|
|
425
|
+
if (rawData === undefined || rawData === null) {
|
|
426
|
+
this.hooks.trigger('postGetRaw', {
|
|
427
|
+
key: keyPrefixed,
|
|
428
|
+
value: undefined
|
|
429
|
+
});
|
|
430
|
+
this.stats.miss();
|
|
431
|
+
return undefined;
|
|
432
|
+
}
|
|
433
|
+
// Check if the data is expired
|
|
434
|
+
/* v8 ignore next -- @preserve */
|
|
435
|
+
const deserializedData = typeof rawData === 'string' || this.opts.compression
|
|
436
|
+
? await this.deserializeData(rawData)
|
|
437
|
+
: rawData;
|
|
438
|
+
if (deserializedData !== undefined &&
|
|
439
|
+
deserializedData.expires !== undefined &&
|
|
440
|
+
deserializedData.expires !== null &&
|
|
441
|
+
deserializedData.expires < Date.now()) {
|
|
442
|
+
this.hooks.trigger('postGetRaw', {
|
|
443
|
+
key: keyPrefixed,
|
|
444
|
+
value: undefined
|
|
445
|
+
});
|
|
446
|
+
this.stats.miss();
|
|
447
|
+
await this.delete(key);
|
|
448
|
+
return undefined;
|
|
449
|
+
}
|
|
450
|
+
// Add a hit
|
|
451
|
+
this.stats.hit();
|
|
452
|
+
this.hooks.trigger('postGetRaw', {
|
|
453
|
+
key: keyPrefixed,
|
|
454
|
+
value: deserializedData
|
|
455
|
+
});
|
|
456
|
+
return deserializedData;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Get the raw values of many keys. This is the replacement for setting raw to true in the getMany() method.
|
|
460
|
+
* @param {string[]} keys the keys to get
|
|
461
|
+
* @returns {Promise<Array<StoredDataRaw<Value>>>} will return an array of StoredDataRaw<Value> or undefined if the key does not exist or is expired.
|
|
462
|
+
*/
|
|
463
|
+
async getManyRaw(keys) {
|
|
464
|
+
const { store } = this.opts;
|
|
465
|
+
const keyPrefixed = this._getKeyPrefixArray(keys);
|
|
466
|
+
if (keys.length === 0) {
|
|
467
|
+
const result = Array.from({ length: keys.length }).fill(undefined);
|
|
468
|
+
// Add in misses
|
|
469
|
+
this.stats.misses += keys.length;
|
|
470
|
+
// Trigger the post get many raw hook
|
|
471
|
+
this.hooks.trigger('postGetManyRaw', {
|
|
472
|
+
keys: keyPrefixed,
|
|
473
|
+
values: result
|
|
474
|
+
});
|
|
475
|
+
return result;
|
|
476
|
+
}
|
|
477
|
+
let result = [];
|
|
478
|
+
// Check to see if the store has a getMany method
|
|
479
|
+
if (store.getMany === undefined) {
|
|
480
|
+
// If not then we will get each key individually
|
|
481
|
+
const promises = keyPrefixed.map(async (key) => {
|
|
482
|
+
const rawData = await store.get(key);
|
|
483
|
+
if (rawData !== undefined && rawData !== null) {
|
|
484
|
+
return this.deserializeData(rawData);
|
|
485
|
+
}
|
|
486
|
+
return undefined;
|
|
487
|
+
});
|
|
488
|
+
const deserializedRows = await Promise.allSettled(promises);
|
|
489
|
+
result = deserializedRows.map((row) => row.value);
|
|
490
|
+
}
|
|
491
|
+
else {
|
|
492
|
+
const rawData = await store.getMany(keyPrefixed);
|
|
493
|
+
for (const row of rawData) {
|
|
494
|
+
/* v8 ignore next -- @preserve */
|
|
495
|
+
if (row !== undefined && row !== null) {
|
|
496
|
+
result.push(await this.deserializeData(row));
|
|
497
|
+
}
|
|
498
|
+
else {
|
|
499
|
+
/* v8 ignore next -- @preserve */
|
|
500
|
+
result.push(undefined);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
// Filter out any expired keys and delete them
|
|
505
|
+
const expiredKeys = [];
|
|
506
|
+
const isDataExpired = (data) => typeof data.expires === 'number' && Date.now() > data.expires;
|
|
507
|
+
for (const [index, row] of result.entries()) {
|
|
508
|
+
if (row !== undefined && isDataExpired(row)) {
|
|
509
|
+
expiredKeys.push(keyPrefixed[index]);
|
|
510
|
+
result[index] = undefined;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
if (expiredKeys.length > 0) {
|
|
514
|
+
await this.deleteMany(expiredKeys);
|
|
515
|
+
}
|
|
516
|
+
// Add in hits and misses
|
|
517
|
+
this.stats.hitsOrMisses(result);
|
|
518
|
+
// Trigger the post get many raw hook
|
|
519
|
+
this.hooks.trigger('postGetManyRaw', {
|
|
520
|
+
keys: keyPrefixed,
|
|
521
|
+
values: result
|
|
522
|
+
});
|
|
523
|
+
return result;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Set an item to the store
|
|
527
|
+
* @param {string | Array<KeyvEntry>} key the key to use. If you pass in an array of KeyvEntry it will set many items
|
|
528
|
+
* @param {Value} value the value of the key
|
|
529
|
+
* @param {number} [ttl] time to live in milliseconds
|
|
530
|
+
* @returns {boolean} if it sets then it will return a true. On failure will return false.
|
|
531
|
+
*/
|
|
532
|
+
async set(key, value, ttl) {
|
|
533
|
+
const data = { key, value, ttl };
|
|
534
|
+
this.hooks.trigger('preSet', data);
|
|
535
|
+
const keyPrefixed = this._getKeyPrefix(data.key);
|
|
536
|
+
data.ttl ??= this._ttl;
|
|
537
|
+
if (data.ttl === 0) {
|
|
538
|
+
data.ttl = undefined;
|
|
539
|
+
}
|
|
540
|
+
const { store } = this.opts;
|
|
541
|
+
const expires = typeof data.ttl === 'number' ? Date.now() + data.ttl : undefined;
|
|
542
|
+
if (typeof data.value === 'symbol') {
|
|
543
|
+
this.emit('error', 'symbol cannot be serialized');
|
|
544
|
+
throw new Error('symbol cannot be serialized');
|
|
545
|
+
}
|
|
546
|
+
const formattedValue = { value: data.value, expires };
|
|
547
|
+
const serializedValue = await this.serializeData(formattedValue);
|
|
548
|
+
let result = true;
|
|
549
|
+
try {
|
|
550
|
+
const value = await store.set(keyPrefixed, serializedValue, data.ttl);
|
|
551
|
+
if (typeof value === 'boolean') {
|
|
552
|
+
result = value;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
catch (error) {
|
|
556
|
+
result = false;
|
|
557
|
+
this.emit('error', error);
|
|
558
|
+
if (this._throwOnErrors) {
|
|
559
|
+
throw error;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
this.hooks.trigger('postSet', {
|
|
563
|
+
key: keyPrefixed,
|
|
564
|
+
value: serializedValue,
|
|
565
|
+
ttl
|
|
566
|
+
});
|
|
567
|
+
this.stats.set();
|
|
568
|
+
return result;
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Set many items to the store
|
|
572
|
+
* @param {Array<KeyvEntry>} entries the entries to set
|
|
573
|
+
* @returns {boolean[]} will return an array of booleans if it sets then it will return a true. On failure will return false.
|
|
574
|
+
*/
|
|
575
|
+
async setMany(entries) {
|
|
576
|
+
let results = [];
|
|
577
|
+
try {
|
|
578
|
+
// If the store doesn't have a setMany method then fall back to setting each entry individually
|
|
579
|
+
if (this._store.setMany === undefined) {
|
|
580
|
+
const promises = [];
|
|
581
|
+
for (const entry of entries) {
|
|
582
|
+
promises.push(this.set(entry.key, entry.value, entry.ttl));
|
|
583
|
+
}
|
|
584
|
+
const promiseResults = await Promise.all(promises);
|
|
585
|
+
results = promiseResults;
|
|
586
|
+
}
|
|
587
|
+
else {
|
|
588
|
+
const serializedEntries = await Promise.all(entries.map(async ({ key, value, ttl }) => {
|
|
589
|
+
ttl ??= this._ttl;
|
|
590
|
+
/* v8 ignore next -- @preserve */
|
|
591
|
+
if (ttl === 0) {
|
|
592
|
+
ttl = undefined;
|
|
593
|
+
}
|
|
594
|
+
/* v8 ignore next -- @preserve */
|
|
595
|
+
const expires = typeof ttl === 'number' ? Date.now() + ttl : undefined;
|
|
596
|
+
/* v8 ignore next -- @preserve */
|
|
597
|
+
if (typeof value === 'symbol') {
|
|
598
|
+
this.emit('error', 'symbol cannot be serialized');
|
|
599
|
+
throw new Error('symbol cannot be serialized');
|
|
600
|
+
}
|
|
601
|
+
const formattedValue = { value, expires };
|
|
602
|
+
const serializedValue = await this.serializeData(formattedValue);
|
|
603
|
+
const keyPrefixed = this._getKeyPrefix(key);
|
|
604
|
+
return { key: keyPrefixed, value: serializedValue, ttl };
|
|
605
|
+
}));
|
|
606
|
+
results = await this._store.setMany(serializedEntries);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
catch (error) {
|
|
610
|
+
this.emit('error', error);
|
|
611
|
+
if (this._throwOnErrors) {
|
|
612
|
+
throw error;
|
|
613
|
+
}
|
|
614
|
+
results = entries.map(() => false);
|
|
615
|
+
}
|
|
616
|
+
return results;
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Delete an Entry
|
|
620
|
+
* @param {string | string[]} key the key to be deleted. if an array it will delete many items
|
|
621
|
+
* @returns {boolean} will return true if item or items are deleted. false if there is an error
|
|
622
|
+
*/
|
|
623
|
+
async delete(key) {
|
|
624
|
+
const { store } = this.opts;
|
|
625
|
+
if (Array.isArray(key)) {
|
|
626
|
+
return this.deleteMany(key);
|
|
627
|
+
}
|
|
628
|
+
const keyPrefixed = this._getKeyPrefix(key);
|
|
629
|
+
this.hooks.trigger('preDelete', { key: keyPrefixed });
|
|
630
|
+
let result = true;
|
|
631
|
+
try {
|
|
632
|
+
const value = await store.delete(keyPrefixed);
|
|
633
|
+
/* v8 ignore next -- @preserve */
|
|
634
|
+
if (typeof value === 'boolean') {
|
|
635
|
+
result = value;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
catch (error) {
|
|
639
|
+
result = false;
|
|
640
|
+
this.emit('error', error);
|
|
641
|
+
if (this._throwOnErrors) {
|
|
642
|
+
throw error;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
this.hooks.trigger('postDelete', {
|
|
646
|
+
key: keyPrefixed,
|
|
647
|
+
value: result
|
|
648
|
+
});
|
|
649
|
+
this.stats.delete();
|
|
650
|
+
return result;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Delete many items from the store
|
|
654
|
+
* @param {string[]} keys the keys to be deleted
|
|
655
|
+
* @returns {boolean} will return true if item or items are deleted. false if there is an error
|
|
656
|
+
*/
|
|
657
|
+
async deleteMany(keys) {
|
|
658
|
+
try {
|
|
659
|
+
const { store } = this.opts;
|
|
660
|
+
const keyPrefixed = this._getKeyPrefixArray(keys);
|
|
661
|
+
this.hooks.trigger('preDelete', { key: keyPrefixed });
|
|
662
|
+
if (store.deleteMany !== undefined) {
|
|
663
|
+
return await store.deleteMany(keyPrefixed);
|
|
664
|
+
}
|
|
665
|
+
const promises = keyPrefixed.map(async (key) => store.delete(key));
|
|
666
|
+
const results = await Promise.all(promises);
|
|
667
|
+
const returnResult = results.every(Boolean);
|
|
668
|
+
this.hooks.trigger('postDelete', {
|
|
669
|
+
key: keyPrefixed,
|
|
670
|
+
value: returnResult
|
|
671
|
+
});
|
|
672
|
+
return returnResult;
|
|
673
|
+
}
|
|
674
|
+
catch (error) {
|
|
675
|
+
this.emit('error', error);
|
|
676
|
+
if (this._throwOnErrors) {
|
|
677
|
+
throw error;
|
|
678
|
+
}
|
|
679
|
+
return false;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* Clear the store
|
|
684
|
+
* @returns {void}
|
|
685
|
+
*/
|
|
686
|
+
async clear() {
|
|
687
|
+
this.emit('clear');
|
|
688
|
+
const { store } = this.opts;
|
|
689
|
+
try {
|
|
690
|
+
await store.clear();
|
|
691
|
+
}
|
|
692
|
+
catch (error) {
|
|
693
|
+
this.emit('error', error);
|
|
694
|
+
if (this._throwOnErrors) {
|
|
695
|
+
throw error;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
async has(key) {
|
|
700
|
+
if (Array.isArray(key)) {
|
|
701
|
+
return this.hasMany(key);
|
|
702
|
+
}
|
|
703
|
+
const keyPrefixed = this._getKeyPrefix(key);
|
|
704
|
+
const { store } = this.opts;
|
|
705
|
+
if (store.has !== undefined && !(store instanceof Map)) {
|
|
706
|
+
return store.has(keyPrefixed);
|
|
707
|
+
}
|
|
708
|
+
let rawData;
|
|
709
|
+
try {
|
|
710
|
+
rawData = await store.get(keyPrefixed);
|
|
711
|
+
}
|
|
712
|
+
catch (error) {
|
|
713
|
+
this.emit('error', error);
|
|
714
|
+
if (this._throwOnErrors) {
|
|
715
|
+
throw error;
|
|
716
|
+
}
|
|
717
|
+
return false;
|
|
718
|
+
}
|
|
719
|
+
if (rawData) {
|
|
720
|
+
const data = (await this.deserializeData(rawData));
|
|
721
|
+
/* v8 ignore next -- @preserve */
|
|
722
|
+
if (data) {
|
|
723
|
+
if (data.expires === undefined || data.expires === null) {
|
|
724
|
+
return true;
|
|
725
|
+
}
|
|
726
|
+
return data.expires > Date.now();
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
return false;
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Check if many keys exist
|
|
733
|
+
* @param {string[]} keys the keys to check
|
|
734
|
+
* @returns {boolean[]} will return an array of booleans if the keys exist
|
|
735
|
+
*/
|
|
736
|
+
async hasMany(keys) {
|
|
737
|
+
const keyPrefixed = this._getKeyPrefixArray(keys);
|
|
738
|
+
const { store } = this.opts;
|
|
739
|
+
if (store.hasMany !== undefined) {
|
|
740
|
+
return store.hasMany(keyPrefixed);
|
|
741
|
+
}
|
|
742
|
+
const results = [];
|
|
743
|
+
for (const key of keys) {
|
|
744
|
+
// eslint-disable-next-line no-await-in-loop
|
|
745
|
+
results.push(await this.has(key));
|
|
746
|
+
}
|
|
747
|
+
return results;
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Will disconnect the store. This is only available if the store has a disconnect method
|
|
751
|
+
* @returns {Promise<void>}
|
|
752
|
+
*/
|
|
753
|
+
async disconnect() {
|
|
754
|
+
const { store } = this.opts;
|
|
755
|
+
this.emit('disconnect');
|
|
756
|
+
if (typeof store.disconnect === 'function') {
|
|
757
|
+
return store.disconnect();
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
emit(event, ...arguments_) {
|
|
761
|
+
if (event === 'error' && !this.opts.emitErrors) {
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
super.emit(event, ...arguments_);
|
|
765
|
+
}
|
|
766
|
+
async serializeData(data) {
|
|
767
|
+
if (!this._serialize) {
|
|
768
|
+
return data;
|
|
769
|
+
}
|
|
770
|
+
if (this._compression?.compress) {
|
|
771
|
+
return this._serialize({
|
|
772
|
+
value: await this._compression.compress(data.value),
|
|
773
|
+
expires: data.expires
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
return this._serialize(data);
|
|
777
|
+
}
|
|
778
|
+
async deserializeData(data) {
|
|
779
|
+
if (!this._deserialize) {
|
|
780
|
+
return data;
|
|
781
|
+
}
|
|
782
|
+
if (this._compression?.decompress && typeof data === 'string') {
|
|
783
|
+
const result = await this._deserialize(data);
|
|
784
|
+
return {
|
|
785
|
+
value: await this._compression.decompress(result?.value),
|
|
786
|
+
expires: result?.expires
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
if (typeof data === 'string') {
|
|
790
|
+
return this._deserialize(data);
|
|
791
|
+
}
|
|
792
|
+
return undefined;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
export default Keyv;
|
|
796
|
+
//# sourceMappingURL=index.js.map
|