keyv 6.0.0-alpha.3 → 6.0.0-beta.3
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 +1 -1
- package/README.md +270 -56
- package/dist/index.cjs +2270 -1100
- package/dist/index.d.cts +1329 -367
- package/dist/index.d.mts +1351 -0
- package/dist/index.mjs +2268 -0
- package/package.json +23 -14
- package/dist/index.d.ts +0 -389
- package/dist/index.js +0 -1087
package/dist/index.js
DELETED
|
@@ -1,1087 +0,0 @@
|
|
|
1
|
-
// src/event-manager.ts
|
|
2
|
-
var EventManager = class {
|
|
3
|
-
_eventListeners;
|
|
4
|
-
_maxListeners;
|
|
5
|
-
constructor() {
|
|
6
|
-
this._eventListeners = /* @__PURE__ */ new Map();
|
|
7
|
-
this._maxListeners = 100;
|
|
8
|
-
}
|
|
9
|
-
maxListeners() {
|
|
10
|
-
return this._maxListeners;
|
|
11
|
-
}
|
|
12
|
-
// Add an event listener
|
|
13
|
-
addListener(event, listener) {
|
|
14
|
-
this.on(event, listener);
|
|
15
|
-
}
|
|
16
|
-
on(event, listener) {
|
|
17
|
-
if (!this._eventListeners.has(event)) {
|
|
18
|
-
this._eventListeners.set(event, []);
|
|
19
|
-
}
|
|
20
|
-
const listeners = this._eventListeners.get(event);
|
|
21
|
-
if (listeners) {
|
|
22
|
-
if (listeners.length >= this._maxListeners) {
|
|
23
|
-
console.warn(
|
|
24
|
-
`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event} listeners added. Use setMaxListeners() to increase limit.`
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
listeners.push(listener);
|
|
28
|
-
}
|
|
29
|
-
return this;
|
|
30
|
-
}
|
|
31
|
-
// Remove an event listener
|
|
32
|
-
removeListener(event, listener) {
|
|
33
|
-
this.off(event, listener);
|
|
34
|
-
}
|
|
35
|
-
off(event, listener) {
|
|
36
|
-
const listeners = this._eventListeners.get(event) ?? [];
|
|
37
|
-
const index = listeners.indexOf(listener);
|
|
38
|
-
if (index !== -1) {
|
|
39
|
-
listeners.splice(index, 1);
|
|
40
|
-
}
|
|
41
|
-
if (listeners.length === 0) {
|
|
42
|
-
this._eventListeners.delete(event);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
once(event, listener) {
|
|
46
|
-
const onceListener = (...arguments_) => {
|
|
47
|
-
listener(...arguments_);
|
|
48
|
-
this.off(event, onceListener);
|
|
49
|
-
};
|
|
50
|
-
this.on(event, onceListener);
|
|
51
|
-
}
|
|
52
|
-
// Emit an event
|
|
53
|
-
// biome-ignore lint/suspicious/noExplicitAny: type format
|
|
54
|
-
emit(event, ...arguments_) {
|
|
55
|
-
const listeners = this._eventListeners.get(event);
|
|
56
|
-
if (listeners && listeners.length > 0) {
|
|
57
|
-
for (const listener of listeners) {
|
|
58
|
-
listener(...arguments_);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
// Get all listeners for a specific event
|
|
63
|
-
listeners(event) {
|
|
64
|
-
return this._eventListeners.get(event) ?? [];
|
|
65
|
-
}
|
|
66
|
-
// Remove all listeners for a specific event
|
|
67
|
-
removeAllListeners(event) {
|
|
68
|
-
if (event) {
|
|
69
|
-
this._eventListeners.delete(event);
|
|
70
|
-
} else {
|
|
71
|
-
this._eventListeners.clear();
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
// Set the maximum number of listeners for a single event
|
|
75
|
-
setMaxListeners(n) {
|
|
76
|
-
this._maxListeners = n;
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
var event_manager_default = EventManager;
|
|
80
|
-
|
|
81
|
-
// src/hooks-manager.ts
|
|
82
|
-
var HooksManager = class extends event_manager_default {
|
|
83
|
-
_hookHandlers;
|
|
84
|
-
constructor() {
|
|
85
|
-
super();
|
|
86
|
-
this._hookHandlers = /* @__PURE__ */ new Map();
|
|
87
|
-
}
|
|
88
|
-
// Adds a handler function for a specific event
|
|
89
|
-
addHandler(event, handler) {
|
|
90
|
-
const eventHandlers = this._hookHandlers.get(event);
|
|
91
|
-
if (eventHandlers) {
|
|
92
|
-
eventHandlers.push(handler);
|
|
93
|
-
} else {
|
|
94
|
-
this._hookHandlers.set(event, [handler]);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
// Removes a specific handler function for a specific event
|
|
98
|
-
removeHandler(event, handler) {
|
|
99
|
-
const eventHandlers = this._hookHandlers.get(event);
|
|
100
|
-
if (eventHandlers) {
|
|
101
|
-
const index = eventHandlers.indexOf(handler);
|
|
102
|
-
if (index !== -1) {
|
|
103
|
-
eventHandlers.splice(index, 1);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
// Triggers all handlers for a specific event with provided data
|
|
108
|
-
// biome-ignore lint/suspicious/noExplicitAny: type format
|
|
109
|
-
trigger(event, data) {
|
|
110
|
-
const eventHandlers = this._hookHandlers.get(event);
|
|
111
|
-
if (eventHandlers) {
|
|
112
|
-
for (const handler of eventHandlers) {
|
|
113
|
-
try {
|
|
114
|
-
handler(data);
|
|
115
|
-
} catch (error) {
|
|
116
|
-
this.emit(
|
|
117
|
-
"error",
|
|
118
|
-
new Error(
|
|
119
|
-
`Error in hook handler for event "${event}": ${error.message}`
|
|
120
|
-
)
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
// Provides read-only access to the current handlers
|
|
127
|
-
get handlers() {
|
|
128
|
-
return new Map(this._hookHandlers);
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
var hooks_manager_default = HooksManager;
|
|
132
|
-
|
|
133
|
-
// src/json-serializer.ts
|
|
134
|
-
function getGlobalBuffer() {
|
|
135
|
-
return globalThis.Buffer;
|
|
136
|
-
}
|
|
137
|
-
function bytesToBase64(bytes) {
|
|
138
|
-
const buffer = getGlobalBuffer();
|
|
139
|
-
if (buffer) {
|
|
140
|
-
return buffer.from(bytes).toString("base64");
|
|
141
|
-
}
|
|
142
|
-
let binary = "";
|
|
143
|
-
for (const byte of bytes) {
|
|
144
|
-
binary += String.fromCharCode(byte);
|
|
145
|
-
}
|
|
146
|
-
return btoa(binary);
|
|
147
|
-
}
|
|
148
|
-
function base64ToBytes(value) {
|
|
149
|
-
const buffer = getGlobalBuffer();
|
|
150
|
-
if (buffer) {
|
|
151
|
-
return buffer.from(value, "base64");
|
|
152
|
-
}
|
|
153
|
-
const binary = atob(value);
|
|
154
|
-
const bytes = new Uint8Array(binary.length);
|
|
155
|
-
for (let index = 0; index < binary.length; index++) {
|
|
156
|
-
bytes[index] = binary.charCodeAt(index);
|
|
157
|
-
}
|
|
158
|
-
return bytes;
|
|
159
|
-
}
|
|
160
|
-
function isBinaryValue(value) {
|
|
161
|
-
const buffer = getGlobalBuffer();
|
|
162
|
-
if (buffer?.isBuffer(value)) {
|
|
163
|
-
return true;
|
|
164
|
-
}
|
|
165
|
-
return value instanceof Uint8Array;
|
|
166
|
-
}
|
|
167
|
-
function prepare(value) {
|
|
168
|
-
if (value === null || value === void 0) {
|
|
169
|
-
return value;
|
|
170
|
-
}
|
|
171
|
-
if (isBinaryValue(value)) {
|
|
172
|
-
return `:base64:${bytesToBase64(value)}`;
|
|
173
|
-
}
|
|
174
|
-
if (typeof value === "bigint") {
|
|
175
|
-
return `:bigint:${value.toString()}`;
|
|
176
|
-
}
|
|
177
|
-
if (typeof value === "string") {
|
|
178
|
-
return value.startsWith(":") ? `:${value}` : value;
|
|
179
|
-
}
|
|
180
|
-
if (Array.isArray(value)) {
|
|
181
|
-
return value.map((item) => prepare(item));
|
|
182
|
-
}
|
|
183
|
-
if (typeof value === "object") {
|
|
184
|
-
if (typeof value.toJSON === "function") {
|
|
185
|
-
return prepare(value.toJSON());
|
|
186
|
-
}
|
|
187
|
-
const result = {};
|
|
188
|
-
for (const key of Object.keys(value)) {
|
|
189
|
-
if (value[key] !== void 0) {
|
|
190
|
-
result[key] = prepare(value[key]);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return result;
|
|
194
|
-
}
|
|
195
|
-
return value;
|
|
196
|
-
}
|
|
197
|
-
var KeyvJsonSerializer = class {
|
|
198
|
-
stringify(object) {
|
|
199
|
-
return JSON.stringify(prepare(object));
|
|
200
|
-
}
|
|
201
|
-
parse(data) {
|
|
202
|
-
return JSON.parse(data, (_, value) => {
|
|
203
|
-
if (typeof value === "string") {
|
|
204
|
-
if (value.startsWith(":bigint:")) {
|
|
205
|
-
return BigInt(value.slice(8));
|
|
206
|
-
}
|
|
207
|
-
if (value.startsWith(":base64:")) {
|
|
208
|
-
return base64ToBytes(value.slice(8));
|
|
209
|
-
}
|
|
210
|
-
return value.startsWith(":") ? value.slice(1) : value;
|
|
211
|
-
}
|
|
212
|
-
return value;
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
};
|
|
216
|
-
var jsonSerializer = new KeyvJsonSerializer();
|
|
217
|
-
|
|
218
|
-
// src/stats-manager.ts
|
|
219
|
-
var StatsManager = class extends event_manager_default {
|
|
220
|
-
enabled = true;
|
|
221
|
-
hits = 0;
|
|
222
|
-
misses = 0;
|
|
223
|
-
sets = 0;
|
|
224
|
-
deletes = 0;
|
|
225
|
-
errors = 0;
|
|
226
|
-
constructor(enabled) {
|
|
227
|
-
super();
|
|
228
|
-
if (enabled !== void 0) {
|
|
229
|
-
this.enabled = enabled;
|
|
230
|
-
}
|
|
231
|
-
this.reset();
|
|
232
|
-
}
|
|
233
|
-
hit() {
|
|
234
|
-
if (this.enabled) {
|
|
235
|
-
this.hits++;
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
miss() {
|
|
239
|
-
if (this.enabled) {
|
|
240
|
-
this.misses++;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
set() {
|
|
244
|
-
if (this.enabled) {
|
|
245
|
-
this.sets++;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
delete() {
|
|
249
|
-
if (this.enabled) {
|
|
250
|
-
this.deletes++;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
hitsOrMisses(array) {
|
|
254
|
-
for (const item of array) {
|
|
255
|
-
if (item === void 0) {
|
|
256
|
-
this.miss();
|
|
257
|
-
} else {
|
|
258
|
-
this.hit();
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
reset() {
|
|
263
|
-
this.hits = 0;
|
|
264
|
-
this.misses = 0;
|
|
265
|
-
this.sets = 0;
|
|
266
|
-
this.deletes = 0;
|
|
267
|
-
this.errors = 0;
|
|
268
|
-
}
|
|
269
|
-
};
|
|
270
|
-
var stats_manager_default = StatsManager;
|
|
271
|
-
|
|
272
|
-
// src/types.ts
|
|
273
|
-
var KeyvHooks = /* @__PURE__ */ ((KeyvHooks2) => {
|
|
274
|
-
KeyvHooks2["PRE_SET"] = "preSet";
|
|
275
|
-
KeyvHooks2["POST_SET"] = "postSet";
|
|
276
|
-
KeyvHooks2["PRE_GET"] = "preGet";
|
|
277
|
-
KeyvHooks2["POST_GET"] = "postGet";
|
|
278
|
-
KeyvHooks2["PRE_GET_MANY"] = "preGetMany";
|
|
279
|
-
KeyvHooks2["POST_GET_MANY"] = "postGetMany";
|
|
280
|
-
KeyvHooks2["PRE_GET_RAW"] = "preGetRaw";
|
|
281
|
-
KeyvHooks2["POST_GET_RAW"] = "postGetRaw";
|
|
282
|
-
KeyvHooks2["PRE_GET_MANY_RAW"] = "preGetManyRaw";
|
|
283
|
-
KeyvHooks2["POST_GET_MANY_RAW"] = "postGetManyRaw";
|
|
284
|
-
KeyvHooks2["PRE_SET_RAW"] = "preSetRaw";
|
|
285
|
-
KeyvHooks2["POST_SET_RAW"] = "postSetRaw";
|
|
286
|
-
KeyvHooks2["PRE_SET_MANY_RAW"] = "preSetManyRaw";
|
|
287
|
-
KeyvHooks2["POST_SET_MANY_RAW"] = "postSetManyRaw";
|
|
288
|
-
KeyvHooks2["PRE_DELETE"] = "preDelete";
|
|
289
|
-
KeyvHooks2["POST_DELETE"] = "postDelete";
|
|
290
|
-
return KeyvHooks2;
|
|
291
|
-
})(KeyvHooks || {});
|
|
292
|
-
|
|
293
|
-
// src/index.ts
|
|
294
|
-
var iterableAdapters = [
|
|
295
|
-
"sqlite",
|
|
296
|
-
"postgres",
|
|
297
|
-
"mysql",
|
|
298
|
-
"mongo",
|
|
299
|
-
"redis",
|
|
300
|
-
"valkey",
|
|
301
|
-
"etcd"
|
|
302
|
-
];
|
|
303
|
-
var Keyv = class extends event_manager_default {
|
|
304
|
-
iterator;
|
|
305
|
-
hooks = new hooks_manager_default();
|
|
306
|
-
stats = new stats_manager_default(false);
|
|
307
|
-
/**
|
|
308
|
-
* Time to live in milliseconds
|
|
309
|
-
*/
|
|
310
|
-
_ttl;
|
|
311
|
-
/**
|
|
312
|
-
* Namespace
|
|
313
|
-
*/
|
|
314
|
-
_namespace;
|
|
315
|
-
/**
|
|
316
|
-
* Store
|
|
317
|
-
*/
|
|
318
|
-
// biome-ignore lint/suspicious/noExplicitAny: type format
|
|
319
|
-
_store = /* @__PURE__ */ new Map();
|
|
320
|
-
_serialization;
|
|
321
|
-
_compression;
|
|
322
|
-
_throwOnErrors = false;
|
|
323
|
-
_emitErrors = true;
|
|
324
|
-
/**
|
|
325
|
-
* Keyv Constructor
|
|
326
|
-
* @param {KeyvStorageAdapter | KeyvOptions} store
|
|
327
|
-
* @param {Omit<KeyvOptions, 'store'>} [options] if you provide the store you can then provide the Keyv Options
|
|
328
|
-
*/
|
|
329
|
-
constructor(store, options) {
|
|
330
|
-
super();
|
|
331
|
-
options ??= {};
|
|
332
|
-
store ??= {};
|
|
333
|
-
const mergedOptions = {
|
|
334
|
-
namespace: "keyv",
|
|
335
|
-
emitErrors: true,
|
|
336
|
-
...options
|
|
337
|
-
};
|
|
338
|
-
if (store && store.get) {
|
|
339
|
-
mergedOptions.store = store;
|
|
340
|
-
} else {
|
|
341
|
-
Object.assign(mergedOptions, store);
|
|
342
|
-
}
|
|
343
|
-
this._store = mergedOptions.store ?? /* @__PURE__ */ new Map();
|
|
344
|
-
this._compression = mergedOptions.compression;
|
|
345
|
-
if (mergedOptions.serialization === false) {
|
|
346
|
-
this._serialization = void 0;
|
|
347
|
-
} else {
|
|
348
|
-
this._serialization = mergedOptions.serialization ?? new KeyvJsonSerializer();
|
|
349
|
-
}
|
|
350
|
-
if (mergedOptions.namespace) {
|
|
351
|
-
this._namespace = mergedOptions.namespace;
|
|
352
|
-
}
|
|
353
|
-
if (this._store) {
|
|
354
|
-
if (!this._isValidStorageAdapter(this._store)) {
|
|
355
|
-
throw new Error("Invalid storage adapter");
|
|
356
|
-
}
|
|
357
|
-
if (typeof this._store.on === "function") {
|
|
358
|
-
this._store.on("error", (error) => this.emit("error", error));
|
|
359
|
-
}
|
|
360
|
-
this._store.namespace = this._namespace;
|
|
361
|
-
if (
|
|
362
|
-
// biome-ignore lint/suspicious/noExplicitAny: need to check Map iterator
|
|
363
|
-
typeof this._store[Symbol.iterator] === "function" && this._store instanceof Map
|
|
364
|
-
) {
|
|
365
|
-
this.iterator = this.generateIterator(
|
|
366
|
-
this._store
|
|
367
|
-
);
|
|
368
|
-
} else if ("iterator" in this._store && this._store.opts && this._checkIterableAdapter()) {
|
|
369
|
-
this.iterator = this.generateIterator(
|
|
370
|
-
// biome-ignore lint/style/noNonNullAssertion: need to fix
|
|
371
|
-
this._store.iterator.bind(this._store)
|
|
372
|
-
);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
if (mergedOptions.stats) {
|
|
376
|
-
this.stats.enabled = mergedOptions.stats;
|
|
377
|
-
}
|
|
378
|
-
if (mergedOptions.ttl) {
|
|
379
|
-
this._ttl = mergedOptions.ttl;
|
|
380
|
-
}
|
|
381
|
-
if (mergedOptions.emitErrors !== void 0) {
|
|
382
|
-
this._emitErrors = mergedOptions.emitErrors;
|
|
383
|
-
}
|
|
384
|
-
if (mergedOptions.throwOnErrors !== void 0) {
|
|
385
|
-
this._throwOnErrors = mergedOptions.throwOnErrors;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* Get the current store
|
|
390
|
-
*/
|
|
391
|
-
// biome-ignore lint/suspicious/noExplicitAny: type format
|
|
392
|
-
get store() {
|
|
393
|
-
return this._store;
|
|
394
|
-
}
|
|
395
|
-
/**
|
|
396
|
-
* 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.
|
|
397
|
-
* @param {KeyvStorageAdapter | Map<any, any> | any} store the store to set
|
|
398
|
-
*/
|
|
399
|
-
// biome-ignore lint/suspicious/noExplicitAny: type format
|
|
400
|
-
set store(store) {
|
|
401
|
-
if (this._isValidStorageAdapter(store)) {
|
|
402
|
-
this._store = store;
|
|
403
|
-
if (typeof store.on === "function") {
|
|
404
|
-
store.on("error", (error) => this.emit("error", error));
|
|
405
|
-
}
|
|
406
|
-
if (this._namespace) {
|
|
407
|
-
this._store.namespace = this._namespace;
|
|
408
|
-
}
|
|
409
|
-
if (typeof store[Symbol.iterator] === "function" && store instanceof Map) {
|
|
410
|
-
this.iterator = this.generateIterator(
|
|
411
|
-
store
|
|
412
|
-
);
|
|
413
|
-
} else if ("iterator" in store && store.opts && this._checkIterableAdapter()) {
|
|
414
|
-
this.iterator = this.generateIterator(store.iterator?.bind(store));
|
|
415
|
-
}
|
|
416
|
-
} else {
|
|
417
|
-
throw new Error("Invalid storage adapter");
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
/**
|
|
421
|
-
* Get the current compression function
|
|
422
|
-
* @returns {KeyvCompressionAdapter} The current compression function
|
|
423
|
-
*/
|
|
424
|
-
get compression() {
|
|
425
|
-
return this._compression;
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* Set the current compression function
|
|
429
|
-
* @param {KeyvCompressionAdapter} compress The compression function to set
|
|
430
|
-
*/
|
|
431
|
-
set compression(compress) {
|
|
432
|
-
this._compression = compress;
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
* Get the current namespace.
|
|
436
|
-
* @returns {string | undefined} The current namespace.
|
|
437
|
-
*/
|
|
438
|
-
get namespace() {
|
|
439
|
-
return this._namespace;
|
|
440
|
-
}
|
|
441
|
-
/**
|
|
442
|
-
* Set the current namespace.
|
|
443
|
-
* @param {string | undefined} namespace The namespace to set.
|
|
444
|
-
*/
|
|
445
|
-
set namespace(namespace) {
|
|
446
|
-
this._namespace = namespace;
|
|
447
|
-
this._store.namespace = namespace;
|
|
448
|
-
}
|
|
449
|
-
/**
|
|
450
|
-
* Get the current TTL.
|
|
451
|
-
* @returns {number} The current TTL in milliseconds.
|
|
452
|
-
*/
|
|
453
|
-
get ttl() {
|
|
454
|
-
return this._ttl;
|
|
455
|
-
}
|
|
456
|
-
/**
|
|
457
|
-
* Set the current TTL.
|
|
458
|
-
* @param {number} ttl The TTL to set in milliseconds.
|
|
459
|
-
*/
|
|
460
|
-
set ttl(ttl) {
|
|
461
|
-
this._ttl = ttl;
|
|
462
|
-
}
|
|
463
|
-
/**
|
|
464
|
-
* Get the current serialization adapter.
|
|
465
|
-
* @returns {KeyvSerializationAdapter | undefined} The current serialization adapter.
|
|
466
|
-
*/
|
|
467
|
-
get serialization() {
|
|
468
|
-
return this._serialization;
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* Set the current serialization adapter.
|
|
472
|
-
* @param {KeyvSerializationAdapter | undefined} serialization The serialization adapter to set.
|
|
473
|
-
*/
|
|
474
|
-
set serialization(serialization) {
|
|
475
|
-
this._serialization = serialization === false ? void 0 : serialization;
|
|
476
|
-
}
|
|
477
|
-
/**
|
|
478
|
-
* Get the current throwErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
479
|
-
* @return {boolean} The current throwOnErrors value.
|
|
480
|
-
*/
|
|
481
|
-
get throwOnErrors() {
|
|
482
|
-
return this._throwOnErrors;
|
|
483
|
-
}
|
|
484
|
-
/**
|
|
485
|
-
* Set the current throwOnErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
486
|
-
* @param {boolean} value The throwOnErrors value to set.
|
|
487
|
-
*/
|
|
488
|
-
set throwOnErrors(value) {
|
|
489
|
-
this._throwOnErrors = value;
|
|
490
|
-
}
|
|
491
|
-
/**
|
|
492
|
-
* Get the current emitErrors value. This will enable or disable emitting errors on methods.
|
|
493
|
-
* @return {boolean} The current emitErrors value.
|
|
494
|
-
* @default true
|
|
495
|
-
*/
|
|
496
|
-
get emitErrors() {
|
|
497
|
-
return this._emitErrors;
|
|
498
|
-
}
|
|
499
|
-
/**
|
|
500
|
-
* Set the current emitErrors value. This will enable or disable emitting errors on methods.
|
|
501
|
-
* @param {boolean} value The emitErrors value to set.
|
|
502
|
-
*/
|
|
503
|
-
set emitErrors(value) {
|
|
504
|
-
this._emitErrors = value;
|
|
505
|
-
}
|
|
506
|
-
generateIterator(iterator) {
|
|
507
|
-
const function_ = async function* () {
|
|
508
|
-
for await (const [key, raw] of typeof iterator === "function" ? iterator(this._store.namespace) : iterator) {
|
|
509
|
-
const data = await this.deserializeData(raw);
|
|
510
|
-
if (typeof data.expires === "number" && Date.now() > data.expires) {
|
|
511
|
-
await this.delete(key);
|
|
512
|
-
continue;
|
|
513
|
-
}
|
|
514
|
-
yield [key, data.value];
|
|
515
|
-
}
|
|
516
|
-
};
|
|
517
|
-
return function_.bind(this);
|
|
518
|
-
}
|
|
519
|
-
_checkIterableAdapter() {
|
|
520
|
-
return iterableAdapters.includes(this._store.opts.dialect) || iterableAdapters.some(
|
|
521
|
-
(element) => this._store.opts.url.includes(element)
|
|
522
|
-
);
|
|
523
|
-
}
|
|
524
|
-
// biome-ignore lint/suspicious/noExplicitAny: type format
|
|
525
|
-
_isValidStorageAdapter(store) {
|
|
526
|
-
return store instanceof Map || typeof store.get === "function" && typeof store.set === "function" && typeof store.delete === "function" && typeof store.clear === "function";
|
|
527
|
-
}
|
|
528
|
-
// eslint-disable-next-line @stylistic/max-len
|
|
529
|
-
async get(key, options) {
|
|
530
|
-
const store = this._store;
|
|
531
|
-
const isArray = Array.isArray(key);
|
|
532
|
-
const isDataExpired = (data) => typeof data.expires === "number" && Date.now() > data.expires;
|
|
533
|
-
if (isArray) {
|
|
534
|
-
if (options?.raw === true) {
|
|
535
|
-
return this.getMany(key, { raw: true });
|
|
536
|
-
}
|
|
537
|
-
return this.getMany(key, { raw: false });
|
|
538
|
-
}
|
|
539
|
-
this.hooks.trigger("preGet" /* PRE_GET */, { key });
|
|
540
|
-
let rawData;
|
|
541
|
-
try {
|
|
542
|
-
rawData = await store.get(key);
|
|
543
|
-
} catch (error) {
|
|
544
|
-
if (this.throwOnErrors) {
|
|
545
|
-
throw error;
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
const deserializedData = typeof rawData === "string" || this._compression ? await this.deserializeData(rawData) : rawData;
|
|
549
|
-
if (deserializedData === void 0 || deserializedData === null) {
|
|
550
|
-
this.hooks.trigger("postGet" /* POST_GET */, {
|
|
551
|
-
key,
|
|
552
|
-
value: void 0
|
|
553
|
-
});
|
|
554
|
-
this.stats.miss();
|
|
555
|
-
return void 0;
|
|
556
|
-
}
|
|
557
|
-
if (isDataExpired(deserializedData)) {
|
|
558
|
-
await this.delete(key);
|
|
559
|
-
this.hooks.trigger("postGet" /* POST_GET */, {
|
|
560
|
-
key,
|
|
561
|
-
value: void 0
|
|
562
|
-
});
|
|
563
|
-
this.stats.miss();
|
|
564
|
-
return void 0;
|
|
565
|
-
}
|
|
566
|
-
this.hooks.trigger("postGet" /* POST_GET */, {
|
|
567
|
-
key,
|
|
568
|
-
value: deserializedData
|
|
569
|
-
});
|
|
570
|
-
this.stats.hit();
|
|
571
|
-
return options?.raw ? deserializedData : deserializedData.value;
|
|
572
|
-
}
|
|
573
|
-
async getMany(keys, options) {
|
|
574
|
-
const store = this._store;
|
|
575
|
-
const isDataExpired = (data) => typeof data.expires === "number" && Date.now() > data.expires;
|
|
576
|
-
this.hooks.trigger("preGetMany" /* PRE_GET_MANY */, { keys });
|
|
577
|
-
if (store.getMany === void 0) {
|
|
578
|
-
const promises = keys.map(async (key) => {
|
|
579
|
-
const rawData2 = await store.get(key);
|
|
580
|
-
const deserializedRow = typeof rawData2 === "string" || this._compression ? await this.deserializeData(rawData2) : rawData2;
|
|
581
|
-
if (deserializedRow === void 0 || deserializedRow === null) {
|
|
582
|
-
return void 0;
|
|
583
|
-
}
|
|
584
|
-
if (isDataExpired(deserializedRow)) {
|
|
585
|
-
await this.delete(key);
|
|
586
|
-
return void 0;
|
|
587
|
-
}
|
|
588
|
-
return options?.raw ? deserializedRow : deserializedRow.value;
|
|
589
|
-
});
|
|
590
|
-
const deserializedRows = await Promise.allSettled(promises);
|
|
591
|
-
const result2 = deserializedRows.map(
|
|
592
|
-
// biome-ignore lint/suspicious/noExplicitAny: type format
|
|
593
|
-
(row) => row.value
|
|
594
|
-
);
|
|
595
|
-
this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result2);
|
|
596
|
-
if (result2.length > 0) {
|
|
597
|
-
this.stats.hit();
|
|
598
|
-
}
|
|
599
|
-
return result2;
|
|
600
|
-
}
|
|
601
|
-
const rawData = await store.getMany(keys);
|
|
602
|
-
const result = [];
|
|
603
|
-
const expiredKeys = [];
|
|
604
|
-
for (const index in rawData) {
|
|
605
|
-
let row = rawData[index];
|
|
606
|
-
if (typeof row === "string") {
|
|
607
|
-
row = await this.deserializeData(row);
|
|
608
|
-
}
|
|
609
|
-
if (row === void 0 || row === null) {
|
|
610
|
-
result.push(void 0);
|
|
611
|
-
continue;
|
|
612
|
-
}
|
|
613
|
-
if (isDataExpired(row)) {
|
|
614
|
-
expiredKeys.push(keys[index]);
|
|
615
|
-
result.push(void 0);
|
|
616
|
-
continue;
|
|
617
|
-
}
|
|
618
|
-
const value = options?.raw ? row : row.value;
|
|
619
|
-
result.push(value);
|
|
620
|
-
}
|
|
621
|
-
if (expiredKeys.length > 0) {
|
|
622
|
-
await this.deleteMany(expiredKeys);
|
|
623
|
-
}
|
|
624
|
-
this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result);
|
|
625
|
-
if (result.length > 0) {
|
|
626
|
-
this.stats.hit();
|
|
627
|
-
}
|
|
628
|
-
return result;
|
|
629
|
-
}
|
|
630
|
-
/**
|
|
631
|
-
* Get the raw value of a key. This is the replacement for setting raw to true in the get() method.
|
|
632
|
-
* @param {string} key the key to get
|
|
633
|
-
* @returns {Promise<StoredDataRaw<Value> | undefined>} will return a StoredDataRaw<Value> or undefined if the key does not exist or is expired.
|
|
634
|
-
*/
|
|
635
|
-
async getRaw(key) {
|
|
636
|
-
const store = this._store;
|
|
637
|
-
this.hooks.trigger("preGetRaw" /* PRE_GET_RAW */, { key });
|
|
638
|
-
const rawData = await store.get(key);
|
|
639
|
-
if (rawData === void 0 || rawData === null) {
|
|
640
|
-
this.hooks.trigger("postGetRaw" /* POST_GET_RAW */, {
|
|
641
|
-
key,
|
|
642
|
-
value: void 0
|
|
643
|
-
});
|
|
644
|
-
this.stats.miss();
|
|
645
|
-
return void 0;
|
|
646
|
-
}
|
|
647
|
-
const deserializedData = typeof rawData === "string" || this._compression ? await this.deserializeData(rawData) : rawData;
|
|
648
|
-
if (deserializedData !== void 0 && deserializedData.expires !== void 0 && deserializedData.expires !== null && // biome-ignore lint/style/noNonNullAssertion: need to fix
|
|
649
|
-
deserializedData.expires < Date.now()) {
|
|
650
|
-
this.hooks.trigger("postGetRaw" /* POST_GET_RAW */, {
|
|
651
|
-
key,
|
|
652
|
-
value: void 0
|
|
653
|
-
});
|
|
654
|
-
this.stats.miss();
|
|
655
|
-
await this.delete(key);
|
|
656
|
-
return void 0;
|
|
657
|
-
}
|
|
658
|
-
this.stats.hit();
|
|
659
|
-
this.hooks.trigger("postGetRaw" /* POST_GET_RAW */, {
|
|
660
|
-
key,
|
|
661
|
-
value: deserializedData
|
|
662
|
-
});
|
|
663
|
-
return deserializedData;
|
|
664
|
-
}
|
|
665
|
-
/**
|
|
666
|
-
* Get the raw values of many keys. This is the replacement for setting raw to true in the getMany() method.
|
|
667
|
-
* @param {string[]} keys the keys to get
|
|
668
|
-
* @returns {Promise<Array<StoredDataRaw<Value>>>} will return an array of StoredDataRaw<Value> or undefined if the key does not exist or is expired.
|
|
669
|
-
*/
|
|
670
|
-
async getManyRaw(keys) {
|
|
671
|
-
const store = this._store;
|
|
672
|
-
if (keys.length === 0) {
|
|
673
|
-
const result2 = Array.from({ length: keys.length }).fill(
|
|
674
|
-
void 0
|
|
675
|
-
);
|
|
676
|
-
this.stats.misses += keys.length;
|
|
677
|
-
this.hooks.trigger("postGetManyRaw" /* POST_GET_MANY_RAW */, {
|
|
678
|
-
keys,
|
|
679
|
-
values: result2
|
|
680
|
-
});
|
|
681
|
-
return result2;
|
|
682
|
-
}
|
|
683
|
-
let result = [];
|
|
684
|
-
if (store.getMany === void 0) {
|
|
685
|
-
const promises = keys.map(async (key) => {
|
|
686
|
-
const rawData = await store.get(key);
|
|
687
|
-
if (rawData !== void 0 && rawData !== null) {
|
|
688
|
-
return this.deserializeData(rawData);
|
|
689
|
-
}
|
|
690
|
-
return void 0;
|
|
691
|
-
});
|
|
692
|
-
const deserializedRows = await Promise.allSettled(promises);
|
|
693
|
-
result = deserializedRows.map(
|
|
694
|
-
(row) => (
|
|
695
|
-
// biome-ignore lint/suspicious/noExplicitAny: type format
|
|
696
|
-
row.value
|
|
697
|
-
)
|
|
698
|
-
);
|
|
699
|
-
} else {
|
|
700
|
-
const rawData = await store.getMany(keys);
|
|
701
|
-
for (const row of rawData) {
|
|
702
|
-
if (row !== void 0 && row !== null) {
|
|
703
|
-
result.push(await this.deserializeData(row));
|
|
704
|
-
} else {
|
|
705
|
-
result.push(void 0);
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
const expiredKeys = [];
|
|
710
|
-
const isDataExpired = (data) => typeof data.expires === "number" && Date.now() > data.expires;
|
|
711
|
-
for (const [index, row] of result.entries()) {
|
|
712
|
-
if (row !== void 0 && isDataExpired(row)) {
|
|
713
|
-
expiredKeys.push(keys[index]);
|
|
714
|
-
result[index] = void 0;
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
if (expiredKeys.length > 0) {
|
|
718
|
-
await this.deleteMany(expiredKeys);
|
|
719
|
-
}
|
|
720
|
-
this.stats.hitsOrMisses(result);
|
|
721
|
-
this.hooks.trigger("postGetManyRaw" /* POST_GET_MANY_RAW */, {
|
|
722
|
-
keys,
|
|
723
|
-
values: result
|
|
724
|
-
});
|
|
725
|
-
return result;
|
|
726
|
-
}
|
|
727
|
-
/**
|
|
728
|
-
* Set an item to the store
|
|
729
|
-
* @param {string | Array<KeyvEntry>} key the key to use. If you pass in an array of KeyvEntry it will set many items
|
|
730
|
-
* @param {Value} value the value of the key
|
|
731
|
-
* @param {number} [ttl] time to live in milliseconds
|
|
732
|
-
* @returns {boolean} if it sets then it will return a true. On failure will return false.
|
|
733
|
-
*/
|
|
734
|
-
async set(key, value, ttl) {
|
|
735
|
-
const data = { key, value, ttl };
|
|
736
|
-
this.hooks.trigger("preSet" /* PRE_SET */, data);
|
|
737
|
-
data.ttl ??= this._ttl;
|
|
738
|
-
if (data.ttl === 0) {
|
|
739
|
-
data.ttl = void 0;
|
|
740
|
-
}
|
|
741
|
-
const store = this._store;
|
|
742
|
-
const expires = typeof data.ttl === "number" ? Date.now() + data.ttl : void 0;
|
|
743
|
-
if (typeof data.value === "symbol") {
|
|
744
|
-
this.emit("error", "symbol cannot be serialized");
|
|
745
|
-
throw new Error("symbol cannot be serialized");
|
|
746
|
-
}
|
|
747
|
-
const formattedValue = { value: data.value, expires };
|
|
748
|
-
const serializedValue = await this.serializeData(formattedValue);
|
|
749
|
-
let result = true;
|
|
750
|
-
try {
|
|
751
|
-
const value2 = await store.set(data.key, serializedValue, data.ttl);
|
|
752
|
-
if (typeof value2 === "boolean") {
|
|
753
|
-
result = value2;
|
|
754
|
-
}
|
|
755
|
-
} catch (error) {
|
|
756
|
-
result = false;
|
|
757
|
-
this.emit("error", error);
|
|
758
|
-
if (this._throwOnErrors) {
|
|
759
|
-
throw error;
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
this.hooks.trigger("postSet" /* POST_SET */, {
|
|
763
|
-
key,
|
|
764
|
-
value: serializedValue,
|
|
765
|
-
ttl
|
|
766
|
-
});
|
|
767
|
-
this.stats.set();
|
|
768
|
-
return result;
|
|
769
|
-
}
|
|
770
|
-
/**
|
|
771
|
-
* Set a raw value to the store without wrapping or serialization. This is the write-side counterpart to getRaw().
|
|
772
|
-
* The value should be a DeserializedData object with { value, expires? }.
|
|
773
|
-
* @param {string} key the key to set
|
|
774
|
-
* @param {DeserializedData<Value>} value the raw value envelope to store
|
|
775
|
-
* @param {number} [ttl] time to live in milliseconds. If the raw value does not already have an expires field, it will be computed from ttl.
|
|
776
|
-
* @returns {boolean} if it sets then it will return a true. On failure will return false.
|
|
777
|
-
*/
|
|
778
|
-
async setRaw(key, value, ttl) {
|
|
779
|
-
const data = { key, value, ttl };
|
|
780
|
-
this.hooks.trigger("preSetRaw" /* PRE_SET_RAW */, data);
|
|
781
|
-
data.ttl ??= this._ttl;
|
|
782
|
-
if (data.ttl === 0) {
|
|
783
|
-
data.ttl = void 0;
|
|
784
|
-
}
|
|
785
|
-
if (data.value.expires === void 0 && typeof data.ttl === "number") {
|
|
786
|
-
data.value.expires = Date.now() + data.ttl;
|
|
787
|
-
}
|
|
788
|
-
const store = this._store;
|
|
789
|
-
let result = true;
|
|
790
|
-
try {
|
|
791
|
-
const serializedValue = await this.serializeData(data.value);
|
|
792
|
-
const storeResult = await store.set(data.key, serializedValue, data.ttl);
|
|
793
|
-
if (typeof storeResult === "boolean") {
|
|
794
|
-
result = storeResult;
|
|
795
|
-
}
|
|
796
|
-
} catch (error) {
|
|
797
|
-
result = false;
|
|
798
|
-
this.emit("error", error);
|
|
799
|
-
if (this._throwOnErrors) {
|
|
800
|
-
throw error;
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
this.hooks.trigger("postSetRaw" /* POST_SET_RAW */, {
|
|
804
|
-
key,
|
|
805
|
-
value: data.value,
|
|
806
|
-
ttl: data.ttl
|
|
807
|
-
});
|
|
808
|
-
this.stats.set();
|
|
809
|
-
return result;
|
|
810
|
-
}
|
|
811
|
-
/**
|
|
812
|
-
* Set many items to the store
|
|
813
|
-
* @param {Array<KeyvEntry>} entries the entries to set
|
|
814
|
-
* @returns {boolean[]} will return an array of booleans if it sets then it will return a true. On failure will return false.
|
|
815
|
-
*/
|
|
816
|
-
// biome-ignore lint/correctness/noUnusedVariables: type format
|
|
817
|
-
async setMany(entries) {
|
|
818
|
-
let results = [];
|
|
819
|
-
try {
|
|
820
|
-
if (this._store.setMany === void 0) {
|
|
821
|
-
const promises = [];
|
|
822
|
-
for (const entry of entries) {
|
|
823
|
-
promises.push(this.set(entry.key, entry.value, entry.ttl));
|
|
824
|
-
}
|
|
825
|
-
const promiseResults = await Promise.all(promises);
|
|
826
|
-
results = promiseResults;
|
|
827
|
-
} else {
|
|
828
|
-
const serializedEntries = await Promise.all(
|
|
829
|
-
entries.map(async ({ key, value, ttl }) => {
|
|
830
|
-
ttl ??= this._ttl;
|
|
831
|
-
if (ttl === 0) {
|
|
832
|
-
ttl = void 0;
|
|
833
|
-
}
|
|
834
|
-
const expires = typeof ttl === "number" ? Date.now() + ttl : void 0;
|
|
835
|
-
if (typeof value === "symbol") {
|
|
836
|
-
this.emit("error", "symbol cannot be serialized");
|
|
837
|
-
throw new Error("symbol cannot be serialized");
|
|
838
|
-
}
|
|
839
|
-
const formattedValue = { value, expires };
|
|
840
|
-
const serializedValue = await this.serializeData(formattedValue);
|
|
841
|
-
return { key, value: serializedValue, ttl };
|
|
842
|
-
})
|
|
843
|
-
);
|
|
844
|
-
const storeResult = await this._store.setMany(serializedEntries);
|
|
845
|
-
results = Array.isArray(storeResult) ? storeResult : entries.map(() => true);
|
|
846
|
-
}
|
|
847
|
-
} catch (error) {
|
|
848
|
-
this.emit("error", error);
|
|
849
|
-
if (this._throwOnErrors) {
|
|
850
|
-
throw error;
|
|
851
|
-
}
|
|
852
|
-
results = entries.map(() => false);
|
|
853
|
-
}
|
|
854
|
-
return results;
|
|
855
|
-
}
|
|
856
|
-
/**
|
|
857
|
-
* Set many raw values to the store without wrapping or serialization. This is the write-side counterpart to getManyRaw().
|
|
858
|
-
* Each entry's value should be a DeserializedData object with { value, expires? }.
|
|
859
|
-
* @param {Array<{key: string, value: DeserializedData<Value>, ttl?: number}>} entries the raw entries to set
|
|
860
|
-
* @returns {boolean[]} will return an array of booleans if it sets then it will return a true. On failure will return false.
|
|
861
|
-
*/
|
|
862
|
-
async setManyRaw(entries) {
|
|
863
|
-
let results = [];
|
|
864
|
-
this.hooks.trigger("preSetManyRaw" /* PRE_SET_MANY_RAW */, { entries });
|
|
865
|
-
try {
|
|
866
|
-
if (this._store.setMany === void 0) {
|
|
867
|
-
const promises = [];
|
|
868
|
-
for (const entry of entries) {
|
|
869
|
-
promises.push(this.setRaw(entry.key, entry.value, entry.ttl));
|
|
870
|
-
}
|
|
871
|
-
results = await Promise.all(promises);
|
|
872
|
-
} else {
|
|
873
|
-
const rawEntries = await Promise.all(
|
|
874
|
-
entries.map(async ({ key, value, ttl }) => {
|
|
875
|
-
ttl ??= this._ttl;
|
|
876
|
-
if (ttl === 0) {
|
|
877
|
-
ttl = void 0;
|
|
878
|
-
}
|
|
879
|
-
if (value.expires === void 0 && typeof ttl === "number") {
|
|
880
|
-
value.expires = Date.now() + ttl;
|
|
881
|
-
}
|
|
882
|
-
const serializedValue = await this.serializeData(value);
|
|
883
|
-
return { key, value: serializedValue, ttl };
|
|
884
|
-
})
|
|
885
|
-
);
|
|
886
|
-
const storeResult = await this._store.setMany(rawEntries);
|
|
887
|
-
results = Array.isArray(storeResult) ? storeResult : entries.map(() => true);
|
|
888
|
-
}
|
|
889
|
-
} catch (error) {
|
|
890
|
-
this.emit("error", error);
|
|
891
|
-
if (this._throwOnErrors) {
|
|
892
|
-
throw error;
|
|
893
|
-
}
|
|
894
|
-
results = entries.map(() => false);
|
|
895
|
-
}
|
|
896
|
-
this.hooks.trigger("postSetManyRaw" /* POST_SET_MANY_RAW */, { entries, results });
|
|
897
|
-
return results;
|
|
898
|
-
}
|
|
899
|
-
/**
|
|
900
|
-
* Delete an Entry
|
|
901
|
-
* @param {string | string[]} key the key to be deleted. if an array it will delete many items
|
|
902
|
-
* @returns {boolean} will return true if item or items are deleted. false if there is an error
|
|
903
|
-
*/
|
|
904
|
-
async delete(key) {
|
|
905
|
-
const store = this._store;
|
|
906
|
-
if (Array.isArray(key)) {
|
|
907
|
-
return this.deleteMany(key);
|
|
908
|
-
}
|
|
909
|
-
this.hooks.trigger("preDelete" /* PRE_DELETE */, { key });
|
|
910
|
-
let result = true;
|
|
911
|
-
try {
|
|
912
|
-
const value = await store.delete(key);
|
|
913
|
-
if (typeof value === "boolean") {
|
|
914
|
-
result = value;
|
|
915
|
-
}
|
|
916
|
-
} catch (error) {
|
|
917
|
-
result = false;
|
|
918
|
-
this.emit("error", error);
|
|
919
|
-
if (this._throwOnErrors) {
|
|
920
|
-
throw error;
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
|
-
this.hooks.trigger("postDelete" /* POST_DELETE */, {
|
|
924
|
-
key,
|
|
925
|
-
value: result
|
|
926
|
-
});
|
|
927
|
-
this.stats.delete();
|
|
928
|
-
return result;
|
|
929
|
-
}
|
|
930
|
-
/**
|
|
931
|
-
* Delete many items from the store
|
|
932
|
-
* @param {string[]} keys the keys to be deleted
|
|
933
|
-
* @returns {boolean} will return true if item or items are deleted. false if there is an error
|
|
934
|
-
*/
|
|
935
|
-
async deleteMany(keys) {
|
|
936
|
-
try {
|
|
937
|
-
const store = this._store;
|
|
938
|
-
this.hooks.trigger("preDelete" /* PRE_DELETE */, { key: keys });
|
|
939
|
-
if (store.deleteMany !== void 0) {
|
|
940
|
-
return await store.deleteMany(keys);
|
|
941
|
-
}
|
|
942
|
-
const promises = keys.map(async (key) => store.delete(key));
|
|
943
|
-
const results = await Promise.all(promises);
|
|
944
|
-
const returnResult = results.every(Boolean);
|
|
945
|
-
this.hooks.trigger("postDelete" /* POST_DELETE */, {
|
|
946
|
-
key: keys,
|
|
947
|
-
value: returnResult
|
|
948
|
-
});
|
|
949
|
-
return returnResult;
|
|
950
|
-
} catch (error) {
|
|
951
|
-
this.emit("error", error);
|
|
952
|
-
if (this._throwOnErrors) {
|
|
953
|
-
throw error;
|
|
954
|
-
}
|
|
955
|
-
return false;
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
/**
|
|
959
|
-
* Clear the store
|
|
960
|
-
* @returns {void}
|
|
961
|
-
*/
|
|
962
|
-
async clear() {
|
|
963
|
-
this.emit("clear");
|
|
964
|
-
const store = this._store;
|
|
965
|
-
try {
|
|
966
|
-
await store.clear();
|
|
967
|
-
} catch (error) {
|
|
968
|
-
this.emit("error", error);
|
|
969
|
-
if (this._throwOnErrors) {
|
|
970
|
-
throw error;
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
async has(key) {
|
|
975
|
-
if (Array.isArray(key)) {
|
|
976
|
-
return this.hasMany(key);
|
|
977
|
-
}
|
|
978
|
-
const store = this._store;
|
|
979
|
-
if (store.has !== void 0 && !(store instanceof Map)) {
|
|
980
|
-
return store.has(key);
|
|
981
|
-
}
|
|
982
|
-
let rawData;
|
|
983
|
-
try {
|
|
984
|
-
rawData = await store.get(key);
|
|
985
|
-
} catch (error) {
|
|
986
|
-
this.emit("error", error);
|
|
987
|
-
if (this._throwOnErrors) {
|
|
988
|
-
throw error;
|
|
989
|
-
}
|
|
990
|
-
return false;
|
|
991
|
-
}
|
|
992
|
-
if (rawData) {
|
|
993
|
-
const data = await this.deserializeData(rawData);
|
|
994
|
-
if (data) {
|
|
995
|
-
if (data.expires === void 0 || data.expires === null) {
|
|
996
|
-
return true;
|
|
997
|
-
}
|
|
998
|
-
return data.expires > Date.now();
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
return false;
|
|
1002
|
-
}
|
|
1003
|
-
/**
|
|
1004
|
-
* Check if many keys exist
|
|
1005
|
-
* @param {string[]} keys the keys to check
|
|
1006
|
-
* @returns {boolean[]} will return an array of booleans if the keys exist
|
|
1007
|
-
*/
|
|
1008
|
-
async hasMany(keys) {
|
|
1009
|
-
const store = this._store;
|
|
1010
|
-
if (store.hasMany !== void 0) {
|
|
1011
|
-
return store.hasMany(keys);
|
|
1012
|
-
}
|
|
1013
|
-
const results = [];
|
|
1014
|
-
for (const key of keys) {
|
|
1015
|
-
results.push(await this.has(key));
|
|
1016
|
-
}
|
|
1017
|
-
return results;
|
|
1018
|
-
}
|
|
1019
|
-
/**
|
|
1020
|
-
* Will disconnect the store. This is only available if the store has a disconnect method
|
|
1021
|
-
* @returns {Promise<void>}
|
|
1022
|
-
*/
|
|
1023
|
-
async disconnect() {
|
|
1024
|
-
const store = this._store;
|
|
1025
|
-
this.emit("disconnect");
|
|
1026
|
-
if (typeof store.disconnect === "function") {
|
|
1027
|
-
return store.disconnect();
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
// biome-ignore lint/suspicious/noExplicitAny: type format
|
|
1031
|
-
emit(event, ...arguments_) {
|
|
1032
|
-
if (event === "error" && !this._emitErrors) {
|
|
1033
|
-
return;
|
|
1034
|
-
}
|
|
1035
|
-
super.emit(event, ...arguments_);
|
|
1036
|
-
}
|
|
1037
|
-
async serializeData(data) {
|
|
1038
|
-
if (!this._serialization && !this._compression) {
|
|
1039
|
-
return data;
|
|
1040
|
-
}
|
|
1041
|
-
let result = data;
|
|
1042
|
-
if (this._serialization) {
|
|
1043
|
-
result = await this._serialization.stringify(data);
|
|
1044
|
-
} else if (this._compression) {
|
|
1045
|
-
result = JSON.stringify(data);
|
|
1046
|
-
}
|
|
1047
|
-
if (this._compression?.compress) {
|
|
1048
|
-
result = await this._compression.compress(result);
|
|
1049
|
-
}
|
|
1050
|
-
return result;
|
|
1051
|
-
}
|
|
1052
|
-
async deserializeData(data) {
|
|
1053
|
-
if (data === void 0 || data === null) {
|
|
1054
|
-
return void 0;
|
|
1055
|
-
}
|
|
1056
|
-
if (!this._serialization && !this._compression) {
|
|
1057
|
-
if (typeof data === "string") {
|
|
1058
|
-
return void 0;
|
|
1059
|
-
}
|
|
1060
|
-
return data;
|
|
1061
|
-
}
|
|
1062
|
-
let result = data;
|
|
1063
|
-
if (this._compression?.decompress) {
|
|
1064
|
-
result = await this._compression.decompress(result);
|
|
1065
|
-
}
|
|
1066
|
-
if (this._serialization && typeof result === "string") {
|
|
1067
|
-
return await this._serialization.parse(result);
|
|
1068
|
-
}
|
|
1069
|
-
if (typeof result === "string") {
|
|
1070
|
-
try {
|
|
1071
|
-
return JSON.parse(result);
|
|
1072
|
-
} catch {
|
|
1073
|
-
return void 0;
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
return result;
|
|
1077
|
-
}
|
|
1078
|
-
};
|
|
1079
|
-
var index_default = Keyv;
|
|
1080
|
-
export {
|
|
1081
|
-
Keyv,
|
|
1082
|
-
KeyvHooks,
|
|
1083
|
-
KeyvJsonSerializer,
|
|
1084
|
-
index_default as default,
|
|
1085
|
-
jsonSerializer
|
|
1086
|
-
};
|
|
1087
|
-
/* v8 ignore next -- @preserve */
|