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 CHANGED
@@ -1,6 +1,6 @@
1
1
  <img src="site/logo.svg" alt="Hookified" height="400" align="center">
2
2
 
3
- # Async Event and Middleware Hooks
3
+ # Event Emitting and Async Middleware Hooks
4
4
 
5
5
  [![tests](https://github.com/jaredwray/hookified/actions/workflows/tests.yaml/badge.svg)](https://github.com/jaredwray/hookified/actions/workflows/tests.yaml)
6
6
  [![GitHub license](https://img.shields.io/github/license/jaredwray/hookified)](https://github.com/jaredwray/hookified/blob/master/LICENSE)
@@ -9,20 +9,18 @@
9
9
  [![npm](https://img.shields.io/npm/v/hookified)](https://npmjs.com/package/hookified)
10
10
 
11
11
  ## Features
12
- - Emit Events via [Emittery](https://npmjs.com/package/emittery)
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 (via [emittery](https://npmjs.com/package/emittery)) to your libraries.
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
- await this.emit('message', 'Hello World'); //using Emittery
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
- var import_emittery = __toESM(require("emittery"), 1);
37
- var Hookified = class extends import_emittery.default {
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
- await this.emit("error", new Error(`Error in hook handler for event "${event}": ${error.message}`));
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
- import Emittery from 'emittery';
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 Emittery {
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
- import Emittery from 'emittery';
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 Emittery {
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
- import Emittery from "emittery";
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
- await this.emit("error", new Error(`Error in hook handler for event "${event}": ${error.message}`));
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.0.0",
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.0",
60
+ "docula": "^0.9.1",
66
61
  "rimraf": "^6.0.1",
67
62
  "tsup": "^8.3.0",
68
63
  "typescript": "^5.6.2",