keyv 5.0.0 → 5.0.2
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 +3 -3
- package/dist/index.cjs +455 -0
- package/dist/{esm/index.d.ts → index.d.cts} +53 -14
- package/dist/{cjs/index.d.ts → index.d.ts} +53 -14
- package/dist/index.js +429 -0
- package/package.json +12 -9
- package/dist/cjs/event-manager.d.ts +0 -16
- package/dist/cjs/event-manager.js +0 -95
- package/dist/cjs/event-manager.js.map +0 -1
- package/dist/cjs/hooks-manager.d.ts +0 -11
- package/dist/cjs/hooks-manager.js +0 -55
- package/dist/cjs/hooks-manager.js.map +0 -1
- package/dist/cjs/index.js +0 -267
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/stats-manager.d.ts +0 -16
- package/dist/cjs/stats-manager.js +0 -51
- package/dist/cjs/stats-manager.js.map +0 -1
- package/dist/esm/event-manager.d.ts +0 -16
- package/dist/esm/event-manager.js +0 -93
- package/dist/esm/event-manager.js.map +0 -1
- package/dist/esm/hooks-manager.d.ts +0 -11
- package/dist/esm/hooks-manager.js +0 -50
- package/dist/esm/hooks-manager.js.map +0 -1
- package/dist/esm/index.js +0 -261
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/stats-manager.d.ts +0 -16
- package/dist/esm/stats-manager.js +0 -46
- package/dist/esm/stats-manager.js.map +0 -1
package/dist/index.js
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { defaultSerialize, defaultDeserialize } from "@keyv/serialize";
|
|
3
|
+
|
|
4
|
+
// src/event-manager.ts
|
|
5
|
+
var EventManager = class {
|
|
6
|
+
_eventListeners;
|
|
7
|
+
_maxListeners;
|
|
8
|
+
constructor() {
|
|
9
|
+
this._eventListeners = /* @__PURE__ */ new Map();
|
|
10
|
+
this._maxListeners = 100;
|
|
11
|
+
}
|
|
12
|
+
maxListeners() {
|
|
13
|
+
return this._maxListeners;
|
|
14
|
+
}
|
|
15
|
+
// Add an event listener
|
|
16
|
+
addListener(event, listener) {
|
|
17
|
+
this.on(event, listener);
|
|
18
|
+
}
|
|
19
|
+
on(event, listener) {
|
|
20
|
+
if (!this._eventListeners.has(event)) {
|
|
21
|
+
this._eventListeners.set(event, []);
|
|
22
|
+
}
|
|
23
|
+
const listeners = this._eventListeners.get(event);
|
|
24
|
+
if (listeners) {
|
|
25
|
+
if (listeners.length >= this._maxListeners) {
|
|
26
|
+
console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event} listeners added. Use setMaxListeners() to increase limit.`);
|
|
27
|
+
}
|
|
28
|
+
listeners.push(listener);
|
|
29
|
+
}
|
|
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
|
+
// Emit an event
|
|
46
|
+
emit(event, ...arguments_) {
|
|
47
|
+
const listeners = this._eventListeners.get(event);
|
|
48
|
+
if (listeners && listeners.length > 0) {
|
|
49
|
+
for (const listener of listeners) {
|
|
50
|
+
listener(...arguments_);
|
|
51
|
+
}
|
|
52
|
+
} else if (event === "error") {
|
|
53
|
+
if (arguments_[0] instanceof Error) {
|
|
54
|
+
throw arguments_[0];
|
|
55
|
+
} else {
|
|
56
|
+
const error = new CustomError(arguments_[0]);
|
|
57
|
+
error.context = arguments_[0];
|
|
58
|
+
throw error;
|
|
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 CustomError = class _CustomError extends Error {
|
|
80
|
+
context;
|
|
81
|
+
constructor(message, context) {
|
|
82
|
+
super(message);
|
|
83
|
+
this.context = context;
|
|
84
|
+
if (Error.captureStackTrace) {
|
|
85
|
+
Error.captureStackTrace(this, _CustomError);
|
|
86
|
+
}
|
|
87
|
+
this.name = this.constructor.name;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var event_manager_default = EventManager;
|
|
91
|
+
|
|
92
|
+
// src/hooks-manager.ts
|
|
93
|
+
var HooksManager = class extends event_manager_default {
|
|
94
|
+
_hookHandlers;
|
|
95
|
+
constructor() {
|
|
96
|
+
super();
|
|
97
|
+
this._hookHandlers = /* @__PURE__ */ new Map();
|
|
98
|
+
}
|
|
99
|
+
// Adds a handler function for a specific event
|
|
100
|
+
addHandler(event, handler) {
|
|
101
|
+
const eventHandlers = this._hookHandlers.get(event);
|
|
102
|
+
if (eventHandlers) {
|
|
103
|
+
eventHandlers.push(handler);
|
|
104
|
+
} else {
|
|
105
|
+
this._hookHandlers.set(event, [handler]);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Removes a specific handler function for a specific event
|
|
109
|
+
removeHandler(event, handler) {
|
|
110
|
+
const eventHandlers = this._hookHandlers.get(event);
|
|
111
|
+
if (eventHandlers) {
|
|
112
|
+
const index = eventHandlers.indexOf(handler);
|
|
113
|
+
if (index !== -1) {
|
|
114
|
+
eventHandlers.splice(index, 1);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Triggers all handlers for a specific event with provided data
|
|
119
|
+
trigger(event, data) {
|
|
120
|
+
const eventHandlers = this._hookHandlers.get(event);
|
|
121
|
+
if (eventHandlers) {
|
|
122
|
+
for (const handler of eventHandlers) {
|
|
123
|
+
try {
|
|
124
|
+
handler(data);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
this.emit("error", new Error(`Error in hook handler for event "${event}": ${error.message}`));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Provides read-only access to the current handlers
|
|
132
|
+
get handlers() {
|
|
133
|
+
return new Map(this._hookHandlers);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
var hooks_manager_default = HooksManager;
|
|
137
|
+
|
|
138
|
+
// src/stats-manager.ts
|
|
139
|
+
var StatsManager = class extends event_manager_default {
|
|
140
|
+
enabled = true;
|
|
141
|
+
hits = 0;
|
|
142
|
+
misses = 0;
|
|
143
|
+
sets = 0;
|
|
144
|
+
deletes = 0;
|
|
145
|
+
errors = 0;
|
|
146
|
+
constructor(enabled) {
|
|
147
|
+
super();
|
|
148
|
+
if (enabled !== void 0) {
|
|
149
|
+
this.enabled = enabled;
|
|
150
|
+
}
|
|
151
|
+
this.reset();
|
|
152
|
+
}
|
|
153
|
+
hit() {
|
|
154
|
+
if (this.enabled) {
|
|
155
|
+
this.hits++;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
miss() {
|
|
159
|
+
if (this.enabled) {
|
|
160
|
+
this.misses++;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
set() {
|
|
164
|
+
if (this.enabled) {
|
|
165
|
+
this.sets++;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
delete() {
|
|
169
|
+
if (this.enabled) {
|
|
170
|
+
this.deletes++;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
reset() {
|
|
174
|
+
this.hits = 0;
|
|
175
|
+
this.misses = 0;
|
|
176
|
+
this.sets = 0;
|
|
177
|
+
this.deletes = 0;
|
|
178
|
+
this.errors = 0;
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
var stats_manager_default = StatsManager;
|
|
182
|
+
|
|
183
|
+
// src/index.ts
|
|
184
|
+
var KeyvHooks = /* @__PURE__ */ ((KeyvHooks2) => {
|
|
185
|
+
KeyvHooks2["PRE_SET"] = "preSet";
|
|
186
|
+
KeyvHooks2["POST_SET"] = "postSet";
|
|
187
|
+
KeyvHooks2["PRE_GET"] = "preGet";
|
|
188
|
+
KeyvHooks2["POST_GET"] = "postGet";
|
|
189
|
+
KeyvHooks2["PRE_GET_MANY"] = "preGetMany";
|
|
190
|
+
KeyvHooks2["POST_GET_MANY"] = "postGetMany";
|
|
191
|
+
KeyvHooks2["PRE_DELETE"] = "preDelete";
|
|
192
|
+
KeyvHooks2["POST_DELETE"] = "postDelete";
|
|
193
|
+
return KeyvHooks2;
|
|
194
|
+
})(KeyvHooks || {});
|
|
195
|
+
var iterableAdapters = [
|
|
196
|
+
"sqlite",
|
|
197
|
+
"postgres",
|
|
198
|
+
"mysql",
|
|
199
|
+
"mongo",
|
|
200
|
+
"redis",
|
|
201
|
+
"tiered"
|
|
202
|
+
];
|
|
203
|
+
var Keyv = class extends event_manager_default {
|
|
204
|
+
opts;
|
|
205
|
+
iterator;
|
|
206
|
+
hooks = new hooks_manager_default();
|
|
207
|
+
stats = new stats_manager_default(false);
|
|
208
|
+
constructor(store, options) {
|
|
209
|
+
super();
|
|
210
|
+
options ??= {};
|
|
211
|
+
store ??= {};
|
|
212
|
+
this.opts = {
|
|
213
|
+
namespace: "keyv",
|
|
214
|
+
serialize: defaultSerialize,
|
|
215
|
+
deserialize: defaultDeserialize,
|
|
216
|
+
emitErrors: true,
|
|
217
|
+
// @ts-expect-error - Map is not a KeyvStoreAdapter
|
|
218
|
+
store: /* @__PURE__ */ new Map(),
|
|
219
|
+
...options
|
|
220
|
+
};
|
|
221
|
+
if (store && store.get) {
|
|
222
|
+
this.opts.store = store;
|
|
223
|
+
} else {
|
|
224
|
+
this.opts = {
|
|
225
|
+
...this.opts,
|
|
226
|
+
...store
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
if (this.opts.compression) {
|
|
230
|
+
const compression = this.opts.compression;
|
|
231
|
+
this.opts.serialize = compression.serialize.bind(compression);
|
|
232
|
+
this.opts.deserialize = compression.deserialize.bind(compression);
|
|
233
|
+
}
|
|
234
|
+
if (this.opts.store) {
|
|
235
|
+
if (!this._isValidStorageAdapter(this.opts.store)) {
|
|
236
|
+
throw new Error("Invalid storage adapter");
|
|
237
|
+
}
|
|
238
|
+
if (typeof this.opts.store.on === "function" && this.opts.emitErrors) {
|
|
239
|
+
this.opts.store.on("error", (error) => this.emit("error", error));
|
|
240
|
+
}
|
|
241
|
+
this.opts.store.namespace = this.opts.namespace;
|
|
242
|
+
if (typeof this.opts.store[Symbol.iterator] === "function" && this.opts.store instanceof Map) {
|
|
243
|
+
this.iterator = this.generateIterator(this.opts.store);
|
|
244
|
+
} else if ("iterator" in this.opts.store && this.opts.store.opts && this._checkIterableAdapter()) {
|
|
245
|
+
this.iterator = this.generateIterator(this.opts.store.iterator.bind(this.opts.store));
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (this.opts.stats) {
|
|
249
|
+
this.stats.enabled = this.opts.stats;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
generateIterator(iterator) {
|
|
253
|
+
const function_ = async function* () {
|
|
254
|
+
for await (const [key, raw] of typeof iterator === "function" ? iterator(this.opts.store.namespace) : iterator) {
|
|
255
|
+
const data = await this.opts.deserialize(raw);
|
|
256
|
+
if (this.opts.store.namespace && !key.includes(this.opts.store.namespace)) {
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (typeof data.expires === "number" && Date.now() > data.expires) {
|
|
260
|
+
this.delete(key);
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
yield [this._getKeyUnprefix(key), data.value];
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
return function_.bind(this);
|
|
267
|
+
}
|
|
268
|
+
_checkIterableAdapter() {
|
|
269
|
+
return iterableAdapters.includes(this.opts.store.opts.dialect) || iterableAdapters.some((element) => this.opts.store.opts.url.includes(element));
|
|
270
|
+
}
|
|
271
|
+
_getKeyPrefix(key) {
|
|
272
|
+
return `${this.opts.namespace}:${key}`;
|
|
273
|
+
}
|
|
274
|
+
_getKeyPrefixArray(keys) {
|
|
275
|
+
return keys.map((key) => `${this.opts.namespace}:${key}`);
|
|
276
|
+
}
|
|
277
|
+
_getKeyUnprefix(key) {
|
|
278
|
+
return key.split(":").splice(1).join(":");
|
|
279
|
+
}
|
|
280
|
+
_isValidStorageAdapter(store) {
|
|
281
|
+
return store instanceof Map || typeof store.get === "function" && typeof store.set === "function" && typeof store.delete === "function" && typeof store.clear === "function";
|
|
282
|
+
}
|
|
283
|
+
async get(key, options) {
|
|
284
|
+
const { store } = this.opts;
|
|
285
|
+
const isArray = Array.isArray(key);
|
|
286
|
+
const keyPrefixed = isArray ? this._getKeyPrefixArray(key) : this._getKeyPrefix(key);
|
|
287
|
+
const isDataExpired = (data) => typeof data.expires === "number" && Date.now() > data.expires;
|
|
288
|
+
if (isArray) {
|
|
289
|
+
this.hooks.trigger("preGetMany" /* PRE_GET_MANY */, { keys: keyPrefixed });
|
|
290
|
+
if (store.getMany === void 0) {
|
|
291
|
+
const promises = keyPrefixed.map(async (key2) => {
|
|
292
|
+
const rawData3 = await store.get(key2);
|
|
293
|
+
const deserializedRow = typeof rawData3 === "string" || this.opts.compression ? await this.opts.deserialize(rawData3) : rawData3;
|
|
294
|
+
if (deserializedRow === void 0 || deserializedRow === null) {
|
|
295
|
+
return void 0;
|
|
296
|
+
}
|
|
297
|
+
if (isDataExpired(deserializedRow)) {
|
|
298
|
+
await this.delete(key2);
|
|
299
|
+
return void 0;
|
|
300
|
+
}
|
|
301
|
+
return options?.raw ? deserializedRow : deserializedRow.value;
|
|
302
|
+
});
|
|
303
|
+
const deserializedRows = await Promise.allSettled(promises);
|
|
304
|
+
const result2 = deserializedRows.map((row) => row.value);
|
|
305
|
+
this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result2);
|
|
306
|
+
if (result2.length > 0) {
|
|
307
|
+
this.stats.hit();
|
|
308
|
+
}
|
|
309
|
+
return result2;
|
|
310
|
+
}
|
|
311
|
+
const rawData2 = await store.getMany(keyPrefixed);
|
|
312
|
+
const result = [];
|
|
313
|
+
for (const index in rawData2) {
|
|
314
|
+
let row = rawData2[index];
|
|
315
|
+
if (typeof row === "string") {
|
|
316
|
+
row = await this.opts.deserialize(row);
|
|
317
|
+
}
|
|
318
|
+
if (row === void 0 || row === null) {
|
|
319
|
+
result.push(void 0);
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
if (isDataExpired(row)) {
|
|
323
|
+
await this.delete(key[index]);
|
|
324
|
+
result.push(void 0);
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
const value = options?.raw ? row : row.value;
|
|
328
|
+
result.push(value);
|
|
329
|
+
}
|
|
330
|
+
this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result);
|
|
331
|
+
if (result.length > 0) {
|
|
332
|
+
this.stats.hit();
|
|
333
|
+
}
|
|
334
|
+
return result;
|
|
335
|
+
}
|
|
336
|
+
this.hooks.trigger("preGet" /* PRE_GET */, { key: keyPrefixed });
|
|
337
|
+
const rawData = await store.get(keyPrefixed);
|
|
338
|
+
const deserializedData = typeof rawData === "string" || this.opts.compression ? await this.opts.deserialize(rawData) : rawData;
|
|
339
|
+
if (deserializedData === void 0 || deserializedData === null) {
|
|
340
|
+
this.stats.miss();
|
|
341
|
+
return void 0;
|
|
342
|
+
}
|
|
343
|
+
if (isDataExpired(deserializedData)) {
|
|
344
|
+
await this.delete(key);
|
|
345
|
+
this.stats.miss();
|
|
346
|
+
return void 0;
|
|
347
|
+
}
|
|
348
|
+
this.hooks.trigger("postGet" /* POST_GET */, { key: keyPrefixed, value: deserializedData });
|
|
349
|
+
this.stats.hit();
|
|
350
|
+
return options?.raw ? deserializedData : deserializedData.value;
|
|
351
|
+
}
|
|
352
|
+
async set(key, value, ttl) {
|
|
353
|
+
this.hooks.trigger("preSet" /* PRE_SET */, { key, value, ttl });
|
|
354
|
+
const keyPrefixed = this._getKeyPrefix(key);
|
|
355
|
+
if (typeof ttl === "undefined") {
|
|
356
|
+
ttl = this.opts.ttl;
|
|
357
|
+
}
|
|
358
|
+
if (ttl === 0) {
|
|
359
|
+
ttl = void 0;
|
|
360
|
+
}
|
|
361
|
+
const { store } = this.opts;
|
|
362
|
+
const expires = typeof ttl === "number" ? Date.now() + ttl : null;
|
|
363
|
+
if (typeof value === "symbol") {
|
|
364
|
+
this.emit("error", "symbol cannot be serialized");
|
|
365
|
+
}
|
|
366
|
+
value = { value, expires };
|
|
367
|
+
value = await this.opts.serialize(value);
|
|
368
|
+
await store.set(keyPrefixed, value, ttl);
|
|
369
|
+
this.hooks.trigger("postSet" /* POST_SET */, { key: keyPrefixed, value, ttl });
|
|
370
|
+
this.stats.set();
|
|
371
|
+
return true;
|
|
372
|
+
}
|
|
373
|
+
async delete(key) {
|
|
374
|
+
const { store } = this.opts;
|
|
375
|
+
if (Array.isArray(key)) {
|
|
376
|
+
const keyPrefixed2 = this._getKeyPrefixArray(key);
|
|
377
|
+
this.hooks.trigger("preDelete" /* PRE_DELETE */, { key: keyPrefixed2 });
|
|
378
|
+
if (store.deleteMany !== void 0) {
|
|
379
|
+
return store.deleteMany(keyPrefixed2);
|
|
380
|
+
}
|
|
381
|
+
const promises = keyPrefixed2.map(async (key2) => store.delete(key2));
|
|
382
|
+
const results = await Promise.allSettled(promises);
|
|
383
|
+
const returnResult = results.every((x) => x.value === true);
|
|
384
|
+
this.hooks.trigger("postDelete" /* POST_DELETE */, returnResult);
|
|
385
|
+
return returnResult;
|
|
386
|
+
}
|
|
387
|
+
const keyPrefixed = this._getKeyPrefix(key);
|
|
388
|
+
const result = store.delete(keyPrefixed);
|
|
389
|
+
this.hooks.trigger("postDelete" /* POST_DELETE */, result);
|
|
390
|
+
this.stats.delete();
|
|
391
|
+
return result;
|
|
392
|
+
}
|
|
393
|
+
async clear() {
|
|
394
|
+
this.emit("clear");
|
|
395
|
+
const { store } = this.opts;
|
|
396
|
+
await store.clear();
|
|
397
|
+
}
|
|
398
|
+
async has(key) {
|
|
399
|
+
const keyPrefixed = this._getKeyPrefix(key);
|
|
400
|
+
const { store } = this.opts;
|
|
401
|
+
if (store.has !== void 0 && !(store instanceof Map)) {
|
|
402
|
+
return store.has(keyPrefixed);
|
|
403
|
+
}
|
|
404
|
+
const rawData = await store.get(keyPrefixed);
|
|
405
|
+
if (rawData) {
|
|
406
|
+
const data = this.opts.deserialize(rawData);
|
|
407
|
+
if (data) {
|
|
408
|
+
if (data.expires === void 0 || data.expires === null) {
|
|
409
|
+
return true;
|
|
410
|
+
}
|
|
411
|
+
return data.expires > Date.now();
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
async disconnect() {
|
|
417
|
+
const { store } = this.opts;
|
|
418
|
+
this.emit("disconnect");
|
|
419
|
+
if (typeof store.disconnect === "function") {
|
|
420
|
+
return store.disconnect();
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
var src_default = Keyv;
|
|
425
|
+
export {
|
|
426
|
+
Keyv,
|
|
427
|
+
KeyvHooks,
|
|
428
|
+
src_default as default
|
|
429
|
+
};
|
package/package.json
CHANGED
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "keyv",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.2",
|
|
4
4
|
"description": "Simple key-value storage with support for multiple backends",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.cjs",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
8
9
|
"exports": {
|
|
9
10
|
".": {
|
|
10
|
-
"require": "./dist/
|
|
11
|
-
"import": "./dist/
|
|
11
|
+
"require": "./dist/index.cjs",
|
|
12
|
+
"import": "./dist/index.js"
|
|
12
13
|
}
|
|
13
14
|
},
|
|
14
15
|
"scripts": {
|
|
15
|
-
"build": "
|
|
16
|
+
"build": "rimraf ./dist && tsup src/index.ts --format cjs,esm --dts --clean",
|
|
16
17
|
"prepare": "yarn build",
|
|
17
18
|
"test": "xo --fix && vitest run --coverage",
|
|
18
19
|
"test:ci": "xo && vitest --run --sequence.setupFiles=list",
|
|
19
|
-
"clean": "
|
|
20
|
+
"clean": "rimraf ./node_modules ./coverage ./test/testdb.sqlite ./dist"
|
|
20
21
|
},
|
|
21
22
|
"xo": {
|
|
22
23
|
"rules": {
|
|
24
|
+
"import/no-named-as-default": "off",
|
|
23
25
|
"unicorn/prefer-module": "off",
|
|
24
26
|
"unicorn/prefer-node-protocol": "off",
|
|
25
27
|
"@typescript-eslint/consistent-type-definitions": "off",
|
|
@@ -78,8 +80,9 @@
|
|
|
78
80
|
},
|
|
79
81
|
"devDependencies": {
|
|
80
82
|
"@keyv/test-suite": "*",
|
|
83
|
+
"rimraf": "^6.0.1",
|
|
81
84
|
"timekeeper": "^2.3.1",
|
|
82
|
-
"tsd": "^0.31.
|
|
85
|
+
"tsd": "^0.31.2",
|
|
83
86
|
"xo": "^0.59.3"
|
|
84
87
|
},
|
|
85
88
|
"tsd": {
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
type EventListener = (...arguments_: any[]) => void;
|
|
2
|
-
declare class EventManager {
|
|
3
|
-
_eventListeners: Map<string, EventListener[]>;
|
|
4
|
-
_maxListeners: number;
|
|
5
|
-
constructor();
|
|
6
|
-
maxListeners(): number;
|
|
7
|
-
addListener(event: string, listener: EventListener): void;
|
|
8
|
-
on(event: string, listener: EventListener): void;
|
|
9
|
-
removeListener(event: string, listener: EventListener): void;
|
|
10
|
-
off(event: string, listener: EventListener): void;
|
|
11
|
-
emit(event: string, ...arguments_: any[]): void;
|
|
12
|
-
listeners(event: string): EventListener[];
|
|
13
|
-
removeAllListeners(event?: string): void;
|
|
14
|
-
setMaxListeners(n: number): void;
|
|
15
|
-
}
|
|
16
|
-
export default EventManager;
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
class EventManager {
|
|
4
|
-
_eventListeners;
|
|
5
|
-
_maxListeners;
|
|
6
|
-
constructor() {
|
|
7
|
-
this._eventListeners = new Map();
|
|
8
|
-
this._maxListeners = 100; // Default maximum number of listeners
|
|
9
|
-
}
|
|
10
|
-
maxListeners() {
|
|
11
|
-
return this._maxListeners;
|
|
12
|
-
}
|
|
13
|
-
// Add an event listener
|
|
14
|
-
addListener(event, listener) {
|
|
15
|
-
this.on(event, listener);
|
|
16
|
-
}
|
|
17
|
-
on(event, listener) {
|
|
18
|
-
if (!this._eventListeners.has(event)) {
|
|
19
|
-
this._eventListeners.set(event, []);
|
|
20
|
-
}
|
|
21
|
-
const listeners = this._eventListeners.get(event);
|
|
22
|
-
if (listeners) {
|
|
23
|
-
if (listeners.length >= this._maxListeners) {
|
|
24
|
-
console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event} listeners added. Use setMaxListeners() to increase limit.`);
|
|
25
|
-
}
|
|
26
|
-
listeners.push(listener);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
// Remove an event listener
|
|
30
|
-
removeListener(event, listener) {
|
|
31
|
-
this.off(event, listener);
|
|
32
|
-
}
|
|
33
|
-
off(event, listener) {
|
|
34
|
-
const listeners = this._eventListeners.get(event) ?? [];
|
|
35
|
-
const index = listeners.indexOf(listener);
|
|
36
|
-
if (index > -1) {
|
|
37
|
-
listeners.splice(index, 1);
|
|
38
|
-
}
|
|
39
|
-
if (listeners.length === 0) {
|
|
40
|
-
this._eventListeners.delete(event);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
// Emit an event
|
|
44
|
-
emit(event, ...arguments_) {
|
|
45
|
-
const listeners = this._eventListeners.get(event);
|
|
46
|
-
if (listeners && listeners.length > 0) {
|
|
47
|
-
for (const listener of listeners) {
|
|
48
|
-
listener(...arguments_);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
else if (event === 'error') {
|
|
52
|
-
// If it's an 'error' event with no listeners, throw the error.
|
|
53
|
-
if (arguments_[0] instanceof Error) {
|
|
54
|
-
throw arguments_[0]; // Throws the error object if the first arg is an error
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
const error = new CustomError(arguments_[0]);
|
|
58
|
-
error.context = arguments_[0];
|
|
59
|
-
throw error;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
// Get all listeners for a specific event
|
|
64
|
-
listeners(event) {
|
|
65
|
-
return this._eventListeners.get(event) ?? [];
|
|
66
|
-
}
|
|
67
|
-
// Remove all listeners for a specific event
|
|
68
|
-
removeAllListeners(event) {
|
|
69
|
-
if (event) {
|
|
70
|
-
this._eventListeners.delete(event);
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
this._eventListeners.clear();
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
// Set the maximum number of listeners for a single event
|
|
77
|
-
setMaxListeners(n) {
|
|
78
|
-
this._maxListeners = n;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
class CustomError extends Error {
|
|
82
|
-
context;
|
|
83
|
-
constructor(message, context) {
|
|
84
|
-
super(message);
|
|
85
|
-
this.context = context;
|
|
86
|
-
// Maintains proper stack trace for where our error was thrown (only available on V8)
|
|
87
|
-
if (Error.captureStackTrace) {
|
|
88
|
-
Error.captureStackTrace(this, CustomError);
|
|
89
|
-
}
|
|
90
|
-
this.name = this.constructor.name;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
exports.default = EventManager;
|
|
94
|
-
module.exports = EventManager;
|
|
95
|
-
//# sourceMappingURL=event-manager.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"event-manager.js","sourceRoot":"","sources":["../../src/event-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import EventManager from './event-manager.js';
|
|
2
|
-
type HookHandler = (...arguments_: any[]) => void;
|
|
3
|
-
declare class HooksManager extends EventManager {
|
|
4
|
-
_hookHandlers: Map<string, HookHandler[]>;
|
|
5
|
-
constructor();
|
|
6
|
-
addHandler(event: string, handler: HookHandler): void;
|
|
7
|
-
removeHandler(event: string, handler: HookHandler): void;
|
|
8
|
-
trigger(event: string, data: any): void;
|
|
9
|
-
get handlers(): Map<string, HookHandler[]>;
|
|
10
|
-
}
|
|
11
|
-
export default HooksManager;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const event_manager_js_1 = __importDefault(require("./event-manager.js"));
|
|
7
|
-
class HooksManager extends event_manager_js_1.default {
|
|
8
|
-
_hookHandlers;
|
|
9
|
-
constructor() {
|
|
10
|
-
super();
|
|
11
|
-
this._hookHandlers = new Map();
|
|
12
|
-
}
|
|
13
|
-
// Adds a handler function for a specific event
|
|
14
|
-
addHandler(event, handler) {
|
|
15
|
-
const eventHandlers = this._hookHandlers.get(event);
|
|
16
|
-
if (eventHandlers) {
|
|
17
|
-
eventHandlers.push(handler);
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
this._hookHandlers.set(event, [handler]);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
// Removes a specific handler function for a specific event
|
|
24
|
-
removeHandler(event, handler) {
|
|
25
|
-
const eventHandlers = this._hookHandlers.get(event);
|
|
26
|
-
if (eventHandlers) {
|
|
27
|
-
const index = eventHandlers.indexOf(handler);
|
|
28
|
-
if (index !== -1) {
|
|
29
|
-
eventHandlers.splice(index, 1);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
// Triggers all handlers for a specific event with provided data
|
|
34
|
-
trigger(event, data) {
|
|
35
|
-
const eventHandlers = this._hookHandlers.get(event);
|
|
36
|
-
if (eventHandlers) {
|
|
37
|
-
for (const handler of eventHandlers) {
|
|
38
|
-
try {
|
|
39
|
-
handler(data);
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
this.emit('error', new Error(`Error in hook handler for event "${event}": ${error.message}`));
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
// Provides read-only access to the current handlers
|
|
48
|
-
get handlers() {
|
|
49
|
-
// Creating a new map to prevent external modifications to the original map
|
|
50
|
-
return new Map(this._hookHandlers);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
exports.default = HooksManager;
|
|
54
|
-
module.exports = HooksManager;
|
|
55
|
-
//# sourceMappingURL=hooks-manager.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hooks-manager.js","sourceRoot":"","sources":["../../src/hooks-manager.ts"],"names":[],"mappings":";;;;;AAAA,0EAA8C;AAI9C,MAAM,YAAa,SAAQ,0BAAY;IACtC,aAAa,CAA6B;IAE1C;QACC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,EAAE,CAAC;IAChC,CAAC;IAED,+CAA+C;IAC/C,UAAU,CAAC,KAAa,EAAE,OAAoB;QAC7C,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACpD,IAAI,aAAa,EAAE,CAAC;YACnB,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC1C,CAAC;IACF,CAAC;IAED,2DAA2D;IAC3D,aAAa,CAAC,KAAa,EAAE,OAAoB;QAChD,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACpD,IAAI,aAAa,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;gBAClB,aAAa,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAChC,CAAC;QACF,CAAC;IACF,CAAC;IAED,gEAAgE;IAChE,OAAO,CAAC,KAAa,EAAE,IAAS;QAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACpD,IAAI,aAAa,EAAE,CAAC;YACnB,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;gBACrC,IAAI,CAAC;oBACJ,OAAO,CAAC,IAAI,CAAC,CAAC;gBACf,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,oCAAoC,KAAK,MAAc,KAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBACxG,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED,oDAAoD;IACpD,IAAI,QAAQ;QACX,2EAA2E;QAC3E,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACpC,CAAC;CACD;AAED,kBAAe,YAAY,CAAC;AAC5B,MAAM,CAAC,OAAO,GAAG,YAAY,CAAC"}
|