hookified 1.0.0 → 1.2.0
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 +29 -9
- package/dist/index.cjs +79 -13
- package/dist/index.d.cts +17 -3
- package/dist/index.d.ts +17 -3
- package/dist/index.js +76 -3
- package/package.json +2 -7
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<img src="site/logo.svg" alt="Hookified" height="400" align="center">
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# Event Emitting and Async Middleware Hooks
|
|
4
4
|
|
|
5
5
|
[](https://github.com/jaredwray/hookified/actions/workflows/tests.yaml)
|
|
6
6
|
[](https://github.com/jaredwray/hookified/blob/master/LICENSE)
|
|
@@ -9,20 +9,18 @@
|
|
|
9
9
|
[](https://npmjs.com/package/hookified)
|
|
10
10
|
|
|
11
11
|
## Features
|
|
12
|
-
-
|
|
12
|
+
- Simple replacement for EventEmitter
|
|
13
13
|
- Async Middleware Hooks for Your Methods
|
|
14
|
-
- ESM / CJS and Nodejs 20+
|
|
14
|
+
- ESM / CJS with Types and Nodejs 20+
|
|
15
15
|
- Maintained on a regular basis!
|
|
16
16
|
|
|
17
|
-
Special thanks to [@sindresorhus](https://github.com/sindresorhus) for the [Emittery](https://npmjs.com/package/emittery) library. 🍻
|
|
18
|
-
|
|
19
17
|
## Installation
|
|
20
18
|
```bash
|
|
21
19
|
npm install hookified --save
|
|
22
20
|
```
|
|
23
21
|
|
|
24
22
|
## Usage
|
|
25
|
-
This was built because we constantly wanted hooks and events extended on libraires we are building such as [Keyv](https://keyv.org). This is a simple way to add hooks and events
|
|
23
|
+
This was built because we constantly wanted hooks and events extended on libraires we are building such as [Keyv](https://keyv.org) and [Cacheable](https://cacheable.org). This is a simple way to add hooks and events to your classes.
|
|
26
24
|
|
|
27
25
|
```javascript
|
|
28
26
|
import { Hookified } from 'hookified';
|
|
@@ -33,7 +31,7 @@ class MyClass extends Hookified {
|
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
async myMethodEmittingEvent() {
|
|
36
|
-
|
|
34
|
+
this.emit('message', 'Hello World'); //using Emittery
|
|
37
35
|
}
|
|
38
36
|
|
|
39
37
|
//with hooks you can pass data in and if they are subscribed via onHook they can modify the data
|
|
@@ -70,8 +68,6 @@ class MyClass extends Hookified {
|
|
|
70
68
|
|
|
71
69
|
## API
|
|
72
70
|
|
|
73
|
-
Please see the [Emittery](https://npmjs.com/package/emittery) documentation for more information on the event emitter.
|
|
74
|
-
|
|
75
71
|
### .onHook(eventName, handler)
|
|
76
72
|
|
|
77
73
|
Subscribe to a hook event.
|
|
@@ -94,6 +90,30 @@ Get all hooks for an event.
|
|
|
94
90
|
|
|
95
91
|
### .clearHooks(eventName)
|
|
96
92
|
|
|
93
|
+
### .on(eventName, handler)
|
|
94
|
+
|
|
95
|
+
Subscribe to an event.
|
|
96
|
+
|
|
97
|
+
### .off(eventName, handler)
|
|
98
|
+
|
|
99
|
+
Unsubscribe from an event.
|
|
100
|
+
|
|
101
|
+
### .emit(eventName, ...args)
|
|
102
|
+
|
|
103
|
+
Emit an event.
|
|
104
|
+
|
|
105
|
+
## .listeners(eventName)
|
|
106
|
+
|
|
107
|
+
Get all listeners for an event.
|
|
108
|
+
|
|
109
|
+
## .removeAllListeners(eventName)
|
|
110
|
+
|
|
111
|
+
Remove all listeners for an event.
|
|
112
|
+
|
|
113
|
+
## .setMaxListeners(maxListeners: number)
|
|
114
|
+
|
|
115
|
+
Set the maximum number of listeners and will truncate if there are already too many.
|
|
116
|
+
|
|
97
117
|
## Development and Testing
|
|
98
118
|
|
|
99
119
|
Hookified is written in TypeScript and tests are written in `vitest`. To run the tests, use the following command:
|
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,24 +15,91 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
31
21
|
var src_exports = {};
|
|
32
22
|
__export(src_exports, {
|
|
23
|
+
Eventified: () => Eventified,
|
|
33
24
|
Hookified: () => Hookified
|
|
34
25
|
});
|
|
35
26
|
module.exports = __toCommonJS(src_exports);
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
|
|
28
|
+
// src/eventified.ts
|
|
29
|
+
var Eventified = class {
|
|
30
|
+
_eventListeners;
|
|
31
|
+
_maxListeners;
|
|
32
|
+
constructor() {
|
|
33
|
+
this._eventListeners = /* @__PURE__ */ new Map();
|
|
34
|
+
this._maxListeners = 100;
|
|
35
|
+
}
|
|
36
|
+
maxListeners() {
|
|
37
|
+
return this._maxListeners;
|
|
38
|
+
}
|
|
39
|
+
// Add an event listener
|
|
40
|
+
addListener(event, listener) {
|
|
41
|
+
this.on(event, listener);
|
|
42
|
+
}
|
|
43
|
+
on(event, listener) {
|
|
44
|
+
if (!this._eventListeners.has(event)) {
|
|
45
|
+
this._eventListeners.set(event, []);
|
|
46
|
+
}
|
|
47
|
+
const listeners = this._eventListeners.get(event);
|
|
48
|
+
if (listeners) {
|
|
49
|
+
if (listeners.length >= this._maxListeners) {
|
|
50
|
+
console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event} listeners added. Use setMaxListeners() to increase limit.`);
|
|
51
|
+
}
|
|
52
|
+
listeners.push(listener);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Remove an event listener
|
|
56
|
+
removeListener(event, listener) {
|
|
57
|
+
this.off(event, listener);
|
|
58
|
+
}
|
|
59
|
+
off(event, listener) {
|
|
60
|
+
const listeners = this._eventListeners.get(event) ?? [];
|
|
61
|
+
const index = listeners.indexOf(listener);
|
|
62
|
+
if (index > -1) {
|
|
63
|
+
listeners.splice(index, 1);
|
|
64
|
+
}
|
|
65
|
+
if (listeners.length === 0) {
|
|
66
|
+
this._eventListeners.delete(event);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Emit an event
|
|
70
|
+
emit(event, ...arguments_) {
|
|
71
|
+
const listeners = this._eventListeners.get(event);
|
|
72
|
+
if (listeners && listeners.length > 0) {
|
|
73
|
+
for (const listener of listeners) {
|
|
74
|
+
listener(...arguments_);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Get all listeners for a specific event
|
|
79
|
+
listeners(event) {
|
|
80
|
+
return this._eventListeners.get(event) ?? [];
|
|
81
|
+
}
|
|
82
|
+
// Remove all listeners for a specific event
|
|
83
|
+
removeAllListeners(event) {
|
|
84
|
+
if (event) {
|
|
85
|
+
this._eventListeners.delete(event);
|
|
86
|
+
} else {
|
|
87
|
+
this._eventListeners.clear();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Set the maximum number of listeners for a single event
|
|
91
|
+
setMaxListeners(n) {
|
|
92
|
+
this._maxListeners = n;
|
|
93
|
+
for (const listeners of this._eventListeners.values()) {
|
|
94
|
+
if (listeners.length > n) {
|
|
95
|
+
listeners.splice(n);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// src/index.ts
|
|
102
|
+
var Hookified = class extends Eventified {
|
|
38
103
|
_hooks;
|
|
39
104
|
constructor() {
|
|
40
105
|
super();
|
|
@@ -67,7 +132,7 @@ var Hookified = class extends import_emittery.default {
|
|
|
67
132
|
try {
|
|
68
133
|
await handler(...arguments_);
|
|
69
134
|
} catch (error) {
|
|
70
|
-
|
|
135
|
+
this.emit("error", new Error(`Error in hook handler for event "${event}": ${error.message}`));
|
|
71
136
|
}
|
|
72
137
|
}
|
|
73
138
|
}
|
|
@@ -85,5 +150,6 @@ var Hookified = class extends import_emittery.default {
|
|
|
85
150
|
};
|
|
86
151
|
// Annotate the CommonJS export names for ESM import in node:
|
|
87
152
|
0 && (module.exports = {
|
|
153
|
+
Eventified,
|
|
88
154
|
Hookified
|
|
89
155
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
type EventListener = (...arguments_: any[]) => void;
|
|
2
|
+
declare class Eventified {
|
|
3
|
+
_eventListeners: Map<string, EventListener[]>;
|
|
4
|
+
_maxListeners: number;
|
|
5
|
+
constructor();
|
|
6
|
+
maxListeners(): number;
|
|
7
|
+
addListener(event: string, listener: EventListener): void;
|
|
8
|
+
on(event: string, listener: EventListener): void;
|
|
9
|
+
removeListener(event: string, listener: EventListener): void;
|
|
10
|
+
off(event: string, listener: EventListener): void;
|
|
11
|
+
emit(event: string, ...arguments_: any[]): void;
|
|
12
|
+
listeners(event: string): EventListener[];
|
|
13
|
+
removeAllListeners(event?: string): void;
|
|
14
|
+
setMaxListeners(n: number): void;
|
|
15
|
+
}
|
|
2
16
|
|
|
3
17
|
type Hook = (...arguments_: any[]) => Promise<void> | void;
|
|
4
|
-
declare class Hookified extends
|
|
18
|
+
declare class Hookified extends Eventified {
|
|
5
19
|
_hooks: Map<string, Hook[]>;
|
|
6
20
|
constructor();
|
|
7
21
|
onHook(event: string, handler: Hook): void;
|
|
@@ -12,4 +26,4 @@ declare class Hookified extends Emittery {
|
|
|
12
26
|
clearHooks(): void;
|
|
13
27
|
}
|
|
14
28
|
|
|
15
|
-
export { type Hook, Hookified };
|
|
29
|
+
export { type EventListener, Eventified, type Hook, Hookified };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
type EventListener = (...arguments_: any[]) => void;
|
|
2
|
+
declare class Eventified {
|
|
3
|
+
_eventListeners: Map<string, EventListener[]>;
|
|
4
|
+
_maxListeners: number;
|
|
5
|
+
constructor();
|
|
6
|
+
maxListeners(): number;
|
|
7
|
+
addListener(event: string, listener: EventListener): void;
|
|
8
|
+
on(event: string, listener: EventListener): void;
|
|
9
|
+
removeListener(event: string, listener: EventListener): void;
|
|
10
|
+
off(event: string, listener: EventListener): void;
|
|
11
|
+
emit(event: string, ...arguments_: any[]): void;
|
|
12
|
+
listeners(event: string): EventListener[];
|
|
13
|
+
removeAllListeners(event?: string): void;
|
|
14
|
+
setMaxListeners(n: number): void;
|
|
15
|
+
}
|
|
2
16
|
|
|
3
17
|
type Hook = (...arguments_: any[]) => Promise<void> | void;
|
|
4
|
-
declare class Hookified extends
|
|
18
|
+
declare class Hookified extends Eventified {
|
|
5
19
|
_hooks: Map<string, Hook[]>;
|
|
6
20
|
constructor();
|
|
7
21
|
onHook(event: string, handler: Hook): void;
|
|
@@ -12,4 +26,4 @@ declare class Hookified extends Emittery {
|
|
|
12
26
|
clearHooks(): void;
|
|
13
27
|
}
|
|
14
28
|
|
|
15
|
-
export { type Hook, Hookified };
|
|
29
|
+
export { type EventListener, Eventified, type Hook, Hookified };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,78 @@
|
|
|
1
|
+
// src/eventified.ts
|
|
2
|
+
var Eventified = class {
|
|
3
|
+
_eventListeners;
|
|
4
|
+
_maxListeners;
|
|
5
|
+
constructor() {
|
|
6
|
+
this._eventListeners = /* @__PURE__ */ new Map();
|
|
7
|
+
this._maxListeners = 100;
|
|
8
|
+
}
|
|
9
|
+
maxListeners() {
|
|
10
|
+
return this._maxListeners;
|
|
11
|
+
}
|
|
12
|
+
// Add an event listener
|
|
13
|
+
addListener(event, listener) {
|
|
14
|
+
this.on(event, listener);
|
|
15
|
+
}
|
|
16
|
+
on(event, listener) {
|
|
17
|
+
if (!this._eventListeners.has(event)) {
|
|
18
|
+
this._eventListeners.set(event, []);
|
|
19
|
+
}
|
|
20
|
+
const listeners = this._eventListeners.get(event);
|
|
21
|
+
if (listeners) {
|
|
22
|
+
if (listeners.length >= this._maxListeners) {
|
|
23
|
+
console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${listeners.length + 1} ${event} listeners added. Use setMaxListeners() to increase limit.`);
|
|
24
|
+
}
|
|
25
|
+
listeners.push(listener);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Remove an event listener
|
|
29
|
+
removeListener(event, listener) {
|
|
30
|
+
this.off(event, listener);
|
|
31
|
+
}
|
|
32
|
+
off(event, listener) {
|
|
33
|
+
const listeners = this._eventListeners.get(event) ?? [];
|
|
34
|
+
const index = listeners.indexOf(listener);
|
|
35
|
+
if (index > -1) {
|
|
36
|
+
listeners.splice(index, 1);
|
|
37
|
+
}
|
|
38
|
+
if (listeners.length === 0) {
|
|
39
|
+
this._eventListeners.delete(event);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Emit an event
|
|
43
|
+
emit(event, ...arguments_) {
|
|
44
|
+
const listeners = this._eventListeners.get(event);
|
|
45
|
+
if (listeners && listeners.length > 0) {
|
|
46
|
+
for (const listener of listeners) {
|
|
47
|
+
listener(...arguments_);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Get all listeners for a specific event
|
|
52
|
+
listeners(event) {
|
|
53
|
+
return this._eventListeners.get(event) ?? [];
|
|
54
|
+
}
|
|
55
|
+
// Remove all listeners for a specific event
|
|
56
|
+
removeAllListeners(event) {
|
|
57
|
+
if (event) {
|
|
58
|
+
this._eventListeners.delete(event);
|
|
59
|
+
} else {
|
|
60
|
+
this._eventListeners.clear();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Set the maximum number of listeners for a single event
|
|
64
|
+
setMaxListeners(n) {
|
|
65
|
+
this._maxListeners = n;
|
|
66
|
+
for (const listeners of this._eventListeners.values()) {
|
|
67
|
+
if (listeners.length > n) {
|
|
68
|
+
listeners.splice(n);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
1
74
|
// src/index.ts
|
|
2
|
-
|
|
3
|
-
var Hookified = class extends Emittery {
|
|
75
|
+
var Hookified = class extends Eventified {
|
|
4
76
|
_hooks;
|
|
5
77
|
constructor() {
|
|
6
78
|
super();
|
|
@@ -33,7 +105,7 @@ var Hookified = class extends Emittery {
|
|
|
33
105
|
try {
|
|
34
106
|
await handler(...arguments_);
|
|
35
107
|
} catch (error) {
|
|
36
|
-
|
|
108
|
+
this.emit("error", new Error(`Error in hook handler for event "${event}": ${error.message}`));
|
|
37
109
|
}
|
|
38
110
|
}
|
|
39
111
|
}
|
|
@@ -50,5 +122,6 @@ var Hookified = class extends Emittery {
|
|
|
50
122
|
}
|
|
51
123
|
};
|
|
52
124
|
export {
|
|
125
|
+
Eventified,
|
|
53
126
|
Hookified
|
|
54
127
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hookified",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Event and Middleware Hooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
},
|
|
27
27
|
"keywords": [
|
|
28
28
|
"hooks",
|
|
29
|
-
"emittery",
|
|
30
29
|
"eventemitter",
|
|
31
30
|
"eventemitter3",
|
|
32
31
|
"middleware",
|
|
@@ -37,7 +36,6 @@
|
|
|
37
36
|
"event-driven",
|
|
38
37
|
"event-emitter",
|
|
39
38
|
"hook-handlers",
|
|
40
|
-
"async-hooks",
|
|
41
39
|
"middleware",
|
|
42
40
|
"emit",
|
|
43
41
|
"event-management",
|
|
@@ -57,12 +55,9 @@
|
|
|
57
55
|
"url": "https://github.com/jaredwray/hookified/issues"
|
|
58
56
|
},
|
|
59
57
|
"homepage": "https://github.com/jaredwray/hookified#readme",
|
|
60
|
-
"dependencies": {
|
|
61
|
-
"emittery": "^1.0.3"
|
|
62
|
-
},
|
|
63
58
|
"devDependencies": {
|
|
64
59
|
"@vitest/coverage-v8": "^2.1.1",
|
|
65
|
-
"docula": "^0.9.
|
|
60
|
+
"docula": "^0.9.1",
|
|
66
61
|
"rimraf": "^6.0.1",
|
|
67
62
|
"tsup": "^8.3.0",
|
|
68
63
|
"typescript": "^5.6.2",
|