diff --git a/LICENSE b/LICENSE
index 528d47b..be87f15 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,4 @@
-MIT License
-
-Copyright (c) Jared Wray
+MIT License & © Jared Wray
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 03fddc9..fd24dfc 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-# Event and Middleware Hooks for Your Libraries
+# Async Event and Middleware Hooks
[![tests](https://github.com/jaredwray/hookified/actions/workflows/tests.yaml/badge.svg)](https://github.com/jaredwray/hookified/actions/workflows/tests.yaml)
[![GitHub license](https://img.shields.io/github/license/jaredwray/hookified)](https://github.com/jaredwray/hookified/blob/master/LICENSE)
@@ -10,10 +10,12 @@
## Features
- Emit Events via [Emittery](https://npmjs.com/package/emittery)
-- Middleware Hooks with data passing
+- Async Middleware Hooks for Your Methods
- ESM and Nodejs 20+
- Maintained on a regular basis!
+Special thanks to [@sindresorhus](https://github.com/sindresorhus) for the [Emittery](https://npmjs.com/package/emittery) library. 🍻
+
## Installation
```bash
npm install hookified --save
@@ -31,7 +33,7 @@ class MyClass extends Hookified {
}
async myMethodEmittingEvent() {
- await this.emit('message', 'Hello World');
+ await this.emit('message', 'Hello World'); //using Emittery
}
//with hooks you can pass data in and if they are subscribed via onHook they can modify the data
@@ -43,5 +45,71 @@ class MyClass extends Hookified {
return data;
}
}
+```
+
+You can even pass in multiple arguments to the hooks:
+
+```javascript
+import { Hookified } from 'hookified';
+
+class MyClass extends Hookified {
+ constructor() {
+ super();
+ }
+
+ async myMethodWithHooks() Promise {
+ let data = { some: 'data' };
+ let data2 = { some: 'data2' };
+ // do something
+ await this.hook('before:myMethod2', data, data2);
+
+ return data;
+ }
+}
+```
+
+## API
+
+Please see the [Emittery](https://npmjs.com/package/emittery) documentation for more information on the event emitter.
+
+### .onHook(eventName, handler)
+
+Subscribe to a hook event.
+
+### .removeHook(eventName)
+
+Unsubscribe from a hook event.
+
+### .hook(eventName, ...args)
+
+Run a hook event.
+
+### .hooks
+
+Get all hooks.
+
+### .getHooks(eventName)
+
+Get all hooks for an event.
+
+### .clearHooks(eventName)
+
+## Development and Testing
+
+Hookified is written in TypeScript and tests are written in `vitest`. To run the tests, use the following command:
+
+To setup the environment and run the tests:
+
+```bash
+npm i && npm test
+```
+
+To contribute follow the [Contributing Guidelines](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md).
+
+## License
+
+[MIT & © Jared Wray](LICENSE)
+
+
diff --git a/package.json b/package.json
index ea9c176..e1b64ac 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "hookified",
- "version": "0.6.0",
+ "version": "0.7.0",
"description": "Event and Middleware Hooks",
"type": "module",
"main": "./dist/index.js",
diff --git a/src/index.ts b/src/index.ts
index 5788283..fc030ab 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -11,7 +11,7 @@ export class Hookified extends Emittery {
}
// Adds a handler function for a specific event
- async onHook(event: string, handler: Hook) {
+ onHook(event: string, handler: Hook) {
const eventHandlers = this._hooks.get(event);
if (eventHandlers) {
eventHandlers.push(handler);
@@ -21,7 +21,7 @@ export class Hookified extends Emittery {
}
// Removes a specific handler function for a specific event
- async removeHook(event: string, handler: Hook) {
+ removeHook(event: string, handler: Hook) {
const eventHandlers = this._hooks.get(event);
if (eventHandlers) {
const index = eventHandlers.indexOf(handler);
@@ -52,4 +52,12 @@ export class Hookified extends Emittery {
// Creating a new map to prevent external modifications to the original map
return this._hooks;
}
+
+ getHooks(event: string) {
+ return this._hooks.get(event);
+ }
+
+ clearHooks() {
+ this._hooks.clear();
+ }
}
diff --git a/test/index.test.ts b/test/index.test.ts
index 2c10869..c99c4cd 100644
--- a/test/index.test.ts
+++ b/test/index.test.ts
@@ -13,21 +13,35 @@ describe('Hookified', () => {
const handler = () => {};
// eslint-disable-next-line @typescript-eslint/no-empty-function
const handler2 = () => {};
- await hookified.onHook('event', handler);
- await hookified.onHook('event2', handler2);
- expect(hookified.hooks.get('event')).toEqual([handler]);
- expect(hookified.hooks.get('event2')).toEqual([handler2]);
+ hookified.onHook('event', handler);
+ hookified.onHook('event2', handler2);
+ expect(hookified.getHooks('event')).toEqual([handler]);
+ expect(hookified.getHooks('event2')).toEqual([handler2]);
expect(hookified.hooks.size).toBe(2);
});
+ test('onHook with Clear', async () => {
+ const hookified = new Hookified();
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ const handler = () => {};
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ const handler2 = () => {};
+ hookified.onHook('event', handler);
+ hookified.onHook('event2', handler2);
+ expect(hookified.getHooks('event')).toEqual([handler]);
+ expect(hookified.getHooks('event2')).toEqual([handler2]);
+ hookified.clearHooks();
+ expect(hookified.hooks.size).toBe(0);
+ });
+
test('onHook multiple handlers', async () => {
const hookified = new Hookified();
// eslint-disable-next-line @typescript-eslint/no-empty-function
const handler = () => {};
// eslint-disable-next-line @typescript-eslint/no-empty-function
const handler2 = () => {};
- await hookified.onHook('event', handler);
- await hookified.onHook('event', handler2);
+ hookified.onHook('event', handler);
+ hookified.onHook('event', handler2);
expect(hookified.hooks.get('event')).toEqual([handler, handler2]);
expect(hookified.hooks.size).toBe(1);
});
@@ -38,10 +52,10 @@ describe('Hookified', () => {
const handler = () => {};
// eslint-disable-next-line @typescript-eslint/no-empty-function
const handler2 = () => {};
- await hookified.onHook('event', handler);
- await hookified.onHook('event', handler2);
- await hookified.removeHook('event', handler);
- expect(hookified.hooks.get('event')).toEqual([handler2]);
+ hookified.onHook('event', handler);
+ hookified.onHook('event', handler2);
+ hookified.removeHook('event', handler);
+ expect(hookified.getHooks('event')).toEqual([handler2]);
expect(hookified.hooks.size).toBe(1);
});
@@ -56,7 +70,7 @@ describe('Hookified', () => {
handlerData = data;
};
- await hookified.onHook('event', handler);
+ hookified.onHook('event', handler);
await hookified.hook('event', data);
expect(handlerData.key).toBe('modified');
});
@@ -78,7 +92,7 @@ describe('Hookified', () => {
console.log(handlerData);
};
- await hookified.onHook('event', handler);
+ hookified.onHook('event', handler);
await hookified.hook('event', data, data2, data3);
expect(handlerData[0].key).toBe('modified');
expect(handlerData[1].key).toBe('foo');
@@ -94,13 +108,12 @@ describe('Hookified', () => {
});
const data = {key: 'value'};
- let handlerData;
- const handler = (data: any) => {
+ const handler = () => {
throw new Error('error');
};
- await hookified.onHook('event', handler);
+ hookified.onHook('event', handler);
await hookified.hook('event', data);
expect(errorMessage).toBe('Error in hook handler for event "event": error');
});