hookified 1.8.0 → 1.8.1
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 +26 -1
- package/dist/node/index.cjs +1 -393
- package/dist/node/index.js +1 -365
- package/package.json +10 -1
package/README.md
CHANGED
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
- Browser Support and Delivered via CDN
|
|
17
17
|
- Ability to throw errors in hooks
|
|
18
18
|
- Ability to pass in a logger (such as Pino) for errors
|
|
19
|
-
- No package dependencies
|
|
19
|
+
- No package dependencies and only 100KB in size
|
|
20
|
+
- Fast and Efficient with [Benchmarks](#benchmarks)
|
|
20
21
|
- Maintained on a regular basis!
|
|
21
22
|
|
|
22
23
|
# Table of Contents
|
|
@@ -48,6 +49,7 @@
|
|
|
48
49
|
- [.listenerCount(eventName?)](#listenercounteventname)
|
|
49
50
|
- [.rawListeners(eventName?)](#rawlistenerseventname)
|
|
50
51
|
- [Development and Testing](#development-and-testing)
|
|
52
|
+
- [Benchmarks](#benchmarks)
|
|
51
53
|
- [License](#license)
|
|
52
54
|
|
|
53
55
|
# Installation
|
|
@@ -809,6 +811,29 @@ npm i && npm test
|
|
|
809
811
|
|
|
810
812
|
To contribute follow the [Contributing Guidelines](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md).
|
|
811
813
|
|
|
814
|
+
# Benchmarks
|
|
815
|
+
|
|
816
|
+
We are doing very simple benchmarking to see how this compares to other libraries using `tinybench`. This is not a full benchmark but just a simple way to see how it performs. Our goal is to be as close or better than the other libraries including native (EventEmitter).
|
|
817
|
+
|
|
818
|
+
## Hooks
|
|
819
|
+
| name | summary | ops/sec | time/op | margin | samples |
|
|
820
|
+
|-------------------|:---------:|----------:|----------:|:--------:|----------:|
|
|
821
|
+
| Hookified 1.8.0 | 🥇 | 4M | 306ns | ±2.46% | 3M |
|
|
822
|
+
| Hookable ^5.5.3 | -71% | 1M | 1µs | ±2.93% | 826K |
|
|
823
|
+
|
|
824
|
+
## Emits
|
|
825
|
+
|
|
826
|
+
This shows how close the native `EventEmitter` is to `hookified` and `eventemitter3`. We are using the same test as above but just emitting events. It is not a fair comparison but it is interesting to see how close they are.
|
|
827
|
+
|
|
828
|
+
| name | summary | ops/sec | time/op | margin | samples |
|
|
829
|
+
|-------------------------|:---------:|----------:|----------:|:--------:|----------:|
|
|
830
|
+
| Hookified 1.8.0 | 🥇 | 10M | 112ns | ±1.13% | 9M |
|
|
831
|
+
| EventEmitter3 5.0.1 | -1.3% | 10M | 114ns | ±1.84% | 9M |
|
|
832
|
+
| EventEmitter v22.12.0 | -1.5% | 9M | 114ns | ±1.18% | 9M |
|
|
833
|
+
| Emittery 1.1.0 | -92% | 785K | 1µs | ±0.45% | 761K |
|
|
834
|
+
|
|
835
|
+
_Note: the `EventEmitter` version is Nodejs versioning._
|
|
836
|
+
|
|
812
837
|
# License
|
|
813
838
|
|
|
814
839
|
[MIT & © Jared Wray](LICENSE)
|
package/dist/node/index.cjs
CHANGED
|
@@ -1,393 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
Eventified: () => Eventified,
|
|
24
|
-
Hookified: () => Hookified
|
|
25
|
-
});
|
|
26
|
-
module.exports = __toCommonJS(index_exports);
|
|
27
|
-
|
|
28
|
-
// src/eventified.ts
|
|
29
|
-
var Eventified = class {
|
|
30
|
-
_eventListeners;
|
|
31
|
-
_maxListeners;
|
|
32
|
-
_logger;
|
|
33
|
-
constructor(options) {
|
|
34
|
-
this._eventListeners = /* @__PURE__ */ new Map();
|
|
35
|
-
this._maxListeners = 100;
|
|
36
|
-
this._logger = options?.logger;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Adds a handler function for a specific event that will run only once
|
|
40
|
-
* @param {string | symbol} eventName
|
|
41
|
-
* @param {EventListener} listener
|
|
42
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
43
|
-
*/
|
|
44
|
-
once(eventName, listener) {
|
|
45
|
-
const onceListener = (...arguments_) => {
|
|
46
|
-
this.off(eventName, onceListener);
|
|
47
|
-
listener(...arguments_);
|
|
48
|
-
};
|
|
49
|
-
this.on(eventName, onceListener);
|
|
50
|
-
return this;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Gets the number of listeners for a specific event. If no event is provided, it returns the total number of listeners
|
|
54
|
-
* @param {string} eventName The event name. Not required
|
|
55
|
-
* @returns {number} The number of listeners
|
|
56
|
-
*/
|
|
57
|
-
listenerCount(eventName) {
|
|
58
|
-
if (!eventName) {
|
|
59
|
-
return this.getAllListeners().length;
|
|
60
|
-
}
|
|
61
|
-
const listeners = this._eventListeners.get(eventName);
|
|
62
|
-
return listeners ? listeners.length : 0;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Gets an array of event names
|
|
66
|
-
* @returns {Array<string | symbol>} An array of event names
|
|
67
|
-
*/
|
|
68
|
-
eventNames() {
|
|
69
|
-
return Array.from(this._eventListeners.keys());
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Gets an array of listeners for a specific event. If no event is provided, it returns all listeners
|
|
73
|
-
* @param {string} [event] (Optional) The event name
|
|
74
|
-
* @returns {EventListener[]} An array of listeners
|
|
75
|
-
*/
|
|
76
|
-
rawListeners(event) {
|
|
77
|
-
if (!event) {
|
|
78
|
-
return this.getAllListeners();
|
|
79
|
-
}
|
|
80
|
-
return this._eventListeners.get(event) ?? [];
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Prepends a listener to the beginning of the listeners array for the specified event
|
|
84
|
-
* @param {string | symbol} eventName
|
|
85
|
-
* @param {EventListener} listener
|
|
86
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
87
|
-
*/
|
|
88
|
-
prependListener(eventName, listener) {
|
|
89
|
-
const listeners = this._eventListeners.get(eventName) ?? [];
|
|
90
|
-
listeners.unshift(listener);
|
|
91
|
-
this._eventListeners.set(eventName, listeners);
|
|
92
|
-
return this;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Prepends a one-time listener to the beginning of the listeners array for the specified event
|
|
96
|
-
* @param {string | symbol} eventName
|
|
97
|
-
* @param {EventListener} listener
|
|
98
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
99
|
-
*/
|
|
100
|
-
prependOnceListener(eventName, listener) {
|
|
101
|
-
const onceListener = (...arguments_) => {
|
|
102
|
-
this.off(eventName, onceListener);
|
|
103
|
-
listener(...arguments_);
|
|
104
|
-
};
|
|
105
|
-
this.prependListener(eventName, onceListener);
|
|
106
|
-
return this;
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Gets the maximum number of listeners that can be added for a single event
|
|
110
|
-
* @returns {number} The maximum number of listeners
|
|
111
|
-
*/
|
|
112
|
-
maxListeners() {
|
|
113
|
-
return this._maxListeners;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Adds a listener for a specific event. It is an alias for the on() method
|
|
117
|
-
* @param {string | symbol} event
|
|
118
|
-
* @param {EventListener} listener
|
|
119
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
120
|
-
*/
|
|
121
|
-
addListener(event, listener) {
|
|
122
|
-
this.on(event, listener);
|
|
123
|
-
return this;
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Adds a listener for a specific event
|
|
127
|
-
* @param {string | symbol} event
|
|
128
|
-
* @param {EventListener} listener
|
|
129
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
130
|
-
*/
|
|
131
|
-
on(event, listener) {
|
|
132
|
-
if (!this._eventListeners.has(event)) {
|
|
133
|
-
this._eventListeners.set(event, []);
|
|
134
|
-
}
|
|
135
|
-
const listeners = this._eventListeners.get(event);
|
|
136
|
-
if (listeners) {
|
|
137
|
-
if (listeners.length >= this._maxListeners) {
|
|
138
|
-
console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event} listeners added. Use setMaxListeners() to increase limit.`);
|
|
139
|
-
}
|
|
140
|
-
listeners.push(listener);
|
|
141
|
-
}
|
|
142
|
-
return this;
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Removes a listener for a specific event. It is an alias for the off() method
|
|
146
|
-
* @param {string | symbol} event
|
|
147
|
-
* @param {EventListener} listener
|
|
148
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
149
|
-
*/
|
|
150
|
-
removeListener(event, listener) {
|
|
151
|
-
this.off(event, listener);
|
|
152
|
-
return this;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Removes a listener for a specific event
|
|
156
|
-
* @param {string | symbol} event
|
|
157
|
-
* @param {EventListener} listener
|
|
158
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
159
|
-
*/
|
|
160
|
-
off(event, listener) {
|
|
161
|
-
const listeners = this._eventListeners.get(event) ?? [];
|
|
162
|
-
const index = listeners.indexOf(listener);
|
|
163
|
-
if (index !== -1) {
|
|
164
|
-
listeners.splice(index, 1);
|
|
165
|
-
}
|
|
166
|
-
if (listeners.length === 0) {
|
|
167
|
-
this._eventListeners.delete(event);
|
|
168
|
-
}
|
|
169
|
-
return this;
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Calls all listeners for a specific event
|
|
173
|
-
* @param {string | symbol} event
|
|
174
|
-
* @param arguments_ The arguments to pass to the listeners
|
|
175
|
-
* @returns {boolean} Returns true if the event had listeners, false otherwise
|
|
176
|
-
*/
|
|
177
|
-
emit(event, ...arguments_) {
|
|
178
|
-
let result = false;
|
|
179
|
-
const listeners = this._eventListeners.get(event);
|
|
180
|
-
if (listeners && listeners.length > 0) {
|
|
181
|
-
for (const listener of listeners) {
|
|
182
|
-
listener(...arguments_);
|
|
183
|
-
result = true;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
return result;
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Gets all listeners for a specific event. If no event is provided, it returns all listeners
|
|
190
|
-
* @param {string} [event] (Optional) The event name
|
|
191
|
-
* @returns {EventListener[]} An array of listeners
|
|
192
|
-
*/
|
|
193
|
-
listeners(event) {
|
|
194
|
-
return this._eventListeners.get(event) ?? [];
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Removes all listeners for a specific event. If no event is provided, it removes all listeners
|
|
198
|
-
* @param {string} [event] (Optional) The event name
|
|
199
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
200
|
-
*/
|
|
201
|
-
removeAllListeners(event) {
|
|
202
|
-
if (event) {
|
|
203
|
-
this._eventListeners.delete(event);
|
|
204
|
-
} else {
|
|
205
|
-
this._eventListeners.clear();
|
|
206
|
-
}
|
|
207
|
-
return this;
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Sets the maximum number of listeners that can be added for a single event
|
|
211
|
-
* @param {number} n The maximum number of listeners
|
|
212
|
-
* @returns {void}
|
|
213
|
-
*/
|
|
214
|
-
setMaxListeners(n) {
|
|
215
|
-
this._maxListeners = n;
|
|
216
|
-
for (const listeners of this._eventListeners.values()) {
|
|
217
|
-
if (listeners.length > n) {
|
|
218
|
-
listeners.splice(n);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Gets all listeners
|
|
224
|
-
* @returns {EventListener[]} An array of listeners
|
|
225
|
-
*/
|
|
226
|
-
getAllListeners() {
|
|
227
|
-
let result = new Array();
|
|
228
|
-
for (const listeners of this._eventListeners.values()) {
|
|
229
|
-
result = result.concat(listeners);
|
|
230
|
-
}
|
|
231
|
-
return result;
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
// src/index.ts
|
|
236
|
-
var Hookified = class extends Eventified {
|
|
237
|
-
_hooks;
|
|
238
|
-
_throwHookErrors = false;
|
|
239
|
-
constructor(options) {
|
|
240
|
-
super({ logger: options?.logger });
|
|
241
|
-
this._hooks = /* @__PURE__ */ new Map();
|
|
242
|
-
if (options?.throwHookErrors !== void 0) {
|
|
243
|
-
this._throwHookErrors = options.throwHookErrors;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* Gets all hooks
|
|
248
|
-
* @returns {Map<string, Hook[]>}
|
|
249
|
-
*/
|
|
250
|
-
get hooks() {
|
|
251
|
-
return this._hooks;
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Gets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.
|
|
255
|
-
* @returns {boolean}
|
|
256
|
-
*/
|
|
257
|
-
get throwHookErrors() {
|
|
258
|
-
return this._throwHookErrors;
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Sets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.
|
|
262
|
-
* @param {boolean} value
|
|
263
|
-
*/
|
|
264
|
-
set throwHookErrors(value) {
|
|
265
|
-
this._throwHookErrors = value;
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Gets the logger
|
|
269
|
-
* @returns {Logger}
|
|
270
|
-
*/
|
|
271
|
-
get logger() {
|
|
272
|
-
return this._logger;
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* Sets the logger
|
|
276
|
-
* @param {Logger} logger
|
|
277
|
-
*/
|
|
278
|
-
set logger(logger) {
|
|
279
|
-
this._logger = logger;
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Adds a handler function for a specific event
|
|
283
|
-
* @param {string} event
|
|
284
|
-
* @param {Hook} handler - this can be async or sync
|
|
285
|
-
* @returns {void}
|
|
286
|
-
*/
|
|
287
|
-
onHook(event, handler) {
|
|
288
|
-
const eventHandlers = this._hooks.get(event);
|
|
289
|
-
if (eventHandlers) {
|
|
290
|
-
eventHandlers.push(handler);
|
|
291
|
-
} else {
|
|
292
|
-
this._hooks.set(event, [handler]);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Adds a handler function for a specific event that runs before all other handlers
|
|
297
|
-
* @param {string} event
|
|
298
|
-
* @param {Hook} handler - this can be async or sync
|
|
299
|
-
* @returns {void}
|
|
300
|
-
*/
|
|
301
|
-
prependHook(event, handler) {
|
|
302
|
-
const eventHandlers = this._hooks.get(event);
|
|
303
|
-
if (eventHandlers) {
|
|
304
|
-
eventHandlers.unshift(handler);
|
|
305
|
-
} else {
|
|
306
|
-
this._hooks.set(event, [handler]);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Adds a handler that only executes once for a specific event before all other handlers
|
|
311
|
-
* @param event
|
|
312
|
-
* @param handler
|
|
313
|
-
*/
|
|
314
|
-
prependOnceHook(event, handler) {
|
|
315
|
-
const hook = async (...arguments_) => {
|
|
316
|
-
this.removeHook(event, hook);
|
|
317
|
-
return handler(...arguments_);
|
|
318
|
-
};
|
|
319
|
-
this.prependHook(event, hook);
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* Adds a handler that only executes once for a specific event
|
|
323
|
-
* @param event
|
|
324
|
-
* @param handler
|
|
325
|
-
*/
|
|
326
|
-
onceHook(event, handler) {
|
|
327
|
-
const hook = async (...arguments_) => {
|
|
328
|
-
this.removeHook(event, hook);
|
|
329
|
-
return handler(...arguments_);
|
|
330
|
-
};
|
|
331
|
-
this.onHook(event, hook);
|
|
332
|
-
}
|
|
333
|
-
/**
|
|
334
|
-
* Removes a handler function for a specific event
|
|
335
|
-
* @param {string} event
|
|
336
|
-
* @param {Hook} handler
|
|
337
|
-
* @returns {void}
|
|
338
|
-
*/
|
|
339
|
-
removeHook(event, handler) {
|
|
340
|
-
const eventHandlers = this._hooks.get(event);
|
|
341
|
-
if (eventHandlers) {
|
|
342
|
-
const index = eventHandlers.indexOf(handler);
|
|
343
|
-
if (index !== -1) {
|
|
344
|
-
eventHandlers.splice(index, 1);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* Calls all handlers for a specific event
|
|
350
|
-
* @param {string} event
|
|
351
|
-
* @param {T[]} arguments_
|
|
352
|
-
* @returns {Promise<void>}
|
|
353
|
-
*/
|
|
354
|
-
async hook(event, ...arguments_) {
|
|
355
|
-
const eventHandlers = this._hooks.get(event);
|
|
356
|
-
if (eventHandlers) {
|
|
357
|
-
for (const handler of eventHandlers) {
|
|
358
|
-
try {
|
|
359
|
-
await handler(...arguments_);
|
|
360
|
-
} catch (error) {
|
|
361
|
-
const message = `${event}: ${error.message}`;
|
|
362
|
-
this.emit("error", new Error(message));
|
|
363
|
-
if (this._logger) {
|
|
364
|
-
this._logger.error(message);
|
|
365
|
-
}
|
|
366
|
-
if (this._throwHookErrors) {
|
|
367
|
-
throw new Error(message);
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
/**
|
|
374
|
-
* Gets all hooks for a specific event
|
|
375
|
-
* @param {string} event
|
|
376
|
-
* @returns {Hook[]}
|
|
377
|
-
*/
|
|
378
|
-
getHooks(event) {
|
|
379
|
-
return this._hooks.get(event);
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* Removes all hooks
|
|
383
|
-
* @returns {void}
|
|
384
|
-
*/
|
|
385
|
-
clearHooks() {
|
|
386
|
-
this._hooks.clear();
|
|
387
|
-
}
|
|
388
|
-
};
|
|
389
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
390
|
-
0 && (module.exports = {
|
|
391
|
-
Eventified,
|
|
392
|
-
Hookified
|
|
393
|
-
});
|
|
1
|
+
"use strict";var g=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var v=(n,e)=>{for(var t in e)g(n,t,{get:e[t],enumerable:!0})},c=(n,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of h(e))!u.call(n,r)&&r!==t&&g(n,r,{get:()=>e[r],enumerable:!(s=a(e,r))||s.enumerable});return n};var p=n=>c(g({},"__esModule",{value:!0}),n);var E={};v(E,{Eventified:()=>i,Hookified:()=>m});module.exports=p(E);var i=class{_eventListeners;_maxListeners;_logger;constructor(e){this._eventListeners=new Map,this._maxListeners=100,this._logger=e?.logger}once(e,t){let s=(...r)=>{this.off(e,s),t(...r)};return this.on(e,s),this}listenerCount(e){if(!e)return this.getAllListeners().length;let t=this._eventListeners.get(e);return t?t.length:0}eventNames(){return Array.from(this._eventListeners.keys())}rawListeners(e){return e?this._eventListeners.get(e)??[]:this.getAllListeners()}prependListener(e,t){let s=this._eventListeners.get(e)??[];return s.unshift(t),this._eventListeners.set(e,s),this}prependOnceListener(e,t){let s=(...r)=>{this.off(e,s),t(...r)};return this.prependListener(e,s),this}maxListeners(){return this._maxListeners}addListener(e,t){return this.on(e,t),this}on(e,t){this._eventListeners.has(e)||this._eventListeners.set(e,[]);let s=this._eventListeners.get(e);return s&&(s.length>=this._maxListeners&&console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${s.length+1} ${e} listeners added. Use setMaxListeners() to increase limit.`),s.push(t)),this}removeListener(e,t){return this.off(e,t),this}off(e,t){let s=this._eventListeners.get(e)??[],r=s.indexOf(t);return r!==-1&&s.splice(r,1),s.length===0&&this._eventListeners.delete(e),this}emit(e,...t){let s=!1,r=this._eventListeners.get(e);if(r&&r.length>0)for(let o of r)o(...t),s=!0;return s}listeners(e){return this._eventListeners.get(e)??[]}removeAllListeners(e){return e?this._eventListeners.delete(e):this._eventListeners.clear(),this}setMaxListeners(e){this._maxListeners=e;for(let t of this._eventListeners.values())t.length>e&&t.splice(e)}getAllListeners(){let e=new Array;for(let t of this._eventListeners.values())e=e.concat(t);return e}};var m=class extends i{_hooks;_throwHookErrors=!1;constructor(e){super({logger:e?.logger}),this._hooks=new Map,e?.throwHookErrors!==void 0&&(this._throwHookErrors=e.throwHookErrors)}get hooks(){return this._hooks}get throwHookErrors(){return this._throwHookErrors}set throwHookErrors(e){this._throwHookErrors=e}get logger(){return this._logger}set logger(e){this._logger=e}onHook(e,t){let s=this._hooks.get(e);s?s.push(t):this._hooks.set(e,[t])}prependHook(e,t){let s=this._hooks.get(e);s?s.unshift(t):this._hooks.set(e,[t])}prependOnceHook(e,t){let s=async(...r)=>(this.removeHook(e,s),t(...r));this.prependHook(e,s)}onceHook(e,t){let s=async(...r)=>(this.removeHook(e,s),t(...r));this.onHook(e,s)}removeHook(e,t){let s=this._hooks.get(e);if(s){let r=s.indexOf(t);r!==-1&&s.splice(r,1)}}async hook(e,...t){let s=this._hooks.get(e);if(s)for(let r of s)try{await r(...t)}catch(o){let l=`${e}: ${o.message}`;if(this.emit("error",new Error(l)),this._logger&&this._logger.error(l),this._throwHookErrors)throw new Error(l)}}getHooks(e){return this._hooks.get(e)}clearHooks(){this._hooks.clear()}};0&&(module.exports={Eventified,Hookified});
|
package/dist/node/index.js
CHANGED
|
@@ -1,365 +1 @@
|
|
|
1
|
-
|
|
2
|
-
var Eventified = class {
|
|
3
|
-
_eventListeners;
|
|
4
|
-
_maxListeners;
|
|
5
|
-
_logger;
|
|
6
|
-
constructor(options) {
|
|
7
|
-
this._eventListeners = /* @__PURE__ */ new Map();
|
|
8
|
-
this._maxListeners = 100;
|
|
9
|
-
this._logger = options?.logger;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Adds a handler function for a specific event that will run only once
|
|
13
|
-
* @param {string | symbol} eventName
|
|
14
|
-
* @param {EventListener} listener
|
|
15
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
16
|
-
*/
|
|
17
|
-
once(eventName, listener) {
|
|
18
|
-
const onceListener = (...arguments_) => {
|
|
19
|
-
this.off(eventName, onceListener);
|
|
20
|
-
listener(...arguments_);
|
|
21
|
-
};
|
|
22
|
-
this.on(eventName, onceListener);
|
|
23
|
-
return this;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Gets the number of listeners for a specific event. If no event is provided, it returns the total number of listeners
|
|
27
|
-
* @param {string} eventName The event name. Not required
|
|
28
|
-
* @returns {number} The number of listeners
|
|
29
|
-
*/
|
|
30
|
-
listenerCount(eventName) {
|
|
31
|
-
if (!eventName) {
|
|
32
|
-
return this.getAllListeners().length;
|
|
33
|
-
}
|
|
34
|
-
const listeners = this._eventListeners.get(eventName);
|
|
35
|
-
return listeners ? listeners.length : 0;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Gets an array of event names
|
|
39
|
-
* @returns {Array<string | symbol>} An array of event names
|
|
40
|
-
*/
|
|
41
|
-
eventNames() {
|
|
42
|
-
return Array.from(this._eventListeners.keys());
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Gets an array of listeners for a specific event. If no event is provided, it returns all listeners
|
|
46
|
-
* @param {string} [event] (Optional) The event name
|
|
47
|
-
* @returns {EventListener[]} An array of listeners
|
|
48
|
-
*/
|
|
49
|
-
rawListeners(event) {
|
|
50
|
-
if (!event) {
|
|
51
|
-
return this.getAllListeners();
|
|
52
|
-
}
|
|
53
|
-
return this._eventListeners.get(event) ?? [];
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Prepends a listener to the beginning of the listeners array for the specified event
|
|
57
|
-
* @param {string | symbol} eventName
|
|
58
|
-
* @param {EventListener} listener
|
|
59
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
60
|
-
*/
|
|
61
|
-
prependListener(eventName, listener) {
|
|
62
|
-
const listeners = this._eventListeners.get(eventName) ?? [];
|
|
63
|
-
listeners.unshift(listener);
|
|
64
|
-
this._eventListeners.set(eventName, listeners);
|
|
65
|
-
return this;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Prepends a one-time listener to the beginning of the listeners array for the specified event
|
|
69
|
-
* @param {string | symbol} eventName
|
|
70
|
-
* @param {EventListener} listener
|
|
71
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
72
|
-
*/
|
|
73
|
-
prependOnceListener(eventName, listener) {
|
|
74
|
-
const onceListener = (...arguments_) => {
|
|
75
|
-
this.off(eventName, onceListener);
|
|
76
|
-
listener(...arguments_);
|
|
77
|
-
};
|
|
78
|
-
this.prependListener(eventName, onceListener);
|
|
79
|
-
return this;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Gets the maximum number of listeners that can be added for a single event
|
|
83
|
-
* @returns {number} The maximum number of listeners
|
|
84
|
-
*/
|
|
85
|
-
maxListeners() {
|
|
86
|
-
return this._maxListeners;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Adds a listener for a specific event. It is an alias for the on() method
|
|
90
|
-
* @param {string | symbol} event
|
|
91
|
-
* @param {EventListener} listener
|
|
92
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
93
|
-
*/
|
|
94
|
-
addListener(event, listener) {
|
|
95
|
-
this.on(event, listener);
|
|
96
|
-
return this;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Adds a listener for a specific event
|
|
100
|
-
* @param {string | symbol} event
|
|
101
|
-
* @param {EventListener} listener
|
|
102
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
103
|
-
*/
|
|
104
|
-
on(event, listener) {
|
|
105
|
-
if (!this._eventListeners.has(event)) {
|
|
106
|
-
this._eventListeners.set(event, []);
|
|
107
|
-
}
|
|
108
|
-
const listeners = this._eventListeners.get(event);
|
|
109
|
-
if (listeners) {
|
|
110
|
-
if (listeners.length >= this._maxListeners) {
|
|
111
|
-
console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event} listeners added. Use setMaxListeners() to increase limit.`);
|
|
112
|
-
}
|
|
113
|
-
listeners.push(listener);
|
|
114
|
-
}
|
|
115
|
-
return this;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Removes a listener for a specific event. It is an alias for the off() method
|
|
119
|
-
* @param {string | symbol} event
|
|
120
|
-
* @param {EventListener} listener
|
|
121
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
122
|
-
*/
|
|
123
|
-
removeListener(event, listener) {
|
|
124
|
-
this.off(event, listener);
|
|
125
|
-
return this;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Removes a listener for a specific event
|
|
129
|
-
* @param {string | symbol} event
|
|
130
|
-
* @param {EventListener} listener
|
|
131
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
132
|
-
*/
|
|
133
|
-
off(event, listener) {
|
|
134
|
-
const listeners = this._eventListeners.get(event) ?? [];
|
|
135
|
-
const index = listeners.indexOf(listener);
|
|
136
|
-
if (index !== -1) {
|
|
137
|
-
listeners.splice(index, 1);
|
|
138
|
-
}
|
|
139
|
-
if (listeners.length === 0) {
|
|
140
|
-
this._eventListeners.delete(event);
|
|
141
|
-
}
|
|
142
|
-
return this;
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Calls all listeners for a specific event
|
|
146
|
-
* @param {string | symbol} event
|
|
147
|
-
* @param arguments_ The arguments to pass to the listeners
|
|
148
|
-
* @returns {boolean} Returns true if the event had listeners, false otherwise
|
|
149
|
-
*/
|
|
150
|
-
emit(event, ...arguments_) {
|
|
151
|
-
let result = false;
|
|
152
|
-
const listeners = this._eventListeners.get(event);
|
|
153
|
-
if (listeners && listeners.length > 0) {
|
|
154
|
-
for (const listener of listeners) {
|
|
155
|
-
listener(...arguments_);
|
|
156
|
-
result = true;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return result;
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Gets all listeners for a specific event. If no event is provided, it returns all listeners
|
|
163
|
-
* @param {string} [event] (Optional) The event name
|
|
164
|
-
* @returns {EventListener[]} An array of listeners
|
|
165
|
-
*/
|
|
166
|
-
listeners(event) {
|
|
167
|
-
return this._eventListeners.get(event) ?? [];
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Removes all listeners for a specific event. If no event is provided, it removes all listeners
|
|
171
|
-
* @param {string} [event] (Optional) The event name
|
|
172
|
-
* @returns {IEventEmitter} returns the instance of the class for chaining
|
|
173
|
-
*/
|
|
174
|
-
removeAllListeners(event) {
|
|
175
|
-
if (event) {
|
|
176
|
-
this._eventListeners.delete(event);
|
|
177
|
-
} else {
|
|
178
|
-
this._eventListeners.clear();
|
|
179
|
-
}
|
|
180
|
-
return this;
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Sets the maximum number of listeners that can be added for a single event
|
|
184
|
-
* @param {number} n The maximum number of listeners
|
|
185
|
-
* @returns {void}
|
|
186
|
-
*/
|
|
187
|
-
setMaxListeners(n) {
|
|
188
|
-
this._maxListeners = n;
|
|
189
|
-
for (const listeners of this._eventListeners.values()) {
|
|
190
|
-
if (listeners.length > n) {
|
|
191
|
-
listeners.splice(n);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Gets all listeners
|
|
197
|
-
* @returns {EventListener[]} An array of listeners
|
|
198
|
-
*/
|
|
199
|
-
getAllListeners() {
|
|
200
|
-
let result = new Array();
|
|
201
|
-
for (const listeners of this._eventListeners.values()) {
|
|
202
|
-
result = result.concat(listeners);
|
|
203
|
-
}
|
|
204
|
-
return result;
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
// src/index.ts
|
|
209
|
-
var Hookified = class extends Eventified {
|
|
210
|
-
_hooks;
|
|
211
|
-
_throwHookErrors = false;
|
|
212
|
-
constructor(options) {
|
|
213
|
-
super({ logger: options?.logger });
|
|
214
|
-
this._hooks = /* @__PURE__ */ new Map();
|
|
215
|
-
if (options?.throwHookErrors !== void 0) {
|
|
216
|
-
this._throwHookErrors = options.throwHookErrors;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Gets all hooks
|
|
221
|
-
* @returns {Map<string, Hook[]>}
|
|
222
|
-
*/
|
|
223
|
-
get hooks() {
|
|
224
|
-
return this._hooks;
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Gets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.
|
|
228
|
-
* @returns {boolean}
|
|
229
|
-
*/
|
|
230
|
-
get throwHookErrors() {
|
|
231
|
-
return this._throwHookErrors;
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Sets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.
|
|
235
|
-
* @param {boolean} value
|
|
236
|
-
*/
|
|
237
|
-
set throwHookErrors(value) {
|
|
238
|
-
this._throwHookErrors = value;
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Gets the logger
|
|
242
|
-
* @returns {Logger}
|
|
243
|
-
*/
|
|
244
|
-
get logger() {
|
|
245
|
-
return this._logger;
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Sets the logger
|
|
249
|
-
* @param {Logger} logger
|
|
250
|
-
*/
|
|
251
|
-
set logger(logger) {
|
|
252
|
-
this._logger = logger;
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Adds a handler function for a specific event
|
|
256
|
-
* @param {string} event
|
|
257
|
-
* @param {Hook} handler - this can be async or sync
|
|
258
|
-
* @returns {void}
|
|
259
|
-
*/
|
|
260
|
-
onHook(event, handler) {
|
|
261
|
-
const eventHandlers = this._hooks.get(event);
|
|
262
|
-
if (eventHandlers) {
|
|
263
|
-
eventHandlers.push(handler);
|
|
264
|
-
} else {
|
|
265
|
-
this._hooks.set(event, [handler]);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* Adds a handler function for a specific event that runs before all other handlers
|
|
270
|
-
* @param {string} event
|
|
271
|
-
* @param {Hook} handler - this can be async or sync
|
|
272
|
-
* @returns {void}
|
|
273
|
-
*/
|
|
274
|
-
prependHook(event, handler) {
|
|
275
|
-
const eventHandlers = this._hooks.get(event);
|
|
276
|
-
if (eventHandlers) {
|
|
277
|
-
eventHandlers.unshift(handler);
|
|
278
|
-
} else {
|
|
279
|
-
this._hooks.set(event, [handler]);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Adds a handler that only executes once for a specific event before all other handlers
|
|
284
|
-
* @param event
|
|
285
|
-
* @param handler
|
|
286
|
-
*/
|
|
287
|
-
prependOnceHook(event, handler) {
|
|
288
|
-
const hook = async (...arguments_) => {
|
|
289
|
-
this.removeHook(event, hook);
|
|
290
|
-
return handler(...arguments_);
|
|
291
|
-
};
|
|
292
|
-
this.prependHook(event, hook);
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Adds a handler that only executes once for a specific event
|
|
296
|
-
* @param event
|
|
297
|
-
* @param handler
|
|
298
|
-
*/
|
|
299
|
-
onceHook(event, handler) {
|
|
300
|
-
const hook = async (...arguments_) => {
|
|
301
|
-
this.removeHook(event, hook);
|
|
302
|
-
return handler(...arguments_);
|
|
303
|
-
};
|
|
304
|
-
this.onHook(event, hook);
|
|
305
|
-
}
|
|
306
|
-
/**
|
|
307
|
-
* Removes a handler function for a specific event
|
|
308
|
-
* @param {string} event
|
|
309
|
-
* @param {Hook} handler
|
|
310
|
-
* @returns {void}
|
|
311
|
-
*/
|
|
312
|
-
removeHook(event, handler) {
|
|
313
|
-
const eventHandlers = this._hooks.get(event);
|
|
314
|
-
if (eventHandlers) {
|
|
315
|
-
const index = eventHandlers.indexOf(handler);
|
|
316
|
-
if (index !== -1) {
|
|
317
|
-
eventHandlers.splice(index, 1);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* Calls all handlers for a specific event
|
|
323
|
-
* @param {string} event
|
|
324
|
-
* @param {T[]} arguments_
|
|
325
|
-
* @returns {Promise<void>}
|
|
326
|
-
*/
|
|
327
|
-
async hook(event, ...arguments_) {
|
|
328
|
-
const eventHandlers = this._hooks.get(event);
|
|
329
|
-
if (eventHandlers) {
|
|
330
|
-
for (const handler of eventHandlers) {
|
|
331
|
-
try {
|
|
332
|
-
await handler(...arguments_);
|
|
333
|
-
} catch (error) {
|
|
334
|
-
const message = `${event}: ${error.message}`;
|
|
335
|
-
this.emit("error", new Error(message));
|
|
336
|
-
if (this._logger) {
|
|
337
|
-
this._logger.error(message);
|
|
338
|
-
}
|
|
339
|
-
if (this._throwHookErrors) {
|
|
340
|
-
throw new Error(message);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
/**
|
|
347
|
-
* Gets all hooks for a specific event
|
|
348
|
-
* @param {string} event
|
|
349
|
-
* @returns {Hook[]}
|
|
350
|
-
*/
|
|
351
|
-
getHooks(event) {
|
|
352
|
-
return this._hooks.get(event);
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Removes all hooks
|
|
356
|
-
* @returns {void}
|
|
357
|
-
*/
|
|
358
|
-
clearHooks() {
|
|
359
|
-
this._hooks.clear();
|
|
360
|
-
}
|
|
361
|
-
};
|
|
362
|
-
export {
|
|
363
|
-
Eventified,
|
|
364
|
-
Hookified
|
|
365
|
-
};
|
|
1
|
+
var n=class{_eventListeners;_maxListeners;_logger;constructor(e){this._eventListeners=new Map,this._maxListeners=100,this._logger=e?.logger}once(e,s){let t=(...r)=>{this.off(e,t),s(...r)};return this.on(e,t),this}listenerCount(e){if(!e)return this.getAllListeners().length;let s=this._eventListeners.get(e);return s?s.length:0}eventNames(){return Array.from(this._eventListeners.keys())}rawListeners(e){return e?this._eventListeners.get(e)??[]:this.getAllListeners()}prependListener(e,s){let t=this._eventListeners.get(e)??[];return t.unshift(s),this._eventListeners.set(e,t),this}prependOnceListener(e,s){let t=(...r)=>{this.off(e,t),s(...r)};return this.prependListener(e,t),this}maxListeners(){return this._maxListeners}addListener(e,s){return this.on(e,s),this}on(e,s){this._eventListeners.has(e)||this._eventListeners.set(e,[]);let t=this._eventListeners.get(e);return t&&(t.length>=this._maxListeners&&console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${t.length+1} ${e} listeners added. Use setMaxListeners() to increase limit.`),t.push(s)),this}removeListener(e,s){return this.off(e,s),this}off(e,s){let t=this._eventListeners.get(e)??[],r=t.indexOf(s);return r!==-1&&t.splice(r,1),t.length===0&&this._eventListeners.delete(e),this}emit(e,...s){let t=!1,r=this._eventListeners.get(e);if(r&&r.length>0)for(let i of r)i(...s),t=!0;return t}listeners(e){return this._eventListeners.get(e)??[]}removeAllListeners(e){return e?this._eventListeners.delete(e):this._eventListeners.clear(),this}setMaxListeners(e){this._maxListeners=e;for(let s of this._eventListeners.values())s.length>e&&s.splice(e)}getAllListeners(){let e=new Array;for(let s of this._eventListeners.values())e=e.concat(s);return e}};var l=class extends n{_hooks;_throwHookErrors=!1;constructor(e){super({logger:e?.logger}),this._hooks=new Map,e?.throwHookErrors!==void 0&&(this._throwHookErrors=e.throwHookErrors)}get hooks(){return this._hooks}get throwHookErrors(){return this._throwHookErrors}set throwHookErrors(e){this._throwHookErrors=e}get logger(){return this._logger}set logger(e){this._logger=e}onHook(e,s){let t=this._hooks.get(e);t?t.push(s):this._hooks.set(e,[s])}prependHook(e,s){let t=this._hooks.get(e);t?t.unshift(s):this._hooks.set(e,[s])}prependOnceHook(e,s){let t=async(...r)=>(this.removeHook(e,t),s(...r));this.prependHook(e,t)}onceHook(e,s){let t=async(...r)=>(this.removeHook(e,t),s(...r));this.onHook(e,t)}removeHook(e,s){let t=this._hooks.get(e);if(t){let r=t.indexOf(s);r!==-1&&t.splice(r,1)}}async hook(e,...s){let t=this._hooks.get(e);if(t)for(let r of t)try{await r(...s)}catch(i){let o=`${e}: ${i.message}`;if(this.emit("error",new Error(o)),this._logger&&this._logger.error(o),this._throwHookErrors)throw new Error(o)}}getHooks(e){return this._hooks.get(e)}clearHooks(){this._hooks.clear()}};export{n as Eventified,l as Hookified};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hookified",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.1",
|
|
4
4
|
"description": "Event Emitting and Middleware Hooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/node/index.cjs",
|
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
"test:ci": "xo && vitest run --coverage",
|
|
22
22
|
"clean": "rimraf ./dist ./coverage ./site/dist",
|
|
23
23
|
"build": "rimraf ./dist && tsup",
|
|
24
|
+
"benchmark": "pnpm benchmark:hooks && pnpm benchmark:emit",
|
|
25
|
+
"benchmark:hooks": "pnpm tsx benchmark/hook.ts",
|
|
26
|
+
"benchmark:emit": "pnpm tsx benchmark/emit.ts",
|
|
24
27
|
"website:build": "docula build",
|
|
25
28
|
"website:serve": "docula serve",
|
|
26
29
|
"prepare": "npm run build"
|
|
@@ -57,11 +60,17 @@
|
|
|
57
60
|
},
|
|
58
61
|
"homepage": "https://github.com/jaredwray/hookified#readme",
|
|
59
62
|
"devDependencies": {
|
|
63
|
+
"@monstermann/tinybench-pretty-printer": "^0.0.0",
|
|
60
64
|
"@vitest/coverage-v8": "^3.0.8",
|
|
61
65
|
"docula": "^0.10.1",
|
|
66
|
+
"emittery": "^1.1.0",
|
|
67
|
+
"eventemitter3": "^5.0.1",
|
|
68
|
+
"hookable": "^5.5.3",
|
|
62
69
|
"pino": "^9.6.0",
|
|
63
70
|
"rimraf": "^6.0.1",
|
|
71
|
+
"tinybench": "^3.1.1",
|
|
64
72
|
"tsup": "^8.4.0",
|
|
73
|
+
"tsx": "^4.19.3",
|
|
65
74
|
"typescript": "^5.8.2",
|
|
66
75
|
"vitest": "^3.0.8",
|
|
67
76
|
"xo": "^0.60.0"
|