hookified 1.12.0 → 1.12.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 +233 -24
- package/dist/browser/index.global.js +1 -1
- package/dist/browser/index.global.js.map +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/index.js.map +1 -1
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.cts +64 -0
- package/dist/node/index.d.ts +64 -0
- package/dist/node/index.js +1 -1
- package/package.json +9 -10
package/README.md
CHANGED
|
@@ -16,6 +16,9 @@
|
|
|
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
|
+
- Enforce consistent hook naming conventions with `enforceBeforeAfter`
|
|
20
|
+
- Deprecation warnings for hooks with `deprecatedHooks`
|
|
21
|
+
- Control deprecated hook execution with `allowDeprecated`
|
|
19
22
|
- No package dependencies and only 100KB in size
|
|
20
23
|
- Fast and Efficient with [Benchmarks](#benchmarks)
|
|
21
24
|
- Maintained on a regular basis!
|
|
@@ -27,6 +30,9 @@
|
|
|
27
30
|
- [API - Hooks](#api---hooks)
|
|
28
31
|
- [.throwHookErrors](#throwhookerrors)
|
|
29
32
|
- [.logger](#logger)
|
|
33
|
+
- [.enforceBeforeAfter](#enforcebeforeafter)
|
|
34
|
+
- [.deprecatedHooks](#deprecatedhooks)
|
|
35
|
+
- [.allowDeprecated](#allowdeprecated)
|
|
30
36
|
- [.onHook(eventName, handler)](#onhookeventname-handler)
|
|
31
37
|
- [.onHookEntry(hookEntry)](#onhookentryhookentry)
|
|
32
38
|
- [.addHook(eventName, handler)](#addhookeventname-handler)
|
|
@@ -57,9 +63,9 @@
|
|
|
57
63
|
- [.eventNames()](#eventnames)
|
|
58
64
|
- [.listenerCount(eventName?)](#listenercounteventname)
|
|
59
65
|
- [.rawListeners(eventName?)](#rawlistenerseventname)
|
|
60
|
-
- [Development and Contribution](#development-and-contribution)
|
|
61
66
|
- [Benchmarks](#benchmarks)
|
|
62
|
-
- [
|
|
67
|
+
- [How to Contribute](#how-to-contribute)
|
|
68
|
+
- [License and Copyright](#license-and-copyright)
|
|
63
69
|
|
|
64
70
|
# Installation
|
|
65
71
|
```bash
|
|
@@ -231,6 +237,197 @@ myClass.onHook('before:myMethod2', async () => {
|
|
|
231
237
|
await myClass.hook('before:myMethod2');
|
|
232
238
|
```
|
|
233
239
|
|
|
240
|
+
## .enforceBeforeAfter
|
|
241
|
+
|
|
242
|
+
If set to true, enforces that all hook names must start with 'before' or 'after'. This is useful for maintaining consistent hook naming conventions in your application. Default is false.
|
|
243
|
+
|
|
244
|
+
```javascript
|
|
245
|
+
import { Hookified } from 'hookified';
|
|
246
|
+
|
|
247
|
+
class MyClass extends Hookified {
|
|
248
|
+
constructor() {
|
|
249
|
+
super({ enforceBeforeAfter: true });
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const myClass = new MyClass();
|
|
254
|
+
|
|
255
|
+
console.log(myClass.enforceBeforeAfter); // true
|
|
256
|
+
|
|
257
|
+
// These will work fine
|
|
258
|
+
myClass.onHook('beforeSave', async () => {
|
|
259
|
+
console.log('Before save hook');
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
myClass.onHook('afterSave', async () => {
|
|
263
|
+
console.log('After save hook');
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
myClass.onHook('before:validation', async () => {
|
|
267
|
+
console.log('Before validation hook');
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// This will throw an error
|
|
271
|
+
try {
|
|
272
|
+
myClass.onHook('customEvent', async () => {
|
|
273
|
+
console.log('This will not work');
|
|
274
|
+
});
|
|
275
|
+
} catch (error) {
|
|
276
|
+
console.log(error.message); // Hook event "customEvent" must start with "before" or "after" when enforceBeforeAfter is enabled
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// You can also change it dynamically
|
|
280
|
+
myClass.enforceBeforeAfter = false;
|
|
281
|
+
myClass.onHook('customEvent', async () => {
|
|
282
|
+
console.log('This will work now');
|
|
283
|
+
});
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
The validation applies to all hook-related methods:
|
|
287
|
+
- `onHook()`, `addHook()`, `onHookEntry()`, `onHooks()`
|
|
288
|
+
- `prependHook()`, `onceHook()`, `prependOnceHook()`
|
|
289
|
+
- `hook()`, `callHook()`
|
|
290
|
+
- `getHooks()`, `removeHook()`, `removeHooks()`
|
|
291
|
+
|
|
292
|
+
Note: The `beforeHook()` and `afterHook()` helper methods automatically generate proper hook names and work regardless of the `enforceBeforeAfter` setting.
|
|
293
|
+
|
|
294
|
+
## .deprecatedHooks
|
|
295
|
+
|
|
296
|
+
A Map of deprecated hook names to deprecation messages. When a deprecated hook is used, a warning will be emitted via the 'warn' event and logged to the logger (if available). Default is an empty Map.
|
|
297
|
+
|
|
298
|
+
```javascript
|
|
299
|
+
import { Hookified } from 'hookified';
|
|
300
|
+
|
|
301
|
+
// Define deprecated hooks with custom messages
|
|
302
|
+
const deprecatedHooks = new Map([
|
|
303
|
+
['oldHook', 'Use newHook instead'],
|
|
304
|
+
['legacyMethod', 'This hook will be removed in v2.0'],
|
|
305
|
+
['deprecatedFeature', ''] // Empty message - will just say "deprecated"
|
|
306
|
+
]);
|
|
307
|
+
|
|
308
|
+
class MyClass extends Hookified {
|
|
309
|
+
constructor() {
|
|
310
|
+
super({ deprecatedHooks });
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const myClass = new MyClass();
|
|
315
|
+
|
|
316
|
+
console.log(myClass.deprecatedHooks); // Map with deprecated hooks
|
|
317
|
+
|
|
318
|
+
// Listen for deprecation warnings
|
|
319
|
+
myClass.on('warn', (event) => {
|
|
320
|
+
console.log(`Deprecation warning: ${event.message}`);
|
|
321
|
+
// event.hook contains the hook name
|
|
322
|
+
// event.message contains the full warning message
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
// Using a deprecated hook will emit warnings
|
|
326
|
+
myClass.onHook('oldHook', () => {
|
|
327
|
+
console.log('This hook is deprecated');
|
|
328
|
+
});
|
|
329
|
+
// Output: Hook "oldHook" is deprecated: Use newHook instead
|
|
330
|
+
|
|
331
|
+
// Using a deprecated hook with empty message
|
|
332
|
+
myClass.onHook('deprecatedFeature', () => {
|
|
333
|
+
console.log('This hook is deprecated');
|
|
334
|
+
});
|
|
335
|
+
// Output: Hook "deprecatedFeature" is deprecated
|
|
336
|
+
|
|
337
|
+
// You can also set deprecated hooks dynamically
|
|
338
|
+
myClass.deprecatedHooks.set('anotherOldHook', 'Please migrate to the new API');
|
|
339
|
+
|
|
340
|
+
// Works with logger if provided
|
|
341
|
+
import pino from 'pino';
|
|
342
|
+
const logger = pino();
|
|
343
|
+
|
|
344
|
+
const myClassWithLogger = new Hookified({
|
|
345
|
+
deprecatedHooks,
|
|
346
|
+
logger
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Deprecation warnings will be logged to logger.warn
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
The deprecation warning system applies to all hook-related methods:
|
|
353
|
+
- Registration: `onHook()`, `addHook()`, `onHookEntry()`, `onHooks()`, `prependHook()`, `onceHook()`, `prependOnceHook()`
|
|
354
|
+
- Execution: `hook()`, `callHook()`
|
|
355
|
+
- Management: `getHooks()`, `removeHook()`, `removeHooks()`
|
|
356
|
+
|
|
357
|
+
Deprecation warnings are emitted in two ways:
|
|
358
|
+
1. **Event**: A 'warn' event is emitted with `{ hook: string, message: string }`
|
|
359
|
+
2. **Logger**: Logged to `logger.warn()` if a logger is configured and has a `warn` method
|
|
360
|
+
|
|
361
|
+
## .allowDeprecated
|
|
362
|
+
|
|
363
|
+
Controls whether deprecated hooks are allowed to be registered and executed. Default is true. When set to false, deprecated hooks will still emit warnings but will be prevented from registration and execution.
|
|
364
|
+
|
|
365
|
+
```javascript
|
|
366
|
+
import { Hookified } from 'hookified';
|
|
367
|
+
|
|
368
|
+
const deprecatedHooks = new Map([
|
|
369
|
+
['oldHook', 'Use newHook instead']
|
|
370
|
+
]);
|
|
371
|
+
|
|
372
|
+
class MyClass extends Hookified {
|
|
373
|
+
constructor() {
|
|
374
|
+
super({ deprecatedHooks, allowDeprecated: false });
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const myClass = new MyClass();
|
|
379
|
+
|
|
380
|
+
console.log(myClass.allowDeprecated); // false
|
|
381
|
+
|
|
382
|
+
// Listen for deprecation warnings (still emitted even when blocked)
|
|
383
|
+
myClass.on('warn', (event) => {
|
|
384
|
+
console.log(`Warning: ${event.message}`);
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
// Try to register a deprecated hook - will emit warning but not register
|
|
388
|
+
myClass.onHook('oldHook', () => {
|
|
389
|
+
console.log('This will never execute');
|
|
390
|
+
});
|
|
391
|
+
// Output: Warning: Hook "oldHook" is deprecated: Use newHook instead
|
|
392
|
+
|
|
393
|
+
// Verify hook was not registered
|
|
394
|
+
console.log(myClass.getHooks('oldHook')); // undefined
|
|
395
|
+
|
|
396
|
+
// Try to execute a deprecated hook - will emit warning but not execute
|
|
397
|
+
await myClass.hook('oldHook');
|
|
398
|
+
// Output: Warning: Hook "oldHook" is deprecated: Use newHook instead
|
|
399
|
+
// (but no handlers execute)
|
|
400
|
+
|
|
401
|
+
// Non-deprecated hooks work normally
|
|
402
|
+
myClass.onHook('validHook', () => {
|
|
403
|
+
console.log('This works fine');
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
console.log(myClass.getHooks('validHook')); // [handler function]
|
|
407
|
+
|
|
408
|
+
// You can dynamically change the setting
|
|
409
|
+
myClass.allowDeprecated = true;
|
|
410
|
+
|
|
411
|
+
// Now deprecated hooks can be registered and executed
|
|
412
|
+
myClass.onHook('oldHook', () => {
|
|
413
|
+
console.log('Now this works');
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
console.log(myClass.getHooks('oldHook')); // [handler function]
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
**Behavior when `allowDeprecated` is false:**
|
|
420
|
+
- **Registration**: All hook registration methods (`onHook`, `addHook`, `prependHook`, etc.) will emit warnings but skip registration
|
|
421
|
+
- **Execution**: Hook execution methods (`hook`, `callHook`) will emit warnings but skip execution
|
|
422
|
+
- **Management**: Hook management methods (`getHooks`, `removeHook`) will emit warnings and return undefined/skip operations
|
|
423
|
+
- **Warnings**: Deprecation warnings are always emitted regardless of `allowDeprecated` setting
|
|
424
|
+
|
|
425
|
+
**Use cases:**
|
|
426
|
+
- **Development**: Keep `allowDeprecated: true` to maintain functionality while seeing warnings
|
|
427
|
+
- **Testing**: Set `allowDeprecated: false` to ensure no deprecated hooks are accidentally used
|
|
428
|
+
- **Migration**: Gradually disable deprecated hooks during API transitions
|
|
429
|
+
- **Production**: Disable deprecated hooks to prevent legacy code execution
|
|
430
|
+
|
|
234
431
|
## .onHook(eventName, handler)
|
|
235
432
|
|
|
236
433
|
Subscribe to a hook event.
|
|
@@ -999,7 +1196,31 @@ myClass.on('message', (message) => {
|
|
|
999
1196
|
console.log(myClass.rawListeners('message'));
|
|
1000
1197
|
```
|
|
1001
1198
|
|
|
1002
|
-
#
|
|
1199
|
+
# Benchmarks
|
|
1200
|
+
|
|
1201
|
+
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).
|
|
1202
|
+
|
|
1203
|
+
## Hooks
|
|
1204
|
+
|
|
1205
|
+
| name | summary | ops/sec | time/op | margin | samples |
|
|
1206
|
+
|-----------------------|:---------:|----------:|----------:|:--------:|----------:|
|
|
1207
|
+
| Hookified (v1.12.1) | 🥇 | 5M | 243ns | ±0.89% | 4M |
|
|
1208
|
+
| Hookable (v5.5.3) | -69% | 1M | 835ns | ±2.23% | 1M |
|
|
1209
|
+
|
|
1210
|
+
## Emits
|
|
1211
|
+
|
|
1212
|
+
This shows how on par `hookified` is to the native `EventEmitter` and popular `eventemitter3`. These are simple emitting benchmarks to see how it performs.
|
|
1213
|
+
|
|
1214
|
+
| name | summary | ops/sec | time/op | margin | samples |
|
|
1215
|
+
|---------------------------|:---------:|----------:|----------:|:--------:|----------:|
|
|
1216
|
+
| Hookified (v1.12.1) | 🥇 | 12M | 89ns | ±2.56% | 11M |
|
|
1217
|
+
| EventEmitter3 (v5.0.1) | -1.7% | 12M | 91ns | ±3.31% | 11M |
|
|
1218
|
+
| EventEmitter (v20.17.0) | -4% | 11M | 92ns | ±0.38% | 11M |
|
|
1219
|
+
| Emittery (v1.2.0) | -91% | 1M | 1µs | ±1.59% | 993K |
|
|
1220
|
+
|
|
1221
|
+
_Note: the `EventEmitter` version is Nodejs versioning._
|
|
1222
|
+
|
|
1223
|
+
# How to Contribute
|
|
1003
1224
|
|
|
1004
1225
|
Hookified is written in TypeScript and tests are written in `vitest`. To run the tests, use the following command:
|
|
1005
1226
|
|
|
@@ -1017,31 +1238,19 @@ npm install -g pnpm
|
|
|
1017
1238
|
|
|
1018
1239
|
To contribute follow the [Contributing Guidelines](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md).
|
|
1019
1240
|
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
## Hooks
|
|
1025
|
-
|
|
1026
|
-
| name | summary | ops/sec | time/op | margin | samples |
|
|
1027
|
-
|-------------------|:---------:|----------:|----------:|:--------:|----------:|
|
|
1028
|
-
| Hookified 1.8.0 | 🥇 | 4M | 299ns | ±2.42% | 3M |
|
|
1029
|
-
| Hookable 5.5.3 | -73% | 982K | 1µs | ±2.92% | 812K |
|
|
1030
|
-
|
|
1031
|
-
## Emits
|
|
1241
|
+
```bash
|
|
1242
|
+
pnpm i && pnpm test
|
|
1243
|
+
```
|
|
1032
1244
|
|
|
1033
|
-
|
|
1245
|
+
Note that we are using `pnpm` as our package manager. If you don't have it installed, you can install it globally with:
|
|
1034
1246
|
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
| EventEmitter3 5.0.1 | -1.3% | 10M | 114ns | ±1.84% | 9M |
|
|
1039
|
-
| EventEmitter v22.12.0 | -1.5% | 9M | 114ns | ±1.18% | 9M |
|
|
1040
|
-
| Emittery 1.1.0 | -92% | 785K | 1µs | ±0.45% | 761K |
|
|
1247
|
+
```bash
|
|
1248
|
+
npm install -g pnpm
|
|
1249
|
+
```
|
|
1041
1250
|
|
|
1042
|
-
|
|
1251
|
+
To contribute follow the [Contributing Guidelines](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md).
|
|
1043
1252
|
|
|
1044
|
-
# License
|
|
1253
|
+
# License and Copyright
|
|
1045
1254
|
|
|
1046
1255
|
[MIT & © Jared Wray](LICENSE)
|
|
1047
1256
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";(()=>{var
|
|
1
|
+
"use strict";(()=>{var g=Object.defineProperty;var p=(n,t,e)=>t in n?g(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var i=(n,t,e)=>p(n,typeof t!="symbol"?t+"":t,e);var a=class{constructor(t){i(this,"_eventListeners");i(this,"_maxListeners");i(this,"_logger");i(this,"_throwOnEmitError",!1);this._eventListeners=new Map,this._maxListeners=100,this._logger=t?.logger,t?.throwOnEmitError!==void 0&&(this._throwOnEmitError=t.throwOnEmitError)}get logger(){return this._logger}set logger(t){this._logger=t}get throwOnEmitError(){return this._throwOnEmitError}set throwOnEmitError(t){this._throwOnEmitError=t}once(t,e){let r=(...s)=>{this.off(t,r),e(...s)};return this.on(t,r),this}listenerCount(t){if(t===void 0)return this.getAllListeners().length;let e=this._eventListeners.get(t);return e?e.length:0}eventNames(){return[...this._eventListeners.keys()]}rawListeners(t){return t===void 0?this.getAllListeners():this._eventListeners.get(t)??[]}prependListener(t,e){let r=this._eventListeners.get(t)??[];return r.unshift(e),this._eventListeners.set(t,r),this}prependOnceListener(t,e){let r=(...s)=>{this.off(t,r),e(...s)};return this.prependListener(t,r),this}maxListeners(){return this._maxListeners}addListener(t,e){return this.on(t,e),this}on(t,e){this._eventListeners.has(t)||this._eventListeners.set(t,[]);let r=this._eventListeners.get(t);return r&&(r.length>=this._maxListeners&&console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${r.length+1} ${t} listeners added. Use setMaxListeners() to increase limit.`),r.push(e)),this}removeListener(t,e){return this.off(t,e),this}off(t,e){let r=this._eventListeners.get(t)??[],s=r.indexOf(e);return s!==-1&&r.splice(s,1),r.length===0&&this._eventListeners.delete(t),this}emit(t,...e){let r=!1,s=this._eventListeners.get(t);if(s&&s.length>0)for(let o of s)o(...e),r=!0;if(t==="error"){let o=e[0]instanceof Error?e[0]:new Error(`${e[0]}`);if(this._throwOnEmitError&&!r)throw o}return r}listeners(t){return this._eventListeners.get(t)??[]}removeAllListeners(t){return t!==void 0?this._eventListeners.delete(t):this._eventListeners.clear(),this}setMaxListeners(t){this._maxListeners=t;for(let e of this._eventListeners.values())e.length>t&&e.splice(t)}getAllListeners(){let t=[];for(let e of this._eventListeners.values())t=[...t,...e];return t}};var h=class extends a{constructor(e){super({logger:e?.logger});i(this,"_hooks");i(this,"_throwHookErrors",!1);i(this,"_enforceBeforeAfter",!1);i(this,"_deprecatedHooks");i(this,"_allowDeprecated",!0);this._hooks=new Map,this._deprecatedHooks=e?.deprecatedHooks?new Map(e.deprecatedHooks):new Map,e?.throwHookErrors!==void 0&&(this._throwHookErrors=e.throwHookErrors),e?.enforceBeforeAfter!==void 0&&(this._enforceBeforeAfter=e.enforceBeforeAfter),e?.allowDeprecated!==void 0&&(this._allowDeprecated=e.allowDeprecated)}get hooks(){return this._hooks}get throwHookErrors(){return this._throwHookErrors}set throwHookErrors(e){this._throwHookErrors=e}get enforceBeforeAfter(){return this._enforceBeforeAfter}set enforceBeforeAfter(e){this._enforceBeforeAfter=e}get deprecatedHooks(){return this._deprecatedHooks}set deprecatedHooks(e){this._deprecatedHooks=e}get allowDeprecated(){return this._allowDeprecated}set allowDeprecated(e){this._allowDeprecated=e}validateHookName(e){if(this._enforceBeforeAfter){let r=e.trim().toLocaleLowerCase();if(!r.startsWith("before")&&!r.startsWith("after"))throw new Error(`Hook event "${e}" must start with "before" or "after" when enforceBeforeAfter is enabled`)}}checkDeprecatedHook(e){if(this._deprecatedHooks.has(e)){let r=this._deprecatedHooks.get(e),s=`Hook "${e}" is deprecated${r?`: ${r}`:""}`;return this.emit("warn",{hook:e,message:s}),this.logger?.warn&&this.logger.warn(s),this._allowDeprecated}return!0}onHook(e,r){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let s=this._hooks.get(e);s?s.push(r):this._hooks.set(e,[r])}onHookEntry(e){this.onHook(e.event,e.handler)}addHook(e,r){this.onHook(e,r)}onHooks(e){for(let r of e)this.onHook(r.event,r.handler)}prependHook(e,r){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let s=this._hooks.get(e);s?s.unshift(r):this._hooks.set(e,[r])}prependOnceHook(e,r){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let s=async(...o)=>(this.removeHook(e,s),r(...o));this.prependHook(e,s)}onceHook(e,r){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let s=async(...o)=>(this.removeHook(e,s),r(...o));this.onHook(e,s)}removeHook(e,r){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let s=this._hooks.get(e);if(s){let o=s.indexOf(r);o!==-1&&s.splice(o,1)}}removeHooks(e){for(let r of e)this.removeHook(r.event,r.handler)}async hook(e,...r){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let s=this._hooks.get(e);if(s)for(let o of s)try{await o(...r)}catch(c){let l=`${e}: ${c.message}`;if(this.emit("error",new Error(l)),this.logger&&this.logger.error(l),this._throwHookErrors)throw new Error(l)}}async beforeHook(e,...r){await this.hook(`before:${e}`,...r)}async afterHook(e,...r){await this.hook(`after:${e}`,...r)}async callHook(e,...r){await this.hook(e,...r)}getHooks(e){if(this.validateHookName(e),!!this.checkDeprecatedHook(e))return this._hooks.get(e)}clearHooks(){this._hooks.clear()}};})();
|
|
2
2
|
//# sourceMappingURL=index.global.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/eventified.ts","../../src/index.ts"],"sourcesContent":["// biome-ignore-all lint/suspicious/noExplicitAny: this is for event emitter compatibility\nimport type { Logger } from \"logger.js\";\n\nexport type IEventEmitter = {\n\t/**\n\t * Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.on('data', (message) => {\n\t * console.log(message);\n\t * });\n\t */\n\ton(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Alias for `on`. Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\taddListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Registers a one-time listener for the specified event. The listener is removed after it is called once.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.once('close', () => {\n\t * console.log('The connection was closed.');\n\t * });\n\t */\n\tonce(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.off('data', myListener);\n\t */\n\toff(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Alias for `off`. Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\tremoveListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Emits the specified event, invoking all registered listeners with the provided arguments.\n\t *\n\t * @param eventName - The name (or symbol) of the event to emit.\n\t * @param args - Arguments passed to each listener.\n\t * @returns `true` if the event had listeners, `false` otherwise.\n\t *\n\t * @example\n\t * emitter.emit('data', 'Hello World');\n\t */\n\temit(eventName: string | symbol, ...arguments_: any[]): boolean;\n\n\t/**\n\t * Returns the number of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns The number of registered listeners.\n\t *\n\t * @example\n\t * const count = emitter.listenerCount('data');\n\t * console.log(count); // e.g., 2\n\t */\n\tlistenerCount(eventName: string | symbol): number;\n\n\t/**\n\t * Removes all listeners for the specified event. If no event is specified, it removes all listeners for all events.\n\t *\n\t * @param eventName - (Optional) The name (or symbol) of the event.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.removeAllListeners('data');\n\t */\n\tremoveAllListeners(eventName?: string | symbol): IEventEmitter;\n\n\t/**\n\t * Returns an array of event names for which listeners have been registered.\n\t *\n\t * @returns An array of event names (or symbols).\n\t *\n\t * @example\n\t * const events = emitter.eventNames();\n\t * console.log(events); // e.g., ['data', 'close']\n\t */\n\teventNames(): Array<string | symbol>;\n\n\t/**\n\t * Returns an array of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of listener functions.\n\t *\n\t * @example\n\t * const listeners = emitter.listeners('data');\n\t * console.log(listeners.length); // e.g., 2\n\t */\n\tlisteners(eventName: string | symbol): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Returns an array of raw listeners for the specified event. This includes listeners wrapped by internal mechanisms (e.g., once-only listeners).\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of raw listener functions.\n\t *\n\t * @example\n\t * const rawListeners = emitter.rawListeners('data');\n\t */\n\trawListeners(\n\t\teventName: string | symbol,\n\t): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Adds a listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependListener('data', (message) => {\n\t * console.log('This will run first.');\n\t * });\n\t */\n\tprependListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Adds a one-time listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependOnceListener('data', (message) => {\n\t * console.log('This will run first and only once.');\n\t * });\n\t */\n\tprependOnceListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n};\n\nexport type EventListener = (...arguments_: any[]) => void;\n\nexport type EventEmitterOptions = {\n\t/**\n\t * Logger instance for logging errors.\n\t */\n\tlogger?: Logger;\n\t/**\n\t * Whether to throw an error when emit 'error' and there are no listeners. Default is false and only emits an error event.\n\t */\n\tthrowOnEmitError?: boolean;\n};\n\nexport class Eventified implements IEventEmitter {\n\tprivate readonly _eventListeners: Map<string | symbol, EventListener[]>;\n\tprivate _maxListeners: number;\n\tprivate _logger?: Logger;\n\tprivate _throwOnEmitError = false;\n\n\tconstructor(options?: EventEmitterOptions) {\n\t\tthis._eventListeners = new Map<string | symbol, EventListener[]>();\n\t\tthis._maxListeners = 100; // Default maximum number of listeners\n\n\t\tthis._logger = options?.logger;\n\n\t\tif (options?.throwOnEmitError !== undefined) {\n\t\t\tthis._throwOnEmitError = options.throwOnEmitError;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the logger\n\t * @returns {Logger}\n\t */\n\tpublic get logger(): Logger | undefined {\n\t\treturn this._logger;\n\t}\n\n\t/**\n\t * Sets the logger\n\t * @param {Logger} logger\n\t */\n\tpublic set logger(logger: Logger | undefined) {\n\t\tthis._logger = logger;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @returns {boolean}\n\t */\n\tpublic get throwOnEmitError(): boolean {\n\t\treturn this._throwOnEmitError;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @param {boolean} value\n\t */\n\tpublic set throwOnEmitError(value: boolean) {\n\t\tthis._throwOnEmitError = value;\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that will run only once\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic once(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.on(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the number of listeners for a specific event. If no event is provided, it returns the total number of listeners\n\t * @param {string} eventName The event name. Not required\n\t * @returns {number} The number of listeners\n\t */\n\tpublic listenerCount(eventName?: string | symbol): number {\n\t\tif (eventName === undefined) {\n\t\t\treturn this.getAllListeners().length;\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(eventName);\n\t\treturn listeners ? listeners.length : 0;\n\t}\n\n\t/**\n\t * Gets an array of event names\n\t * @returns {Array<string | symbol>} An array of event names\n\t */\n\tpublic eventNames(): Array<string | symbol> {\n\t\treturn [...this._eventListeners.keys()];\n\t}\n\n\t/**\n\t * Gets an array of listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic rawListeners(event?: string | symbol): EventListener[] {\n\t\tif (event === undefined) {\n\t\t\treturn this.getAllListeners();\n\t\t}\n\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Prepends a listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic prependListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(eventName) ?? [];\n\t\tlisteners.unshift(listener);\n\t\tthis._eventListeners.set(eventName, listeners);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepends a one-time listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic prependOnceListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.prependListener(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the maximum number of listeners that can be added for a single event\n\t * @returns {number} The maximum number of listeners\n\t */\n\tpublic maxListeners(): number {\n\t\treturn this._maxListeners;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event. It is an alias for the on() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic addListener(\n\t\tevent: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tthis.on(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic on(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tif (!this._eventListeners.has(event)) {\n\t\t\tthis._eventListeners.set(event, []);\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners) {\n\t\t\tif (listeners.length >= this._maxListeners) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event as string} listeners added. Use setMaxListeners() to increase limit.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlisteners.push(listener);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event. It is an alias for the off() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeListener(event: string, listener: EventListener): IEventEmitter {\n\t\tthis.off(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic off(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(event) ?? [];\n\t\tconst index = listeners.indexOf(listener);\n\t\tif (index !== -1) {\n\t\t\tlisteners.splice(index, 1);\n\t\t}\n\n\t\tif (listeners.length === 0) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Calls all listeners for a specific event\n\t * @param {string | symbol} event\n\t * @param arguments_ The arguments to pass to the listeners\n\t * @returns {boolean} Returns true if the event had listeners, false otherwise\n\t */\n\tpublic emit(event: string | symbol, ...arguments_: any[]): boolean {\n\t\tlet result = false;\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners && listeners.length > 0) {\n\t\t\tfor (const listener of listeners) {\n\t\t\t\tlistener(...arguments_);\n\t\t\t\tresult = true;\n\t\t\t}\n\t\t}\n\n\t\tif (event === \"error\") {\n\t\t\tconst error =\n\t\t\t\targuments_[0] instanceof Error\n\t\t\t\t\t? arguments_[0]\n\t\t\t\t\t: new Error(`${arguments_[0]}`);\n\n\t\t\tif (this._throwOnEmitError && !result) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Gets all listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic listeners(event: string | symbol): EventListener[] {\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Removes all listeners for a specific event. If no event is provided, it removes all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeAllListeners(event?: string | symbol): IEventEmitter {\n\t\tif (event !== undefined) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t} else {\n\t\t\tthis._eventListeners.clear();\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the maximum number of listeners that can be added for a single event\n\t * @param {number} n The maximum number of listeners\n\t * @returns {void}\n\t */\n\tpublic setMaxListeners(n: number): void {\n\t\tthis._maxListeners = n;\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tif (listeners.length > n) {\n\t\t\t\tlisteners.splice(n);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets all listeners\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic getAllListeners(): EventListener[] {\n\t\tlet result: EventListener[] = [];\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tresult = [...result, ...listeners];\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import { type EventEmitterOptions, Eventified } from \"./eventified.js\";\n\n// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\nexport type Hook = (...arguments_: any[]) => Promise<void> | void;\n\nexport type HookEntry = {\n\t/**\n\t * The event name for the hook\n\t */\n\tevent: string;\n\t/**\n\t * The handler function for the hook\n\t */\n\thandler: Hook;\n};\n\nexport type HookifiedOptions = {\n\t/**\n\t * Whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t */\n\tthrowHookErrors?: boolean;\n} & EventEmitterOptions;\n\nexport class Hookified extends Eventified {\n\tprivate readonly _hooks: Map<string, Hook[]>;\n\tprivate _throwHookErrors = false;\n\n\tconstructor(options?: HookifiedOptions) {\n\t\tsuper({ logger: options?.logger });\n\t\tthis._hooks = new Map();\n\n\t\tif (options?.throwHookErrors !== undefined) {\n\t\t\tthis._throwHookErrors = options.throwHookErrors;\n\t\t}\n\t}\n\n\t/**\n\t * Gets all hooks\n\t * @returns {Map<string, Hook[]>}\n\t */\n\tpublic get hooks() {\n\t\treturn this._hooks;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t * @returns {boolean}\n\t */\n\tpublic get throwHookErrors() {\n\t\treturn this._throwHookErrors;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t * @param {boolean} value\n\t */\n\tpublic set throwHookErrors(value) {\n\t\tthis._throwHookErrors = value;\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tpublic onHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\teventHandlers.push(handler);\n\t\t} else {\n\t\t\tthis._hooks.set(event, [handler]);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that runs before all other handlers\n\t * @param {HookEntry} hookEntry\n\t * @returns {void}\n\t */\n\tpublic onHookEntry(hookEntry: HookEntry) {\n\t\tthis.onHook(hookEntry.event, hookEntry.handler);\n\t}\n\n\t/**\n\t * Alias for onHook. This is provided for compatibility with other libraries that use the `addHook` method.\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tpublic addHook(event: string, handler: Hook) {\n\t\t// Alias for onHook\n\t\tthis.onHook(event, handler);\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event\n\t * @param {Array<HookEntry>} hooks\n\t * @returns {void}\n\t */\n\tpublic onHooks(hooks: HookEntry[]) {\n\t\tfor (const hook of hooks) {\n\t\t\tthis.onHook(hook.event, hook.handler);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that runs before all other handlers\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tpublic prependHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\teventHandlers.unshift(handler);\n\t\t} else {\n\t\t\tthis._hooks.set(event, [handler]);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event before all other handlers\n\t * @param event\n\t * @param handler\n\t */\n\tpublic prependOnceHook(event: string, handler: Hook) {\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst hook = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook(event, hook);\n\t\t\treturn handler(...arguments_);\n\t\t};\n\n\t\tthis.prependHook(event, hook);\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event\n\t * @param event\n\t * @param handler\n\t */\n\tpublic onceHook(event: string, handler: Hook) {\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst hook = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook(event, hook);\n\t\t\treturn handler(...arguments_);\n\t\t};\n\n\t\tthis.onHook(event, hook);\n\t}\n\n\t/**\n\t * Removes a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler\n\t * @returns {void}\n\t */\n\tpublic removeHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tconst index = eventHandlers.indexOf(handler);\n\t\t\tif (index !== -1) {\n\t\t\t\teventHandlers.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes all handlers for a specific event\n\t * @param {Array<HookEntry>} hooks\n\t * @returns {void}\n\t */\n\tpublic removeHooks(hooks: HookEntry[]) {\n\t\tfor (const hook of hooks) {\n\t\t\tthis.removeHook(hook.event, hook.handler);\n\t\t}\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tpublic async hook<T>(event: string, ...arguments_: T[]) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const handler of eventHandlers) {\n\t\t\t\ttry {\n\t\t\t\t\tawait handler(...arguments_);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst message = `${event}: ${(error as Error).message}`;\n\t\t\t\t\tthis.emit(\"error\", new Error(message));\n\t\t\t\t\tif (this.logger) {\n\t\t\t\t\t\tthis.logger.error(message);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this._throwHookErrors) {\n\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Prepends the word `before` to your hook. Example is event is `test`, the before hook is `before:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async beforeHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`before:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Prepends the word `after` to your hook. Example is event is `test`, the after hook is `after:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async afterHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`after:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event. This is an alias for `hook` and is provided for\n\t * compatibility with other libraries that use the `callHook` method.\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tpublic async callHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(event, ...arguments_);\n\t}\n\n\t/**\n\t * Gets all hooks for a specific event\n\t * @param {string} event\n\t * @returns {Hook[]}\n\t */\n\tpublic getHooks(event: string) {\n\t\treturn this._hooks.get(event);\n\t}\n\n\t/**\n\t * Removes all hooks\n\t * @returns {void}\n\t */\n\tpublic clearHooks() {\n\t\tthis._hooks.clear();\n\t}\n}\n\nexport { Eventified, type EventListener } from \"./eventified.js\";\nexport type { Logger } from \"./logger.js\";\n"],"mappings":"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","names":["Eventified","options","__publicField","logger","value","eventName","listener","onceListener","arguments_","listeners","event","index","result","error","n","Hookified","Eventified","options","__publicField","value","event","handler","eventHandlers","hookEntry","hooks","hook","arguments_","index","error","message"]}
|
|
1
|
+
{"version":3,"sources":["../../src/eventified.ts","../../src/index.ts"],"sourcesContent":["// biome-ignore-all lint/suspicious/noExplicitAny: this is for event emitter compatibility\nimport type { Logger } from \"logger.js\";\n\nexport type IEventEmitter = {\n\t/**\n\t * Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.on('data', (message) => {\n\t * console.log(message);\n\t * });\n\t */\n\ton(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Alias for `on`. Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\taddListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Registers a one-time listener for the specified event. The listener is removed after it is called once.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.once('close', () => {\n\t * console.log('The connection was closed.');\n\t * });\n\t */\n\tonce(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.off('data', myListener);\n\t */\n\toff(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Alias for `off`. Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\tremoveListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Emits the specified event, invoking all registered listeners with the provided arguments.\n\t *\n\t * @param eventName - The name (or symbol) of the event to emit.\n\t * @param args - Arguments passed to each listener.\n\t * @returns `true` if the event had listeners, `false` otherwise.\n\t *\n\t * @example\n\t * emitter.emit('data', 'Hello World');\n\t */\n\temit(eventName: string | symbol, ...arguments_: any[]): boolean;\n\n\t/**\n\t * Returns the number of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns The number of registered listeners.\n\t *\n\t * @example\n\t * const count = emitter.listenerCount('data');\n\t * console.log(count); // e.g., 2\n\t */\n\tlistenerCount(eventName: string | symbol): number;\n\n\t/**\n\t * Removes all listeners for the specified event. If no event is specified, it removes all listeners for all events.\n\t *\n\t * @param eventName - (Optional) The name (or symbol) of the event.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.removeAllListeners('data');\n\t */\n\tremoveAllListeners(eventName?: string | symbol): IEventEmitter;\n\n\t/**\n\t * Returns an array of event names for which listeners have been registered.\n\t *\n\t * @returns An array of event names (or symbols).\n\t *\n\t * @example\n\t * const events = emitter.eventNames();\n\t * console.log(events); // e.g., ['data', 'close']\n\t */\n\teventNames(): Array<string | symbol>;\n\n\t/**\n\t * Returns an array of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of listener functions.\n\t *\n\t * @example\n\t * const listeners = emitter.listeners('data');\n\t * console.log(listeners.length); // e.g., 2\n\t */\n\tlisteners(eventName: string | symbol): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Returns an array of raw listeners for the specified event. This includes listeners wrapped by internal mechanisms (e.g., once-only listeners).\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of raw listener functions.\n\t *\n\t * @example\n\t * const rawListeners = emitter.rawListeners('data');\n\t */\n\trawListeners(\n\t\teventName: string | symbol,\n\t): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Adds a listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependListener('data', (message) => {\n\t * console.log('This will run first.');\n\t * });\n\t */\n\tprependListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Adds a one-time listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependOnceListener('data', (message) => {\n\t * console.log('This will run first and only once.');\n\t * });\n\t */\n\tprependOnceListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n};\n\nexport type EventListener = (...arguments_: any[]) => void;\n\nexport type EventEmitterOptions = {\n\t/**\n\t * Logger instance for logging errors.\n\t */\n\tlogger?: Logger;\n\t/**\n\t * Whether to throw an error when emit 'error' and there are no listeners. Default is false and only emits an error event.\n\t */\n\tthrowOnEmitError?: boolean;\n};\n\nexport class Eventified implements IEventEmitter {\n\tprivate readonly _eventListeners: Map<string | symbol, EventListener[]>;\n\tprivate _maxListeners: number;\n\tprivate _logger?: Logger;\n\tprivate _throwOnEmitError = false;\n\n\tconstructor(options?: EventEmitterOptions) {\n\t\tthis._eventListeners = new Map<string | symbol, EventListener[]>();\n\t\tthis._maxListeners = 100; // Default maximum number of listeners\n\n\t\tthis._logger = options?.logger;\n\n\t\tif (options?.throwOnEmitError !== undefined) {\n\t\t\tthis._throwOnEmitError = options.throwOnEmitError;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the logger\n\t * @returns {Logger}\n\t */\n\tpublic get logger(): Logger | undefined {\n\t\treturn this._logger;\n\t}\n\n\t/**\n\t * Sets the logger\n\t * @param {Logger} logger\n\t */\n\tpublic set logger(logger: Logger | undefined) {\n\t\tthis._logger = logger;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @returns {boolean}\n\t */\n\tpublic get throwOnEmitError(): boolean {\n\t\treturn this._throwOnEmitError;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @param {boolean} value\n\t */\n\tpublic set throwOnEmitError(value: boolean) {\n\t\tthis._throwOnEmitError = value;\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that will run only once\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic once(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.on(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the number of listeners for a specific event. If no event is provided, it returns the total number of listeners\n\t * @param {string} eventName The event name. Not required\n\t * @returns {number} The number of listeners\n\t */\n\tpublic listenerCount(eventName?: string | symbol): number {\n\t\tif (eventName === undefined) {\n\t\t\treturn this.getAllListeners().length;\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(eventName);\n\t\treturn listeners ? listeners.length : 0;\n\t}\n\n\t/**\n\t * Gets an array of event names\n\t * @returns {Array<string | symbol>} An array of event names\n\t */\n\tpublic eventNames(): Array<string | symbol> {\n\t\treturn [...this._eventListeners.keys()];\n\t}\n\n\t/**\n\t * Gets an array of listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic rawListeners(event?: string | symbol): EventListener[] {\n\t\tif (event === undefined) {\n\t\t\treturn this.getAllListeners();\n\t\t}\n\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Prepends a listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic prependListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(eventName) ?? [];\n\t\tlisteners.unshift(listener);\n\t\tthis._eventListeners.set(eventName, listeners);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepends a one-time listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic prependOnceListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.prependListener(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the maximum number of listeners that can be added for a single event\n\t * @returns {number} The maximum number of listeners\n\t */\n\tpublic maxListeners(): number {\n\t\treturn this._maxListeners;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event. It is an alias for the on() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic addListener(\n\t\tevent: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tthis.on(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic on(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tif (!this._eventListeners.has(event)) {\n\t\t\tthis._eventListeners.set(event, []);\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners) {\n\t\t\tif (listeners.length >= this._maxListeners) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event as string} listeners added. Use setMaxListeners() to increase limit.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlisteners.push(listener);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event. It is an alias for the off() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeListener(event: string, listener: EventListener): IEventEmitter {\n\t\tthis.off(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic off(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(event) ?? [];\n\t\tconst index = listeners.indexOf(listener);\n\t\tif (index !== -1) {\n\t\t\tlisteners.splice(index, 1);\n\t\t}\n\n\t\tif (listeners.length === 0) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Calls all listeners for a specific event\n\t * @param {string | symbol} event\n\t * @param arguments_ The arguments to pass to the listeners\n\t * @returns {boolean} Returns true if the event had listeners, false otherwise\n\t */\n\tpublic emit(event: string | symbol, ...arguments_: any[]): boolean {\n\t\tlet result = false;\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners && listeners.length > 0) {\n\t\t\tfor (const listener of listeners) {\n\t\t\t\tlistener(...arguments_);\n\t\t\t\tresult = true;\n\t\t\t}\n\t\t}\n\n\t\tif (event === \"error\") {\n\t\t\tconst error =\n\t\t\t\targuments_[0] instanceof Error\n\t\t\t\t\t? arguments_[0]\n\t\t\t\t\t: new Error(`${arguments_[0]}`);\n\n\t\t\tif (this._throwOnEmitError && !result) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Gets all listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic listeners(event: string | symbol): EventListener[] {\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Removes all listeners for a specific event. If no event is provided, it removes all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeAllListeners(event?: string | symbol): IEventEmitter {\n\t\tif (event !== undefined) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t} else {\n\t\t\tthis._eventListeners.clear();\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the maximum number of listeners that can be added for a single event\n\t * @param {number} n The maximum number of listeners\n\t * @returns {void}\n\t */\n\tpublic setMaxListeners(n: number): void {\n\t\tthis._maxListeners = n;\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tif (listeners.length > n) {\n\t\t\t\tlisteners.splice(n);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets all listeners\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic getAllListeners(): EventListener[] {\n\t\tlet result: EventListener[] = [];\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tresult = [...result, ...listeners];\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import { type EventEmitterOptions, Eventified } from \"./eventified.js\";\n\n// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\nexport type Hook = (...arguments_: any[]) => Promise<void> | void;\n\nexport type HookEntry = {\n\t/**\n\t * The event name for the hook\n\t */\n\tevent: string;\n\t/**\n\t * The handler function for the hook\n\t */\n\thandler: Hook;\n};\n\nexport type HookifiedOptions = {\n\t/**\n\t * Whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t */\n\tthrowHookErrors?: boolean;\n\t/**\n\t * Whether to enforce that all hook names start with 'before' or 'after'. Default is false.\n\t * @type {boolean}\n\t * @default false\n\t */\n\tenforceBeforeAfter?: boolean;\n\t/**\n\t * Map of deprecated hook names to deprecation messages. When a deprecated hook is used, a warning will be emitted.\n\t * @type {Map<string, string>}\n\t * @default new Map()\n\t */\n\tdeprecatedHooks?: Map<string, string>;\n\t/**\n\t * Whether to allow deprecated hooks to be registered and executed. Default is true.\n\t * @type {boolean}\n\t * @default true\n\t */\n\tallowDeprecated?: boolean;\n} & EventEmitterOptions;\n\nexport class Hookified extends Eventified {\n\tprivate readonly _hooks: Map<string, Hook[]>;\n\tprivate _throwHookErrors = false;\n\tprivate _enforceBeforeAfter = false;\n\tprivate _deprecatedHooks: Map<string, string>;\n\tprivate _allowDeprecated = true;\n\n\tconstructor(options?: HookifiedOptions) {\n\t\tsuper({ logger: options?.logger });\n\t\tthis._hooks = new Map();\n\t\tthis._deprecatedHooks = options?.deprecatedHooks\n\t\t\t? new Map(options.deprecatedHooks)\n\t\t\t: new Map();\n\n\t\tif (options?.throwHookErrors !== undefined) {\n\t\t\tthis._throwHookErrors = options.throwHookErrors;\n\t\t}\n\n\t\tif (options?.enforceBeforeAfter !== undefined) {\n\t\t\tthis._enforceBeforeAfter = options.enforceBeforeAfter;\n\t\t}\n\n\t\tif (options?.allowDeprecated !== undefined) {\n\t\t\tthis._allowDeprecated = options.allowDeprecated;\n\t\t}\n\t}\n\n\t/**\n\t * Gets all hooks\n\t * @returns {Map<string, Hook[]>}\n\t */\n\tpublic get hooks() {\n\t\treturn this._hooks;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t * @returns {boolean}\n\t */\n\tpublic get throwHookErrors() {\n\t\treturn this._throwHookErrors;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t * @param {boolean} value\n\t */\n\tpublic set throwHookErrors(value) {\n\t\tthis._throwHookErrors = value;\n\t}\n\n\t/**\n\t * Gets whether to enforce that all hook names start with 'before' or 'after'. Default is false.\n\t * @returns {boolean}\n\t * @default false\n\t */\n\tpublic get enforceBeforeAfter() {\n\t\treturn this._enforceBeforeAfter;\n\t}\n\n\t/**\n\t * Sets whether to enforce that all hook names start with 'before' or 'after'. Default is false.\n\t * @param {boolean} value\n\t */\n\tpublic set enforceBeforeAfter(value) {\n\t\tthis._enforceBeforeAfter = value;\n\t}\n\n\t/**\n\t * Gets the map of deprecated hook names to deprecation messages.\n\t * @returns {Map<string, string>}\n\t */\n\tpublic get deprecatedHooks() {\n\t\treturn this._deprecatedHooks;\n\t}\n\n\t/**\n\t * Sets the map of deprecated hook names to deprecation messages.\n\t * @param {Map<string, string>} value\n\t */\n\tpublic set deprecatedHooks(value) {\n\t\tthis._deprecatedHooks = value;\n\t}\n\n\t/**\n\t * Gets whether deprecated hooks are allowed to be registered and executed. Default is true.\n\t * @returns {boolean}\n\t */\n\tpublic get allowDeprecated() {\n\t\treturn this._allowDeprecated;\n\t}\n\n\t/**\n\t * Sets whether deprecated hooks are allowed to be registered and executed. Default is true.\n\t * @param {boolean} value\n\t */\n\tpublic set allowDeprecated(value) {\n\t\tthis._allowDeprecated = value;\n\t}\n\n\t/**\n\t * Validates hook event name if enforceBeforeAfter is enabled\n\t * @param {string} event - The event name to validate\n\t * @throws {Error} If enforceBeforeAfter is true and event doesn't start with 'before' or 'after'\n\t */\n\tprivate validateHookName(event: string): void {\n\t\tif (this._enforceBeforeAfter) {\n\t\t\tconst eventValue = event.trim().toLocaleLowerCase();\n\t\t\tif (!eventValue.startsWith(\"before\") && !eventValue.startsWith(\"after\")) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Hook event \"${event}\" must start with \"before\" or \"after\" when enforceBeforeAfter is enabled`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if a hook is deprecated and emits a warning if it is\n\t * @param {string} event - The event name to check\n\t * @returns {boolean} - Returns true if the hook should proceed, false if it should be blocked\n\t */\n\tprivate checkDeprecatedHook(event: string): boolean {\n\t\tif (this._deprecatedHooks.has(event)) {\n\t\t\tconst message = this._deprecatedHooks.get(event);\n\t\t\tconst warningMessage = `Hook \"${event}\" is deprecated${message ? `: ${message}` : \"\"}`;\n\n\t\t\t// Emit deprecation warning event\n\t\t\tthis.emit(\"warn\", { hook: event, message: warningMessage });\n\n\t\t\t// Log to logger if available\n\t\t\tif (this.logger?.warn) {\n\t\t\t\tthis.logger.warn(warningMessage);\n\t\t\t}\n\n\t\t\t// Return false if deprecated hooks are not allowed\n\t\t\treturn this._allowDeprecated;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tpublic onHook(event: string, handler: Hook) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\teventHandlers.push(handler);\n\t\t} else {\n\t\t\tthis._hooks.set(event, [handler]);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that runs before all other handlers\n\t * @param {HookEntry} hookEntry\n\t * @returns {void}\n\t */\n\tpublic onHookEntry(hookEntry: HookEntry) {\n\t\tthis.onHook(hookEntry.event, hookEntry.handler);\n\t}\n\n\t/**\n\t * Alias for onHook. This is provided for compatibility with other libraries that use the `addHook` method.\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tpublic addHook(event: string, handler: Hook) {\n\t\t// Alias for onHook\n\t\tthis.onHook(event, handler);\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event\n\t * @param {Array<HookEntry>} hooks\n\t * @returns {void}\n\t */\n\tpublic onHooks(hooks: HookEntry[]) {\n\t\tfor (const hook of hooks) {\n\t\t\tthis.onHook(hook.event, hook.handler);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that runs before all other handlers\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tpublic prependHook(event: string, handler: Hook) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\teventHandlers.unshift(handler);\n\t\t} else {\n\t\t\tthis._hooks.set(event, [handler]);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event before all other handlers\n\t * @param event\n\t * @param handler\n\t */\n\tpublic prependOnceHook(event: string, handler: Hook) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst hook = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook(event, hook);\n\t\t\treturn handler(...arguments_);\n\t\t};\n\n\t\tthis.prependHook(event, hook);\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event\n\t * @param event\n\t * @param handler\n\t */\n\tpublic onceHook(event: string, handler: Hook) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst hook = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook(event, hook);\n\t\t\treturn handler(...arguments_);\n\t\t};\n\n\t\tthis.onHook(event, hook);\n\t}\n\n\t/**\n\t * Removes a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler\n\t * @returns {void}\n\t */\n\tpublic removeHook(event: string, handler: Hook) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip removal if deprecated hooks are not allowed\n\t\t}\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tconst index = eventHandlers.indexOf(handler);\n\t\t\tif (index !== -1) {\n\t\t\t\teventHandlers.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes all handlers for a specific event\n\t * @param {Array<HookEntry>} hooks\n\t * @returns {void}\n\t */\n\tpublic removeHooks(hooks: HookEntry[]) {\n\t\tfor (const hook of hooks) {\n\t\t\tthis.removeHook(hook.event, hook.handler);\n\t\t}\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tpublic async hook<T>(event: string, ...arguments_: T[]) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip execution if deprecated hooks are not allowed\n\t\t}\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const handler of eventHandlers) {\n\t\t\t\ttry {\n\t\t\t\t\tawait handler(...arguments_);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst message = `${event}: ${(error as Error).message}`;\n\t\t\t\t\tthis.emit(\"error\", new Error(message));\n\t\t\t\t\tif (this.logger) {\n\t\t\t\t\t\tthis.logger.error(message);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this._throwHookErrors) {\n\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Prepends the word `before` to your hook. Example is event is `test`, the before hook is `before:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async beforeHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`before:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Prepends the word `after` to your hook. Example is event is `test`, the after hook is `after:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async afterHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`after:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event. This is an alias for `hook` and is provided for\n\t * compatibility with other libraries that use the `callHook` method.\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tpublic async callHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(event, ...arguments_);\n\t}\n\n\t/**\n\t * Gets all hooks for a specific event\n\t * @param {string} event\n\t * @returns {Hook[]}\n\t */\n\tpublic getHooks(event: string) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn undefined; // Return undefined if deprecated hooks are not allowed\n\t\t}\n\t\treturn this._hooks.get(event);\n\t}\n\n\t/**\n\t * Removes all hooks\n\t * @returns {void}\n\t */\n\tpublic clearHooks() {\n\t\tthis._hooks.clear();\n\t}\n}\n\nexport { Eventified, type EventListener } from \"./eventified.js\";\nexport type { Logger } from \"./logger.js\";\n"],"mappings":"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","names":["Eventified","options","__publicField","logger","value","eventName","listener","onceListener","arguments_","listeners","event","index","result","error","n","Hookified","Eventified","options","__publicField","value","event","eventValue","message","warningMessage","handler","eventHandlers","hookEntry","hooks","hook","arguments_","index","error"]}
|
package/dist/browser/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var g=Object.defineProperty;var p=(n,t,e)=>t in n?g(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var i=(n,t,e)=>p(n,typeof t!="symbol"?t+"":t,e);var a=class{constructor(t){i(this,"_eventListeners");i(this,"_maxListeners");i(this,"_logger");i(this,"_throwOnEmitError",!1);this._eventListeners=new Map,this._maxListeners=100,this._logger=t?.logger,t?.throwOnEmitError!==void 0&&(this._throwOnEmitError=t.throwOnEmitError)}get logger(){return this._logger}set logger(t){this._logger=t}get throwOnEmitError(){return this._throwOnEmitError}set throwOnEmitError(t){this._throwOnEmitError=t}once(t,e){let r=(...s)=>{this.off(t,r),e(...s)};return this.on(t,r),this}listenerCount(t){if(t===void 0)return this.getAllListeners().length;let e=this._eventListeners.get(t);return e?e.length:0}eventNames(){return[...this._eventListeners.keys()]}rawListeners(t){return t===void 0?this.getAllListeners():this._eventListeners.get(t)??[]}prependListener(t,e){let r=this._eventListeners.get(t)??[];return r.unshift(e),this._eventListeners.set(t,r),this}prependOnceListener(t,e){let r=(...s)=>{this.off(t,r),e(...s)};return this.prependListener(t,r),this}maxListeners(){return this._maxListeners}addListener(t,e){return this.on(t,e),this}on(t,e){this._eventListeners.has(t)||this._eventListeners.set(t,[]);let r=this._eventListeners.get(t);return r&&(r.length>=this._maxListeners&&console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${r.length+1} ${t} listeners added. Use setMaxListeners() to increase limit.`),r.push(e)),this}removeListener(t,e){return this.off(t,e),this}off(t,e){let r=this._eventListeners.get(t)??[],s=r.indexOf(e);return s!==-1&&r.splice(s,1),r.length===0&&this._eventListeners.delete(t),this}emit(t,...e){let r=!1,s=this._eventListeners.get(t);if(s&&s.length>0)for(let o of s)o(...e),r=!0;if(t==="error"){let o=e[0]instanceof Error?e[0]:new Error(`${e[0]}`);if(this._throwOnEmitError&&!r)throw o}return r}listeners(t){return this._eventListeners.get(t)??[]}removeAllListeners(t){return t!==void 0?this._eventListeners.delete(t):this._eventListeners.clear(),this}setMaxListeners(t){this._maxListeners=t;for(let e of this._eventListeners.values())e.length>t&&e.splice(t)}getAllListeners(){let t=[];for(let e of this._eventListeners.values())t=[...t,...e];return t}};var h=class extends a{constructor(e){super({logger:e?.logger});i(this,"_hooks");i(this,"_throwHookErrors",!1);i(this,"_enforceBeforeAfter",!1);i(this,"_deprecatedHooks");i(this,"_allowDeprecated",!0);this._hooks=new Map,this._deprecatedHooks=e?.deprecatedHooks?new Map(e.deprecatedHooks):new Map,e?.throwHookErrors!==void 0&&(this._throwHookErrors=e.throwHookErrors),e?.enforceBeforeAfter!==void 0&&(this._enforceBeforeAfter=e.enforceBeforeAfter),e?.allowDeprecated!==void 0&&(this._allowDeprecated=e.allowDeprecated)}get hooks(){return this._hooks}get throwHookErrors(){return this._throwHookErrors}set throwHookErrors(e){this._throwHookErrors=e}get enforceBeforeAfter(){return this._enforceBeforeAfter}set enforceBeforeAfter(e){this._enforceBeforeAfter=e}get deprecatedHooks(){return this._deprecatedHooks}set deprecatedHooks(e){this._deprecatedHooks=e}get allowDeprecated(){return this._allowDeprecated}set allowDeprecated(e){this._allowDeprecated=e}validateHookName(e){if(this._enforceBeforeAfter){let r=e.trim().toLocaleLowerCase();if(!r.startsWith("before")&&!r.startsWith("after"))throw new Error(`Hook event "${e}" must start with "before" or "after" when enforceBeforeAfter is enabled`)}}checkDeprecatedHook(e){if(this._deprecatedHooks.has(e)){let r=this._deprecatedHooks.get(e),s=`Hook "${e}" is deprecated${r?`: ${r}`:""}`;return this.emit("warn",{hook:e,message:s}),this.logger?.warn&&this.logger.warn(s),this._allowDeprecated}return!0}onHook(e,r){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let s=this._hooks.get(e);s?s.push(r):this._hooks.set(e,[r])}onHookEntry(e){this.onHook(e.event,e.handler)}addHook(e,r){this.onHook(e,r)}onHooks(e){for(let r of e)this.onHook(r.event,r.handler)}prependHook(e,r){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let s=this._hooks.get(e);s?s.unshift(r):this._hooks.set(e,[r])}prependOnceHook(e,r){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let s=async(...o)=>(this.removeHook(e,s),r(...o));this.prependHook(e,s)}onceHook(e,r){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let s=async(...o)=>(this.removeHook(e,s),r(...o));this.onHook(e,s)}removeHook(e,r){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let s=this._hooks.get(e);if(s){let o=s.indexOf(r);o!==-1&&s.splice(o,1)}}removeHooks(e){for(let r of e)this.removeHook(r.event,r.handler)}async hook(e,...r){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let s=this._hooks.get(e);if(s)for(let o of s)try{await o(...r)}catch(c){let l=`${e}: ${c.message}`;if(this.emit("error",new Error(l)),this.logger&&this.logger.error(l),this._throwHookErrors)throw new Error(l)}}async beforeHook(e,...r){await this.hook(`before:${e}`,...r)}async afterHook(e,...r){await this.hook(`after:${e}`,...r)}async callHook(e,...r){await this.hook(e,...r)}getHooks(e){if(this.validateHookName(e),!!this.checkDeprecatedHook(e))return this._hooks.get(e)}clearHooks(){this._hooks.clear()}};export{a as Eventified,h as Hookified};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/eventified.ts","../../src/index.ts"],"sourcesContent":["// biome-ignore-all lint/suspicious/noExplicitAny: this is for event emitter compatibility\nimport type { Logger } from \"logger.js\";\n\nexport type IEventEmitter = {\n\t/**\n\t * Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.on('data', (message) => {\n\t * console.log(message);\n\t * });\n\t */\n\ton(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Alias for `on`. Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\taddListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Registers a one-time listener for the specified event. The listener is removed after it is called once.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.once('close', () => {\n\t * console.log('The connection was closed.');\n\t * });\n\t */\n\tonce(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.off('data', myListener);\n\t */\n\toff(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Alias for `off`. Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\tremoveListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Emits the specified event, invoking all registered listeners with the provided arguments.\n\t *\n\t * @param eventName - The name (or symbol) of the event to emit.\n\t * @param args - Arguments passed to each listener.\n\t * @returns `true` if the event had listeners, `false` otherwise.\n\t *\n\t * @example\n\t * emitter.emit('data', 'Hello World');\n\t */\n\temit(eventName: string | symbol, ...arguments_: any[]): boolean;\n\n\t/**\n\t * Returns the number of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns The number of registered listeners.\n\t *\n\t * @example\n\t * const count = emitter.listenerCount('data');\n\t * console.log(count); // e.g., 2\n\t */\n\tlistenerCount(eventName: string | symbol): number;\n\n\t/**\n\t * Removes all listeners for the specified event. If no event is specified, it removes all listeners for all events.\n\t *\n\t * @param eventName - (Optional) The name (or symbol) of the event.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.removeAllListeners('data');\n\t */\n\tremoveAllListeners(eventName?: string | symbol): IEventEmitter;\n\n\t/**\n\t * Returns an array of event names for which listeners have been registered.\n\t *\n\t * @returns An array of event names (or symbols).\n\t *\n\t * @example\n\t * const events = emitter.eventNames();\n\t * console.log(events); // e.g., ['data', 'close']\n\t */\n\teventNames(): Array<string | symbol>;\n\n\t/**\n\t * Returns an array of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of listener functions.\n\t *\n\t * @example\n\t * const listeners = emitter.listeners('data');\n\t * console.log(listeners.length); // e.g., 2\n\t */\n\tlisteners(eventName: string | symbol): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Returns an array of raw listeners for the specified event. This includes listeners wrapped by internal mechanisms (e.g., once-only listeners).\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of raw listener functions.\n\t *\n\t * @example\n\t * const rawListeners = emitter.rawListeners('data');\n\t */\n\trawListeners(\n\t\teventName: string | symbol,\n\t): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Adds a listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependListener('data', (message) => {\n\t * console.log('This will run first.');\n\t * });\n\t */\n\tprependListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Adds a one-time listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependOnceListener('data', (message) => {\n\t * console.log('This will run first and only once.');\n\t * });\n\t */\n\tprependOnceListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n};\n\nexport type EventListener = (...arguments_: any[]) => void;\n\nexport type EventEmitterOptions = {\n\t/**\n\t * Logger instance for logging errors.\n\t */\n\tlogger?: Logger;\n\t/**\n\t * Whether to throw an error when emit 'error' and there are no listeners. Default is false and only emits an error event.\n\t */\n\tthrowOnEmitError?: boolean;\n};\n\nexport class Eventified implements IEventEmitter {\n\tprivate readonly _eventListeners: Map<string | symbol, EventListener[]>;\n\tprivate _maxListeners: number;\n\tprivate _logger?: Logger;\n\tprivate _throwOnEmitError = false;\n\n\tconstructor(options?: EventEmitterOptions) {\n\t\tthis._eventListeners = new Map<string | symbol, EventListener[]>();\n\t\tthis._maxListeners = 100; // Default maximum number of listeners\n\n\t\tthis._logger = options?.logger;\n\n\t\tif (options?.throwOnEmitError !== undefined) {\n\t\t\tthis._throwOnEmitError = options.throwOnEmitError;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the logger\n\t * @returns {Logger}\n\t */\n\tpublic get logger(): Logger | undefined {\n\t\treturn this._logger;\n\t}\n\n\t/**\n\t * Sets the logger\n\t * @param {Logger} logger\n\t */\n\tpublic set logger(logger: Logger | undefined) {\n\t\tthis._logger = logger;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @returns {boolean}\n\t */\n\tpublic get throwOnEmitError(): boolean {\n\t\treturn this._throwOnEmitError;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @param {boolean} value\n\t */\n\tpublic set throwOnEmitError(value: boolean) {\n\t\tthis._throwOnEmitError = value;\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that will run only once\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic once(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.on(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the number of listeners for a specific event. If no event is provided, it returns the total number of listeners\n\t * @param {string} eventName The event name. Not required\n\t * @returns {number} The number of listeners\n\t */\n\tpublic listenerCount(eventName?: string | symbol): number {\n\t\tif (eventName === undefined) {\n\t\t\treturn this.getAllListeners().length;\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(eventName);\n\t\treturn listeners ? listeners.length : 0;\n\t}\n\n\t/**\n\t * Gets an array of event names\n\t * @returns {Array<string | symbol>} An array of event names\n\t */\n\tpublic eventNames(): Array<string | symbol> {\n\t\treturn [...this._eventListeners.keys()];\n\t}\n\n\t/**\n\t * Gets an array of listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic rawListeners(event?: string | symbol): EventListener[] {\n\t\tif (event === undefined) {\n\t\t\treturn this.getAllListeners();\n\t\t}\n\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Prepends a listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic prependListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(eventName) ?? [];\n\t\tlisteners.unshift(listener);\n\t\tthis._eventListeners.set(eventName, listeners);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepends a one-time listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic prependOnceListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.prependListener(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the maximum number of listeners that can be added for a single event\n\t * @returns {number} The maximum number of listeners\n\t */\n\tpublic maxListeners(): number {\n\t\treturn this._maxListeners;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event. It is an alias for the on() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic addListener(\n\t\tevent: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tthis.on(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic on(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tif (!this._eventListeners.has(event)) {\n\t\t\tthis._eventListeners.set(event, []);\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners) {\n\t\t\tif (listeners.length >= this._maxListeners) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event as string} listeners added. Use setMaxListeners() to increase limit.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlisteners.push(listener);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event. It is an alias for the off() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeListener(event: string, listener: EventListener): IEventEmitter {\n\t\tthis.off(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic off(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(event) ?? [];\n\t\tconst index = listeners.indexOf(listener);\n\t\tif (index !== -1) {\n\t\t\tlisteners.splice(index, 1);\n\t\t}\n\n\t\tif (listeners.length === 0) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Calls all listeners for a specific event\n\t * @param {string | symbol} event\n\t * @param arguments_ The arguments to pass to the listeners\n\t * @returns {boolean} Returns true if the event had listeners, false otherwise\n\t */\n\tpublic emit(event: string | symbol, ...arguments_: any[]): boolean {\n\t\tlet result = false;\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners && listeners.length > 0) {\n\t\t\tfor (const listener of listeners) {\n\t\t\t\tlistener(...arguments_);\n\t\t\t\tresult = true;\n\t\t\t}\n\t\t}\n\n\t\tif (event === \"error\") {\n\t\t\tconst error =\n\t\t\t\targuments_[0] instanceof Error\n\t\t\t\t\t? arguments_[0]\n\t\t\t\t\t: new Error(`${arguments_[0]}`);\n\n\t\t\tif (this._throwOnEmitError && !result) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Gets all listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic listeners(event: string | symbol): EventListener[] {\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Removes all listeners for a specific event. If no event is provided, it removes all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeAllListeners(event?: string | symbol): IEventEmitter {\n\t\tif (event !== undefined) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t} else {\n\t\t\tthis._eventListeners.clear();\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the maximum number of listeners that can be added for a single event\n\t * @param {number} n The maximum number of listeners\n\t * @returns {void}\n\t */\n\tpublic setMaxListeners(n: number): void {\n\t\tthis._maxListeners = n;\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tif (listeners.length > n) {\n\t\t\t\tlisteners.splice(n);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets all listeners\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic getAllListeners(): EventListener[] {\n\t\tlet result: EventListener[] = [];\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tresult = [...result, ...listeners];\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import { type EventEmitterOptions, Eventified } from \"./eventified.js\";\n\n// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\nexport type Hook = (...arguments_: any[]) => Promise<void> | void;\n\nexport type HookEntry = {\n\t/**\n\t * The event name for the hook\n\t */\n\tevent: string;\n\t/**\n\t * The handler function for the hook\n\t */\n\thandler: Hook;\n};\n\nexport type HookifiedOptions = {\n\t/**\n\t * Whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t */\n\tthrowHookErrors?: boolean;\n} & EventEmitterOptions;\n\nexport class Hookified extends Eventified {\n\tprivate readonly _hooks: Map<string, Hook[]>;\n\tprivate _throwHookErrors = false;\n\n\tconstructor(options?: HookifiedOptions) {\n\t\tsuper({ logger: options?.logger });\n\t\tthis._hooks = new Map();\n\n\t\tif (options?.throwHookErrors !== undefined) {\n\t\t\tthis._throwHookErrors = options.throwHookErrors;\n\t\t}\n\t}\n\n\t/**\n\t * Gets all hooks\n\t * @returns {Map<string, Hook[]>}\n\t */\n\tpublic get hooks() {\n\t\treturn this._hooks;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t * @returns {boolean}\n\t */\n\tpublic get throwHookErrors() {\n\t\treturn this._throwHookErrors;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t * @param {boolean} value\n\t */\n\tpublic set throwHookErrors(value) {\n\t\tthis._throwHookErrors = value;\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tpublic onHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\teventHandlers.push(handler);\n\t\t} else {\n\t\t\tthis._hooks.set(event, [handler]);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that runs before all other handlers\n\t * @param {HookEntry} hookEntry\n\t * @returns {void}\n\t */\n\tpublic onHookEntry(hookEntry: HookEntry) {\n\t\tthis.onHook(hookEntry.event, hookEntry.handler);\n\t}\n\n\t/**\n\t * Alias for onHook. This is provided for compatibility with other libraries that use the `addHook` method.\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tpublic addHook(event: string, handler: Hook) {\n\t\t// Alias for onHook\n\t\tthis.onHook(event, handler);\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event\n\t * @param {Array<HookEntry>} hooks\n\t * @returns {void}\n\t */\n\tpublic onHooks(hooks: HookEntry[]) {\n\t\tfor (const hook of hooks) {\n\t\t\tthis.onHook(hook.event, hook.handler);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that runs before all other handlers\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tpublic prependHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\teventHandlers.unshift(handler);\n\t\t} else {\n\t\t\tthis._hooks.set(event, [handler]);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event before all other handlers\n\t * @param event\n\t * @param handler\n\t */\n\tpublic prependOnceHook(event: string, handler: Hook) {\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst hook = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook(event, hook);\n\t\t\treturn handler(...arguments_);\n\t\t};\n\n\t\tthis.prependHook(event, hook);\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event\n\t * @param event\n\t * @param handler\n\t */\n\tpublic onceHook(event: string, handler: Hook) {\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst hook = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook(event, hook);\n\t\t\treturn handler(...arguments_);\n\t\t};\n\n\t\tthis.onHook(event, hook);\n\t}\n\n\t/**\n\t * Removes a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler\n\t * @returns {void}\n\t */\n\tpublic removeHook(event: string, handler: Hook) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tconst index = eventHandlers.indexOf(handler);\n\t\t\tif (index !== -1) {\n\t\t\t\teventHandlers.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes all handlers for a specific event\n\t * @param {Array<HookEntry>} hooks\n\t * @returns {void}\n\t */\n\tpublic removeHooks(hooks: HookEntry[]) {\n\t\tfor (const hook of hooks) {\n\t\t\tthis.removeHook(hook.event, hook.handler);\n\t\t}\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tpublic async hook<T>(event: string, ...arguments_: T[]) {\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const handler of eventHandlers) {\n\t\t\t\ttry {\n\t\t\t\t\tawait handler(...arguments_);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst message = `${event}: ${(error as Error).message}`;\n\t\t\t\t\tthis.emit(\"error\", new Error(message));\n\t\t\t\t\tif (this.logger) {\n\t\t\t\t\t\tthis.logger.error(message);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this._throwHookErrors) {\n\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Prepends the word `before` to your hook. Example is event is `test`, the before hook is `before:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async beforeHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`before:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Prepends the word `after` to your hook. Example is event is `test`, the after hook is `after:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async afterHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`after:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event. This is an alias for `hook` and is provided for\n\t * compatibility with other libraries that use the `callHook` method.\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tpublic async callHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(event, ...arguments_);\n\t}\n\n\t/**\n\t * Gets all hooks for a specific event\n\t * @param {string} event\n\t * @returns {Hook[]}\n\t */\n\tpublic getHooks(event: string) {\n\t\treturn this._hooks.get(event);\n\t}\n\n\t/**\n\t * Removes all hooks\n\t * @returns {void}\n\t */\n\tpublic clearHooks() {\n\t\tthis._hooks.clear();\n\t}\n}\n\nexport { Eventified, type EventListener } from \"./eventified.js\";\nexport type { Logger } from \"./logger.js\";\n"],"mappings":"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","names":["Eventified","options","__publicField","logger","value","eventName","listener","onceListener","arguments_","listeners","event","index","result","error","n","Hookified","Eventified","options","__publicField","value","event","handler","eventHandlers","hookEntry","hooks","hook","arguments_","index","error","message"]}
|
|
1
|
+
{"version":3,"sources":["../../src/eventified.ts","../../src/index.ts"],"sourcesContent":["// biome-ignore-all lint/suspicious/noExplicitAny: this is for event emitter compatibility\nimport type { Logger } from \"logger.js\";\n\nexport type IEventEmitter = {\n\t/**\n\t * Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.on('data', (message) => {\n\t * console.log(message);\n\t * });\n\t */\n\ton(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Alias for `on`. Registers a listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\taddListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Registers a one-time listener for the specified event. The listener is removed after it is called once.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.once('close', () => {\n\t * console.log('The connection was closed.');\n\t * });\n\t */\n\tonce(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.off('data', myListener);\n\t */\n\toff(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Alias for `off`. Removes a previously registered listener for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to stop listening for.\n\t * @param listener - The specific callback function to remove.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t */\n\tremoveListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Emits the specified event, invoking all registered listeners with the provided arguments.\n\t *\n\t * @param eventName - The name (or symbol) of the event to emit.\n\t * @param args - Arguments passed to each listener.\n\t * @returns `true` if the event had listeners, `false` otherwise.\n\t *\n\t * @example\n\t * emitter.emit('data', 'Hello World');\n\t */\n\temit(eventName: string | symbol, ...arguments_: any[]): boolean;\n\n\t/**\n\t * Returns the number of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns The number of registered listeners.\n\t *\n\t * @example\n\t * const count = emitter.listenerCount('data');\n\t * console.log(count); // e.g., 2\n\t */\n\tlistenerCount(eventName: string | symbol): number;\n\n\t/**\n\t * Removes all listeners for the specified event. If no event is specified, it removes all listeners for all events.\n\t *\n\t * @param eventName - (Optional) The name (or symbol) of the event.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.removeAllListeners('data');\n\t */\n\tremoveAllListeners(eventName?: string | symbol): IEventEmitter;\n\n\t/**\n\t * Returns an array of event names for which listeners have been registered.\n\t *\n\t * @returns An array of event names (or symbols).\n\t *\n\t * @example\n\t * const events = emitter.eventNames();\n\t * console.log(events); // e.g., ['data', 'close']\n\t */\n\teventNames(): Array<string | symbol>;\n\n\t/**\n\t * Returns an array of listeners registered for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of listener functions.\n\t *\n\t * @example\n\t * const listeners = emitter.listeners('data');\n\t * console.log(listeners.length); // e.g., 2\n\t */\n\tlisteners(eventName: string | symbol): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Returns an array of raw listeners for the specified event. This includes listeners wrapped by internal mechanisms (e.g., once-only listeners).\n\t *\n\t * @param eventName - The name (or symbol) of the event.\n\t * @returns An array of raw listener functions.\n\t *\n\t * @example\n\t * const rawListeners = emitter.rawListeners('data');\n\t */\n\trawListeners(\n\t\teventName: string | symbol,\n\t): Array<(...arguments_: any[]) => void>;\n\n\t/**\n\t * Adds a listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependListener('data', (message) => {\n\t * console.log('This will run first.');\n\t * });\n\t */\n\tprependListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n\n\t/**\n\t * Adds a one-time listener to the beginning of the listeners array for the specified event.\n\t *\n\t * @param eventName - The name (or symbol) of the event to listen for.\n\t * @param listener - A callback function that will be invoked once when the event is emitted.\n\t * @returns The current instance of EventEmitter for method chaining.\n\t *\n\t * @example\n\t * emitter.prependOnceListener('data', (message) => {\n\t * console.log('This will run first and only once.');\n\t * });\n\t */\n\tprependOnceListener(\n\t\teventName: string | symbol,\n\t\tlistener: (...arguments_: any[]) => void,\n\t): IEventEmitter;\n};\n\nexport type EventListener = (...arguments_: any[]) => void;\n\nexport type EventEmitterOptions = {\n\t/**\n\t * Logger instance for logging errors.\n\t */\n\tlogger?: Logger;\n\t/**\n\t * Whether to throw an error when emit 'error' and there are no listeners. Default is false and only emits an error event.\n\t */\n\tthrowOnEmitError?: boolean;\n};\n\nexport class Eventified implements IEventEmitter {\n\tprivate readonly _eventListeners: Map<string | symbol, EventListener[]>;\n\tprivate _maxListeners: number;\n\tprivate _logger?: Logger;\n\tprivate _throwOnEmitError = false;\n\n\tconstructor(options?: EventEmitterOptions) {\n\t\tthis._eventListeners = new Map<string | symbol, EventListener[]>();\n\t\tthis._maxListeners = 100; // Default maximum number of listeners\n\n\t\tthis._logger = options?.logger;\n\n\t\tif (options?.throwOnEmitError !== undefined) {\n\t\t\tthis._throwOnEmitError = options.throwOnEmitError;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the logger\n\t * @returns {Logger}\n\t */\n\tpublic get logger(): Logger | undefined {\n\t\treturn this._logger;\n\t}\n\n\t/**\n\t * Sets the logger\n\t * @param {Logger} logger\n\t */\n\tpublic set logger(logger: Logger | undefined) {\n\t\tthis._logger = logger;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @returns {boolean}\n\t */\n\tpublic get throwOnEmitError(): boolean {\n\t\treturn this._throwOnEmitError;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when an emit throws an error. Default is false and only emits an error event.\n\t * @param {boolean} value\n\t */\n\tpublic set throwOnEmitError(value: boolean) {\n\t\tthis._throwOnEmitError = value;\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that will run only once\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic once(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.on(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the number of listeners for a specific event. If no event is provided, it returns the total number of listeners\n\t * @param {string} eventName The event name. Not required\n\t * @returns {number} The number of listeners\n\t */\n\tpublic listenerCount(eventName?: string | symbol): number {\n\t\tif (eventName === undefined) {\n\t\t\treturn this.getAllListeners().length;\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(eventName);\n\t\treturn listeners ? listeners.length : 0;\n\t}\n\n\t/**\n\t * Gets an array of event names\n\t * @returns {Array<string | symbol>} An array of event names\n\t */\n\tpublic eventNames(): Array<string | symbol> {\n\t\treturn [...this._eventListeners.keys()];\n\t}\n\n\t/**\n\t * Gets an array of listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic rawListeners(event?: string | symbol): EventListener[] {\n\t\tif (event === undefined) {\n\t\t\treturn this.getAllListeners();\n\t\t}\n\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Prepends a listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic prependListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(eventName) ?? [];\n\t\tlisteners.unshift(listener);\n\t\tthis._eventListeners.set(eventName, listeners);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepends a one-time listener to the beginning of the listeners array for the specified event\n\t * @param {string | symbol} eventName\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic prependOnceListener(\n\t\teventName: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tconst onceListener: EventListener = (...arguments_: any[]) => {\n\t\t\tthis.off(eventName as string, onceListener);\n\t\t\tlistener(...arguments_);\n\t\t};\n\n\t\tthis.prependListener(eventName as string, onceListener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the maximum number of listeners that can be added for a single event\n\t * @returns {number} The maximum number of listeners\n\t */\n\tpublic maxListeners(): number {\n\t\treturn this._maxListeners;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event. It is an alias for the on() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic addListener(\n\t\tevent: string | symbol,\n\t\tlistener: EventListener,\n\t): IEventEmitter {\n\t\tthis.on(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic on(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tif (!this._eventListeners.has(event)) {\n\t\t\tthis._eventListeners.set(event, []);\n\t\t}\n\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners) {\n\t\t\tif (listeners.length >= this._maxListeners) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event as string} listeners added. Use setMaxListeners() to increase limit.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlisteners.push(listener);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event. It is an alias for the off() method\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeListener(event: string, listener: EventListener): IEventEmitter {\n\t\tthis.off(event, listener);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a listener for a specific event\n\t * @param {string | symbol} event\n\t * @param {EventListener} listener\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic off(event: string | symbol, listener: EventListener): IEventEmitter {\n\t\tconst listeners = this._eventListeners.get(event) ?? [];\n\t\tconst index = listeners.indexOf(listener);\n\t\tif (index !== -1) {\n\t\t\tlisteners.splice(index, 1);\n\t\t}\n\n\t\tif (listeners.length === 0) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Calls all listeners for a specific event\n\t * @param {string | symbol} event\n\t * @param arguments_ The arguments to pass to the listeners\n\t * @returns {boolean} Returns true if the event had listeners, false otherwise\n\t */\n\tpublic emit(event: string | symbol, ...arguments_: any[]): boolean {\n\t\tlet result = false;\n\t\tconst listeners = this._eventListeners.get(event);\n\n\t\tif (listeners && listeners.length > 0) {\n\t\t\tfor (const listener of listeners) {\n\t\t\t\tlistener(...arguments_);\n\t\t\t\tresult = true;\n\t\t\t}\n\t\t}\n\n\t\tif (event === \"error\") {\n\t\t\tconst error =\n\t\t\t\targuments_[0] instanceof Error\n\t\t\t\t\t? arguments_[0]\n\t\t\t\t\t: new Error(`${arguments_[0]}`);\n\n\t\t\tif (this._throwOnEmitError && !result) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Gets all listeners for a specific event. If no event is provided, it returns all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic listeners(event: string | symbol): EventListener[] {\n\t\treturn this._eventListeners.get(event) ?? [];\n\t}\n\n\t/**\n\t * Removes all listeners for a specific event. If no event is provided, it removes all listeners\n\t * @param {string} [event] (Optional) The event name\n\t * @returns {IEventEmitter} returns the instance of the class for chaining\n\t */\n\tpublic removeAllListeners(event?: string | symbol): IEventEmitter {\n\t\tif (event !== undefined) {\n\t\t\tthis._eventListeners.delete(event);\n\t\t} else {\n\t\t\tthis._eventListeners.clear();\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the maximum number of listeners that can be added for a single event\n\t * @param {number} n The maximum number of listeners\n\t * @returns {void}\n\t */\n\tpublic setMaxListeners(n: number): void {\n\t\tthis._maxListeners = n;\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tif (listeners.length > n) {\n\t\t\t\tlisteners.splice(n);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets all listeners\n\t * @returns {EventListener[]} An array of listeners\n\t */\n\tpublic getAllListeners(): EventListener[] {\n\t\tlet result: EventListener[] = [];\n\t\tfor (const listeners of this._eventListeners.values()) {\n\t\t\tresult = [...result, ...listeners];\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import { type EventEmitterOptions, Eventified } from \"./eventified.js\";\n\n// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\nexport type Hook = (...arguments_: any[]) => Promise<void> | void;\n\nexport type HookEntry = {\n\t/**\n\t * The event name for the hook\n\t */\n\tevent: string;\n\t/**\n\t * The handler function for the hook\n\t */\n\thandler: Hook;\n};\n\nexport type HookifiedOptions = {\n\t/**\n\t * Whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t */\n\tthrowHookErrors?: boolean;\n\t/**\n\t * Whether to enforce that all hook names start with 'before' or 'after'. Default is false.\n\t * @type {boolean}\n\t * @default false\n\t */\n\tenforceBeforeAfter?: boolean;\n\t/**\n\t * Map of deprecated hook names to deprecation messages. When a deprecated hook is used, a warning will be emitted.\n\t * @type {Map<string, string>}\n\t * @default new Map()\n\t */\n\tdeprecatedHooks?: Map<string, string>;\n\t/**\n\t * Whether to allow deprecated hooks to be registered and executed. Default is true.\n\t * @type {boolean}\n\t * @default true\n\t */\n\tallowDeprecated?: boolean;\n} & EventEmitterOptions;\n\nexport class Hookified extends Eventified {\n\tprivate readonly _hooks: Map<string, Hook[]>;\n\tprivate _throwHookErrors = false;\n\tprivate _enforceBeforeAfter = false;\n\tprivate _deprecatedHooks: Map<string, string>;\n\tprivate _allowDeprecated = true;\n\n\tconstructor(options?: HookifiedOptions) {\n\t\tsuper({ logger: options?.logger });\n\t\tthis._hooks = new Map();\n\t\tthis._deprecatedHooks = options?.deprecatedHooks\n\t\t\t? new Map(options.deprecatedHooks)\n\t\t\t: new Map();\n\n\t\tif (options?.throwHookErrors !== undefined) {\n\t\t\tthis._throwHookErrors = options.throwHookErrors;\n\t\t}\n\n\t\tif (options?.enforceBeforeAfter !== undefined) {\n\t\t\tthis._enforceBeforeAfter = options.enforceBeforeAfter;\n\t\t}\n\n\t\tif (options?.allowDeprecated !== undefined) {\n\t\t\tthis._allowDeprecated = options.allowDeprecated;\n\t\t}\n\t}\n\n\t/**\n\t * Gets all hooks\n\t * @returns {Map<string, Hook[]>}\n\t */\n\tpublic get hooks() {\n\t\treturn this._hooks;\n\t}\n\n\t/**\n\t * Gets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t * @returns {boolean}\n\t */\n\tpublic get throwHookErrors() {\n\t\treturn this._throwHookErrors;\n\t}\n\n\t/**\n\t * Sets whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.\n\t * @param {boolean} value\n\t */\n\tpublic set throwHookErrors(value) {\n\t\tthis._throwHookErrors = value;\n\t}\n\n\t/**\n\t * Gets whether to enforce that all hook names start with 'before' or 'after'. Default is false.\n\t * @returns {boolean}\n\t * @default false\n\t */\n\tpublic get enforceBeforeAfter() {\n\t\treturn this._enforceBeforeAfter;\n\t}\n\n\t/**\n\t * Sets whether to enforce that all hook names start with 'before' or 'after'. Default is false.\n\t * @param {boolean} value\n\t */\n\tpublic set enforceBeforeAfter(value) {\n\t\tthis._enforceBeforeAfter = value;\n\t}\n\n\t/**\n\t * Gets the map of deprecated hook names to deprecation messages.\n\t * @returns {Map<string, string>}\n\t */\n\tpublic get deprecatedHooks() {\n\t\treturn this._deprecatedHooks;\n\t}\n\n\t/**\n\t * Sets the map of deprecated hook names to deprecation messages.\n\t * @param {Map<string, string>} value\n\t */\n\tpublic set deprecatedHooks(value) {\n\t\tthis._deprecatedHooks = value;\n\t}\n\n\t/**\n\t * Gets whether deprecated hooks are allowed to be registered and executed. Default is true.\n\t * @returns {boolean}\n\t */\n\tpublic get allowDeprecated() {\n\t\treturn this._allowDeprecated;\n\t}\n\n\t/**\n\t * Sets whether deprecated hooks are allowed to be registered and executed. Default is true.\n\t * @param {boolean} value\n\t */\n\tpublic set allowDeprecated(value) {\n\t\tthis._allowDeprecated = value;\n\t}\n\n\t/**\n\t * Validates hook event name if enforceBeforeAfter is enabled\n\t * @param {string} event - The event name to validate\n\t * @throws {Error} If enforceBeforeAfter is true and event doesn't start with 'before' or 'after'\n\t */\n\tprivate validateHookName(event: string): void {\n\t\tif (this._enforceBeforeAfter) {\n\t\t\tconst eventValue = event.trim().toLocaleLowerCase();\n\t\t\tif (!eventValue.startsWith(\"before\") && !eventValue.startsWith(\"after\")) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Hook event \"${event}\" must start with \"before\" or \"after\" when enforceBeforeAfter is enabled`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if a hook is deprecated and emits a warning if it is\n\t * @param {string} event - The event name to check\n\t * @returns {boolean} - Returns true if the hook should proceed, false if it should be blocked\n\t */\n\tprivate checkDeprecatedHook(event: string): boolean {\n\t\tif (this._deprecatedHooks.has(event)) {\n\t\t\tconst message = this._deprecatedHooks.get(event);\n\t\t\tconst warningMessage = `Hook \"${event}\" is deprecated${message ? `: ${message}` : \"\"}`;\n\n\t\t\t// Emit deprecation warning event\n\t\t\tthis.emit(\"warn\", { hook: event, message: warningMessage });\n\n\t\t\t// Log to logger if available\n\t\t\tif (this.logger?.warn) {\n\t\t\t\tthis.logger.warn(warningMessage);\n\t\t\t}\n\n\t\t\t// Return false if deprecated hooks are not allowed\n\t\t\treturn this._allowDeprecated;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tpublic onHook(event: string, handler: Hook) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\teventHandlers.push(handler);\n\t\t} else {\n\t\t\tthis._hooks.set(event, [handler]);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that runs before all other handlers\n\t * @param {HookEntry} hookEntry\n\t * @returns {void}\n\t */\n\tpublic onHookEntry(hookEntry: HookEntry) {\n\t\tthis.onHook(hookEntry.event, hookEntry.handler);\n\t}\n\n\t/**\n\t * Alias for onHook. This is provided for compatibility with other libraries that use the `addHook` method.\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tpublic addHook(event: string, handler: Hook) {\n\t\t// Alias for onHook\n\t\tthis.onHook(event, handler);\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event\n\t * @param {Array<HookEntry>} hooks\n\t * @returns {void}\n\t */\n\tpublic onHooks(hooks: HookEntry[]) {\n\t\tfor (const hook of hooks) {\n\t\t\tthis.onHook(hook.event, hook.handler);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler function for a specific event that runs before all other handlers\n\t * @param {string} event\n\t * @param {Hook} handler - this can be async or sync\n\t * @returns {void}\n\t */\n\tpublic prependHook(event: string, handler: Hook) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\teventHandlers.unshift(handler);\n\t\t} else {\n\t\t\tthis._hooks.set(event, [handler]);\n\t\t}\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event before all other handlers\n\t * @param event\n\t * @param handler\n\t */\n\tpublic prependOnceHook(event: string, handler: Hook) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst hook = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook(event, hook);\n\t\t\treturn handler(...arguments_);\n\t\t};\n\n\t\tthis.prependHook(event, hook);\n\t}\n\n\t/**\n\t * Adds a handler that only executes once for a specific event\n\t * @param event\n\t * @param handler\n\t */\n\tpublic onceHook(event: string, handler: Hook) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip registration if deprecated hooks are not allowed\n\t\t}\n\t\t// biome-ignore lint/suspicious/noExplicitAny: this is for any parameter compatibility\n\t\tconst hook = async (...arguments_: any[]) => {\n\t\t\tthis.removeHook(event, hook);\n\t\t\treturn handler(...arguments_);\n\t\t};\n\n\t\tthis.onHook(event, hook);\n\t}\n\n\t/**\n\t * Removes a handler function for a specific event\n\t * @param {string} event\n\t * @param {Hook} handler\n\t * @returns {void}\n\t */\n\tpublic removeHook(event: string, handler: Hook) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip removal if deprecated hooks are not allowed\n\t\t}\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tconst index = eventHandlers.indexOf(handler);\n\t\t\tif (index !== -1) {\n\t\t\t\teventHandlers.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes all handlers for a specific event\n\t * @param {Array<HookEntry>} hooks\n\t * @returns {void}\n\t */\n\tpublic removeHooks(hooks: HookEntry[]) {\n\t\tfor (const hook of hooks) {\n\t\t\tthis.removeHook(hook.event, hook.handler);\n\t\t}\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tpublic async hook<T>(event: string, ...arguments_: T[]) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn; // Skip execution if deprecated hooks are not allowed\n\t\t}\n\t\tconst eventHandlers = this._hooks.get(event);\n\t\tif (eventHandlers) {\n\t\t\tfor (const handler of eventHandlers) {\n\t\t\t\ttry {\n\t\t\t\t\tawait handler(...arguments_);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst message = `${event}: ${(error as Error).message}`;\n\t\t\t\t\tthis.emit(\"error\", new Error(message));\n\t\t\t\t\tif (this.logger) {\n\t\t\t\t\t\tthis.logger.error(message);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this._throwHookErrors) {\n\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Prepends the word `before` to your hook. Example is event is `test`, the before hook is `before:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async beforeHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`before:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Prepends the word `after` to your hook. Example is event is `test`, the after hook is `after:test`.\n\t * @param {string} event - The event name\n\t * @param {T[]} arguments_ - The arguments to pass to the hook\n\t */\n\tpublic async afterHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(`after:${event}`, ...arguments_);\n\t}\n\n\t/**\n\t * Calls all handlers for a specific event. This is an alias for `hook` and is provided for\n\t * compatibility with other libraries that use the `callHook` method.\n\t * @param {string} event\n\t * @param {T[]} arguments_\n\t * @returns {Promise<void>}\n\t */\n\tpublic async callHook<T>(event: string, ...arguments_: T[]) {\n\t\tawait this.hook(event, ...arguments_);\n\t}\n\n\t/**\n\t * Gets all hooks for a specific event\n\t * @param {string} event\n\t * @returns {Hook[]}\n\t */\n\tpublic getHooks(event: string) {\n\t\tthis.validateHookName(event);\n\t\tif (!this.checkDeprecatedHook(event)) {\n\t\t\treturn undefined; // Return undefined if deprecated hooks are not allowed\n\t\t}\n\t\treturn this._hooks.get(event);\n\t}\n\n\t/**\n\t * Removes all hooks\n\t * @returns {void}\n\t */\n\tpublic clearHooks() {\n\t\tthis._hooks.clear();\n\t}\n}\n\nexport { Eventified, type EventListener } from \"./eventified.js\";\nexport type { Logger } from \"./logger.js\";\n"],"mappings":"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","names":["Eventified","options","__publicField","logger","value","eventName","listener","onceListener","arguments_","listeners","event","index","result","error","n","Hookified","Eventified","options","__publicField","value","event","eventValue","message","warningMessage","handler","eventHandlers","hookEntry","hooks","hook","arguments_","index","error"]}
|
package/dist/node/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var l=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var m=(o,e)=>{for(var t in e)l(o,t,{get:e[t],enumerable:!0})},d=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of g(e))!p.call(o,s)&&s!==t&&l(o,s,{get:()=>e[s],enumerable:!(r=c(e,s))||r.enumerable});return o};var f=o=>d(l({},"__esModule",{value:!0}),o);var u={};m(u,{Eventified:()=>i,Hookified:()=>h});module.exports=f(u);var i=class{_eventListeners;_maxListeners;_logger;_throwOnEmitError=!1;constructor(e){this._eventListeners=new Map,this._maxListeners=100,this._logger=e?.logger,e?.throwOnEmitError!==void 0&&(this._throwOnEmitError=e.throwOnEmitError)}get logger(){return this._logger}set logger(e){this._logger=e}get throwOnEmitError(){return this._throwOnEmitError}set throwOnEmitError(e){this._throwOnEmitError=e}once(e,t){let r=(...s)=>{this.off(e,r),t(...s)};return this.on(e,r),this}listenerCount(e){if(e===void 0)return this.getAllListeners().length;let t=this._eventListeners.get(e);return t?t.length:0}eventNames(){return[...this._eventListeners.keys()]}rawListeners(e){return e===void 0?this.getAllListeners():this._eventListeners.get(e)??[]}prependListener(e,t){let r=this._eventListeners.get(e)??[];return r.unshift(t),this._eventListeners.set(e,r),this}prependOnceListener(e,t){let r=(...s)=>{this.off(e,r),t(...s)};return this.prependListener(e,r),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 r=this._eventListeners.get(e);return r&&(r.length>=this._maxListeners&&console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${r.length+1} ${e} listeners added. Use setMaxListeners() to increase limit.`),r.push(t)),this}removeListener(e,t){return this.off(e,t),this}off(e,t){let r=this._eventListeners.get(e)??[],s=r.indexOf(t);return s!==-1&&r.splice(s,1),r.length===0&&this._eventListeners.delete(e),this}emit(e,...t){let r=!1,s=this._eventListeners.get(e);if(s&&s.length>0)for(let n of s)n(...t),r=!0;if(e==="error"){let n=t[0]instanceof Error?t[0]:new Error(`${t[0]}`);if(this._throwOnEmitError&&!r)throw n}return r}listeners(e){return this._eventListeners.get(e)??[]}removeAllListeners(e){return e!==void 0?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=[];for(let t of this._eventListeners.values())e=[...e,...t];return e}};var h=class extends i{_hooks;_throwHookErrors=!1;_enforceBeforeAfter=!1;_deprecatedHooks;_allowDeprecated=!0;constructor(e){super({logger:e?.logger}),this._hooks=new Map,this._deprecatedHooks=e?.deprecatedHooks?new Map(e.deprecatedHooks):new Map,e?.throwHookErrors!==void 0&&(this._throwHookErrors=e.throwHookErrors),e?.enforceBeforeAfter!==void 0&&(this._enforceBeforeAfter=e.enforceBeforeAfter),e?.allowDeprecated!==void 0&&(this._allowDeprecated=e.allowDeprecated)}get hooks(){return this._hooks}get throwHookErrors(){return this._throwHookErrors}set throwHookErrors(e){this._throwHookErrors=e}get enforceBeforeAfter(){return this._enforceBeforeAfter}set enforceBeforeAfter(e){this._enforceBeforeAfter=e}get deprecatedHooks(){return this._deprecatedHooks}set deprecatedHooks(e){this._deprecatedHooks=e}get allowDeprecated(){return this._allowDeprecated}set allowDeprecated(e){this._allowDeprecated=e}validateHookName(e){if(this._enforceBeforeAfter){let t=e.trim().toLocaleLowerCase();if(!t.startsWith("before")&&!t.startsWith("after"))throw new Error(`Hook event "${e}" must start with "before" or "after" when enforceBeforeAfter is enabled`)}}checkDeprecatedHook(e){if(this._deprecatedHooks.has(e)){let t=this._deprecatedHooks.get(e),r=`Hook "${e}" is deprecated${t?`: ${t}`:""}`;return this.emit("warn",{hook:e,message:r}),this.logger?.warn&&this.logger.warn(r),this._allowDeprecated}return!0}onHook(e,t){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let r=this._hooks.get(e);r?r.push(t):this._hooks.set(e,[t])}onHookEntry(e){this.onHook(e.event,e.handler)}addHook(e,t){this.onHook(e,t)}onHooks(e){for(let t of e)this.onHook(t.event,t.handler)}prependHook(e,t){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let r=this._hooks.get(e);r?r.unshift(t):this._hooks.set(e,[t])}prependOnceHook(e,t){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let r=async(...s)=>(this.removeHook(e,r),t(...s));this.prependHook(e,r)}onceHook(e,t){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let r=async(...s)=>(this.removeHook(e,r),t(...s));this.onHook(e,r)}removeHook(e,t){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let r=this._hooks.get(e);if(r){let s=r.indexOf(t);s!==-1&&r.splice(s,1)}}removeHooks(e){for(let t of e)this.removeHook(t.event,t.handler)}async hook(e,...t){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let r=this._hooks.get(e);if(r)for(let s of r)try{await s(...t)}catch(n){let a=`${e}: ${n.message}`;if(this.emit("error",new Error(a)),this.logger&&this.logger.error(a),this._throwHookErrors)throw new Error(a)}}async beforeHook(e,...t){await this.hook(`before:${e}`,...t)}async afterHook(e,...t){await this.hook(`after:${e}`,...t)}async callHook(e,...t){await this.hook(e,...t)}getHooks(e){if(this.validateHookName(e),!!this.checkDeprecatedHook(e))return this._hooks.get(e)}clearHooks(){this._hooks.clear()}};0&&(module.exports={Eventified,Hookified});
|
package/dist/node/index.d.cts
CHANGED
|
@@ -307,10 +307,31 @@ type HookifiedOptions = {
|
|
|
307
307
|
* Whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.
|
|
308
308
|
*/
|
|
309
309
|
throwHookErrors?: boolean;
|
|
310
|
+
/**
|
|
311
|
+
* Whether to enforce that all hook names start with 'before' or 'after'. Default is false.
|
|
312
|
+
* @type {boolean}
|
|
313
|
+
* @default false
|
|
314
|
+
*/
|
|
315
|
+
enforceBeforeAfter?: boolean;
|
|
316
|
+
/**
|
|
317
|
+
* Map of deprecated hook names to deprecation messages. When a deprecated hook is used, a warning will be emitted.
|
|
318
|
+
* @type {Map<string, string>}
|
|
319
|
+
* @default new Map()
|
|
320
|
+
*/
|
|
321
|
+
deprecatedHooks?: Map<string, string>;
|
|
322
|
+
/**
|
|
323
|
+
* Whether to allow deprecated hooks to be registered and executed. Default is true.
|
|
324
|
+
* @type {boolean}
|
|
325
|
+
* @default true
|
|
326
|
+
*/
|
|
327
|
+
allowDeprecated?: boolean;
|
|
310
328
|
} & EventEmitterOptions;
|
|
311
329
|
declare class Hookified extends Eventified {
|
|
312
330
|
private readonly _hooks;
|
|
313
331
|
private _throwHookErrors;
|
|
332
|
+
private _enforceBeforeAfter;
|
|
333
|
+
private _deprecatedHooks;
|
|
334
|
+
private _allowDeprecated;
|
|
314
335
|
constructor(options?: HookifiedOptions);
|
|
315
336
|
/**
|
|
316
337
|
* Gets all hooks
|
|
@@ -327,6 +348,49 @@ declare class Hookified extends Eventified {
|
|
|
327
348
|
* @param {boolean} value
|
|
328
349
|
*/
|
|
329
350
|
set throwHookErrors(value: boolean);
|
|
351
|
+
/**
|
|
352
|
+
* Gets whether to enforce that all hook names start with 'before' or 'after'. Default is false.
|
|
353
|
+
* @returns {boolean}
|
|
354
|
+
* @default false
|
|
355
|
+
*/
|
|
356
|
+
get enforceBeforeAfter(): boolean;
|
|
357
|
+
/**
|
|
358
|
+
* Sets whether to enforce that all hook names start with 'before' or 'after'. Default is false.
|
|
359
|
+
* @param {boolean} value
|
|
360
|
+
*/
|
|
361
|
+
set enforceBeforeAfter(value: boolean);
|
|
362
|
+
/**
|
|
363
|
+
* Gets the map of deprecated hook names to deprecation messages.
|
|
364
|
+
* @returns {Map<string, string>}
|
|
365
|
+
*/
|
|
366
|
+
get deprecatedHooks(): Map<string, string>;
|
|
367
|
+
/**
|
|
368
|
+
* Sets the map of deprecated hook names to deprecation messages.
|
|
369
|
+
* @param {Map<string, string>} value
|
|
370
|
+
*/
|
|
371
|
+
set deprecatedHooks(value: Map<string, string>);
|
|
372
|
+
/**
|
|
373
|
+
* Gets whether deprecated hooks are allowed to be registered and executed. Default is true.
|
|
374
|
+
* @returns {boolean}
|
|
375
|
+
*/
|
|
376
|
+
get allowDeprecated(): boolean;
|
|
377
|
+
/**
|
|
378
|
+
* Sets whether deprecated hooks are allowed to be registered and executed. Default is true.
|
|
379
|
+
* @param {boolean} value
|
|
380
|
+
*/
|
|
381
|
+
set allowDeprecated(value: boolean);
|
|
382
|
+
/**
|
|
383
|
+
* Validates hook event name if enforceBeforeAfter is enabled
|
|
384
|
+
* @param {string} event - The event name to validate
|
|
385
|
+
* @throws {Error} If enforceBeforeAfter is true and event doesn't start with 'before' or 'after'
|
|
386
|
+
*/
|
|
387
|
+
private validateHookName;
|
|
388
|
+
/**
|
|
389
|
+
* Checks if a hook is deprecated and emits a warning if it is
|
|
390
|
+
* @param {string} event - The event name to check
|
|
391
|
+
* @returns {boolean} - Returns true if the hook should proceed, false if it should be blocked
|
|
392
|
+
*/
|
|
393
|
+
private checkDeprecatedHook;
|
|
330
394
|
/**
|
|
331
395
|
* Adds a handler function for a specific event
|
|
332
396
|
* @param {string} event
|
package/dist/node/index.d.ts
CHANGED
|
@@ -307,10 +307,31 @@ type HookifiedOptions = {
|
|
|
307
307
|
* Whether an error should be thrown when a hook throws an error. Default is false and only emits an error event.
|
|
308
308
|
*/
|
|
309
309
|
throwHookErrors?: boolean;
|
|
310
|
+
/**
|
|
311
|
+
* Whether to enforce that all hook names start with 'before' or 'after'. Default is false.
|
|
312
|
+
* @type {boolean}
|
|
313
|
+
* @default false
|
|
314
|
+
*/
|
|
315
|
+
enforceBeforeAfter?: boolean;
|
|
316
|
+
/**
|
|
317
|
+
* Map of deprecated hook names to deprecation messages. When a deprecated hook is used, a warning will be emitted.
|
|
318
|
+
* @type {Map<string, string>}
|
|
319
|
+
* @default new Map()
|
|
320
|
+
*/
|
|
321
|
+
deprecatedHooks?: Map<string, string>;
|
|
322
|
+
/**
|
|
323
|
+
* Whether to allow deprecated hooks to be registered and executed. Default is true.
|
|
324
|
+
* @type {boolean}
|
|
325
|
+
* @default true
|
|
326
|
+
*/
|
|
327
|
+
allowDeprecated?: boolean;
|
|
310
328
|
} & EventEmitterOptions;
|
|
311
329
|
declare class Hookified extends Eventified {
|
|
312
330
|
private readonly _hooks;
|
|
313
331
|
private _throwHookErrors;
|
|
332
|
+
private _enforceBeforeAfter;
|
|
333
|
+
private _deprecatedHooks;
|
|
334
|
+
private _allowDeprecated;
|
|
314
335
|
constructor(options?: HookifiedOptions);
|
|
315
336
|
/**
|
|
316
337
|
* Gets all hooks
|
|
@@ -327,6 +348,49 @@ declare class Hookified extends Eventified {
|
|
|
327
348
|
* @param {boolean} value
|
|
328
349
|
*/
|
|
329
350
|
set throwHookErrors(value: boolean);
|
|
351
|
+
/**
|
|
352
|
+
* Gets whether to enforce that all hook names start with 'before' or 'after'. Default is false.
|
|
353
|
+
* @returns {boolean}
|
|
354
|
+
* @default false
|
|
355
|
+
*/
|
|
356
|
+
get enforceBeforeAfter(): boolean;
|
|
357
|
+
/**
|
|
358
|
+
* Sets whether to enforce that all hook names start with 'before' or 'after'. Default is false.
|
|
359
|
+
* @param {boolean} value
|
|
360
|
+
*/
|
|
361
|
+
set enforceBeforeAfter(value: boolean);
|
|
362
|
+
/**
|
|
363
|
+
* Gets the map of deprecated hook names to deprecation messages.
|
|
364
|
+
* @returns {Map<string, string>}
|
|
365
|
+
*/
|
|
366
|
+
get deprecatedHooks(): Map<string, string>;
|
|
367
|
+
/**
|
|
368
|
+
* Sets the map of deprecated hook names to deprecation messages.
|
|
369
|
+
* @param {Map<string, string>} value
|
|
370
|
+
*/
|
|
371
|
+
set deprecatedHooks(value: Map<string, string>);
|
|
372
|
+
/**
|
|
373
|
+
* Gets whether deprecated hooks are allowed to be registered and executed. Default is true.
|
|
374
|
+
* @returns {boolean}
|
|
375
|
+
*/
|
|
376
|
+
get allowDeprecated(): boolean;
|
|
377
|
+
/**
|
|
378
|
+
* Sets whether deprecated hooks are allowed to be registered and executed. Default is true.
|
|
379
|
+
* @param {boolean} value
|
|
380
|
+
*/
|
|
381
|
+
set allowDeprecated(value: boolean);
|
|
382
|
+
/**
|
|
383
|
+
* Validates hook event name if enforceBeforeAfter is enabled
|
|
384
|
+
* @param {string} event - The event name to validate
|
|
385
|
+
* @throws {Error} If enforceBeforeAfter is true and event doesn't start with 'before' or 'after'
|
|
386
|
+
*/
|
|
387
|
+
private validateHookName;
|
|
388
|
+
/**
|
|
389
|
+
* Checks if a hook is deprecated and emits a warning if it is
|
|
390
|
+
* @param {string} event - The event name to check
|
|
391
|
+
* @returns {boolean} - Returns true if the hook should proceed, false if it should be blocked
|
|
392
|
+
*/
|
|
393
|
+
private checkDeprecatedHook;
|
|
330
394
|
/**
|
|
331
395
|
* Adds a handler function for a specific event
|
|
332
396
|
* @param {string} event
|
package/dist/node/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var i=class{_eventListeners;_maxListeners;_logger;_throwOnEmitError=!1;constructor(e){this._eventListeners=new Map,this._maxListeners=100,this._logger=e?.logger,e?.throwOnEmitError!==void 0&&(this._throwOnEmitError=e.throwOnEmitError)}get logger(){return this._logger}set logger(e){this._logger=e}get throwOnEmitError(){return this._throwOnEmitError}set throwOnEmitError(e){this._throwOnEmitError=e}once(e,t){let r=(...s)=>{this.off(e,r),t(...s)};return this.on(e,r),this}listenerCount(e){if(e===void 0)return this.getAllListeners().length;let t=this._eventListeners.get(e);return t?t.length:0}eventNames(){return[...this._eventListeners.keys()]}rawListeners(e){return e===void 0?this.getAllListeners():this._eventListeners.get(e)??[]}prependListener(e,t){let r=this._eventListeners.get(e)??[];return r.unshift(t),this._eventListeners.set(e,r),this}prependOnceListener(e,t){let r=(...s)=>{this.off(e,r),t(...s)};return this.prependListener(e,r),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 r=this._eventListeners.get(e);return r&&(r.length>=this._maxListeners&&console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${r.length+1} ${e} listeners added. Use setMaxListeners() to increase limit.`),r.push(t)),this}removeListener(e,t){return this.off(e,t),this}off(e,t){let r=this._eventListeners.get(e)??[],s=r.indexOf(t);return s!==-1&&r.splice(s,1),r.length===0&&this._eventListeners.delete(e),this}emit(e,...t){let r=!1,s=this._eventListeners.get(e);if(s&&s.length>0)for(let o of s)o(...t),r=!0;if(e==="error"){let o=t[0]instanceof Error?t[0]:new Error(`${t[0]}`);if(this._throwOnEmitError&&!r)throw o}return r}listeners(e){return this._eventListeners.get(e)??[]}removeAllListeners(e){return e!==void 0?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=[];for(let t of this._eventListeners.values())e=[...e,...t];return e}};var a=class extends i{_hooks;_throwHookErrors=!1;_enforceBeforeAfter=!1;_deprecatedHooks;_allowDeprecated=!0;constructor(e){super({logger:e?.logger}),this._hooks=new Map,this._deprecatedHooks=e?.deprecatedHooks?new Map(e.deprecatedHooks):new Map,e?.throwHookErrors!==void 0&&(this._throwHookErrors=e.throwHookErrors),e?.enforceBeforeAfter!==void 0&&(this._enforceBeforeAfter=e.enforceBeforeAfter),e?.allowDeprecated!==void 0&&(this._allowDeprecated=e.allowDeprecated)}get hooks(){return this._hooks}get throwHookErrors(){return this._throwHookErrors}set throwHookErrors(e){this._throwHookErrors=e}get enforceBeforeAfter(){return this._enforceBeforeAfter}set enforceBeforeAfter(e){this._enforceBeforeAfter=e}get deprecatedHooks(){return this._deprecatedHooks}set deprecatedHooks(e){this._deprecatedHooks=e}get allowDeprecated(){return this._allowDeprecated}set allowDeprecated(e){this._allowDeprecated=e}validateHookName(e){if(this._enforceBeforeAfter){let t=e.trim().toLocaleLowerCase();if(!t.startsWith("before")&&!t.startsWith("after"))throw new Error(`Hook event "${e}" must start with "before" or "after" when enforceBeforeAfter is enabled`)}}checkDeprecatedHook(e){if(this._deprecatedHooks.has(e)){let t=this._deprecatedHooks.get(e),r=`Hook "${e}" is deprecated${t?`: ${t}`:""}`;return this.emit("warn",{hook:e,message:r}),this.logger?.warn&&this.logger.warn(r),this._allowDeprecated}return!0}onHook(e,t){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let r=this._hooks.get(e);r?r.push(t):this._hooks.set(e,[t])}onHookEntry(e){this.onHook(e.event,e.handler)}addHook(e,t){this.onHook(e,t)}onHooks(e){for(let t of e)this.onHook(t.event,t.handler)}prependHook(e,t){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let r=this._hooks.get(e);r?r.unshift(t):this._hooks.set(e,[t])}prependOnceHook(e,t){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let r=async(...s)=>(this.removeHook(e,r),t(...s));this.prependHook(e,r)}onceHook(e,t){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let r=async(...s)=>(this.removeHook(e,r),t(...s));this.onHook(e,r)}removeHook(e,t){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let r=this._hooks.get(e);if(r){let s=r.indexOf(t);s!==-1&&r.splice(s,1)}}removeHooks(e){for(let t of e)this.removeHook(t.event,t.handler)}async hook(e,...t){if(this.validateHookName(e),!this.checkDeprecatedHook(e))return;let r=this._hooks.get(e);if(r)for(let s of r)try{await s(...t)}catch(o){let n=`${e}: ${o.message}`;if(this.emit("error",new Error(n)),this.logger&&this.logger.error(n),this._throwHookErrors)throw new Error(n)}}async beforeHook(e,...t){await this.hook(`before:${e}`,...t)}async afterHook(e,...t){await this.hook(`after:${e}`,...t)}async callHook(e,...t){await this.hook(e,...t)}getHooks(e){if(this.validateHookName(e),!!this.checkDeprecatedHook(e))return this._hooks.get(e)}clearHooks(){this._hooks.clear()}};export{i as Eventified,a as Hookified};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hookified",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.1",
|
|
4
4
|
"description": "Event Emitting and Middleware Hooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/node/index.cjs",
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
},
|
|
18
18
|
"types": "dist/node/index.d.ts",
|
|
19
19
|
"scripts": {
|
|
20
|
-
"lint": "biome check --write",
|
|
20
|
+
"lint": "biome check --write --error-on-warnings",
|
|
21
21
|
"test": "pnpm lint && vitest run --coverage",
|
|
22
|
-
"test:ci": "biome check && vitest run --coverage",
|
|
22
|
+
"test:ci": "biome check --error-on-warnings && vitest run --coverage",
|
|
23
23
|
"clean": "rimraf ./dist ./coverage ./site/dist",
|
|
24
24
|
"build": "rimraf ./dist && tsup",
|
|
25
25
|
"benchmark": "pnpm benchmark:hooks && pnpm benchmark:emit",
|
|
@@ -61,19 +61,19 @@
|
|
|
61
61
|
},
|
|
62
62
|
"homepage": "https://github.com/jaredwray/hookified#readme",
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@biomejs/biome": "^2.2.
|
|
65
|
-
"@monstermann/tinybench-pretty-printer": "^0.
|
|
66
|
-
"@types/node": "^24.
|
|
64
|
+
"@biomejs/biome": "^2.2.4",
|
|
65
|
+
"@monstermann/tinybench-pretty-printer": "^0.2.0",
|
|
66
|
+
"@types/node": "^24.5.2",
|
|
67
67
|
"@vitest/coverage-v8": "^3.2.4",
|
|
68
68
|
"docula": "^0.20.0",
|
|
69
69
|
"emittery": "^1.2.0",
|
|
70
70
|
"eventemitter3": "^5.0.1",
|
|
71
71
|
"hookable": "^5.5.3",
|
|
72
|
-
"pino": "^9.
|
|
72
|
+
"pino": "^9.10.0",
|
|
73
73
|
"rimraf": "^6.0.1",
|
|
74
|
-
"tinybench": "^5.0.
|
|
74
|
+
"tinybench": "^5.0.1",
|
|
75
75
|
"tsup": "^8.5.0",
|
|
76
|
-
"tsx": "^4.20.
|
|
76
|
+
"tsx": "^4.20.5",
|
|
77
77
|
"typescript": "^5.9.2",
|
|
78
78
|
"vitest": "^3.2.4"
|
|
79
79
|
},
|
|
@@ -83,7 +83,6 @@
|
|
|
83
83
|
],
|
|
84
84
|
"pnpm": {
|
|
85
85
|
"onlyBuiltDependencies": [
|
|
86
|
-
"esbuild",
|
|
87
86
|
"unrs-resolver"
|
|
88
87
|
]
|
|
89
88
|
}
|