@anephenix/event-emitter 0.0.3
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/LICENSE +21 -0
- package/README.md +116 -0
- package/package.json +59 -0
- package/src/EventEmitter.ts +37 -0
- package/src/index.ts +2 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Anephenix
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
event-emitter
|
|
2
|
+
|
|
3
|
+
A small event emitter library, designed for use in front-end applications
|
|
4
|
+
like Svelte applications.
|
|
5
|
+
|
|
6
|
+
This provides a nice way to connect different parts of an application whilst
|
|
7
|
+
keeping the underlying components decoupled from each other.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```shell
|
|
12
|
+
npm i @anephenix/event-emitter
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// Load the dependency class
|
|
19
|
+
import EventEmitter from "@anephenix/event-emitter";
|
|
20
|
+
|
|
21
|
+
// Create an instance of the event emitter class with type safety
|
|
22
|
+
const eventEmitter = new EventEmitter();
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
We can now pass that eventEmitter instance to the places where we want to
|
|
26
|
+
either trigger an event or react to an event.
|
|
27
|
+
|
|
28
|
+
Whether you do that by loading the eventEmitter instance as a dependency
|
|
29
|
+
within a file, or by passing it as a parameter to a function is completely
|
|
30
|
+
up to you. The important thing is that you use the same eventEmitter
|
|
31
|
+
instance for handling the events that you want to trigger and react to.
|
|
32
|
+
|
|
33
|
+
### Triggering an event
|
|
34
|
+
|
|
35
|
+
To trigger an event, you call the `.emit` function on the eventEmitter
|
|
36
|
+
instance with the name of the event, and the data that you wish to pass along
|
|
37
|
+
with that event.
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
const data = { name: "John", text: "Hello" };
|
|
41
|
+
eventEmitter.emit("message", data);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Handling an event
|
|
45
|
+
|
|
46
|
+
To handle an event, you call the `.on` function on the eventEmitter instance
|
|
47
|
+
with the name of the event, and a listener function that handles the data payload
|
|
48
|
+
received when the event is triggered.
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
const messages = [];
|
|
52
|
+
|
|
53
|
+
function handleMessage(data: { name: string; text: string }) {
|
|
54
|
+
messages.push(data);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
eventEmitter.on("message", handleMessage);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
You can trigger and handle as many events as you like, and even add multiple
|
|
61
|
+
handler functions for the same event.
|
|
62
|
+
|
|
63
|
+
### Removing event handlers
|
|
64
|
+
|
|
65
|
+
To clean up event handlers that are no longer required (e.g. for a component
|
|
66
|
+
that is no longer in view), you can call the `.off` function with a reference
|
|
67
|
+
to the function that was passed to the `.on` function:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
eventEmitter.off("message", handleMessage);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Applying Type Safety to events names and their payloads
|
|
74
|
+
|
|
75
|
+
You may find that you'll want to add some type safety to the list of event
|
|
76
|
+
names that are used in your application, as well as the data payloads that
|
|
77
|
+
they emit and pass to handler functions.
|
|
78
|
+
|
|
79
|
+
The library allows you to define that by using a Type that is passed to the
|
|
80
|
+
setup of the EventEmitter instance, like this:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
interface MyEvents {
|
|
84
|
+
message: (data: string) => void;
|
|
85
|
+
join: (username: string) => void;
|
|
86
|
+
leave: (username: string) => void;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const emitter = new EventEmitter<MyEvents>();
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
This will then provide a way to ensure that calls to emit events and react to
|
|
93
|
+
them are type-checked:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
emitter.on('join', (username:string) => {
|
|
97
|
+
console.log(`${username} joined`);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
emitter.emit("join", "Alice");
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
This will help with preventing the misspelling of event names and also ensuring
|
|
104
|
+
that the event data payloads are correct.
|
|
105
|
+
|
|
106
|
+
## Tests
|
|
107
|
+
|
|
108
|
+
You can run the unit tests using this command:
|
|
109
|
+
|
|
110
|
+
```shell
|
|
111
|
+
npm t
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Licence and Credits
|
|
115
|
+
|
|
116
|
+
©2025 Anephenix OÜ. EventEmitter is licenced under the MIT licence.
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@anephenix/event-emitter",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "A small EventEmitter library",
|
|
5
|
+
"author": "Paul Jensen <paul@anephenix.com>",
|
|
6
|
+
"maintainers": [
|
|
7
|
+
{
|
|
8
|
+
"name": "Paul Jensen",
|
|
9
|
+
"email": "paul@anephenix.com"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"keywords": [
|
|
13
|
+
"event-emitter"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://github.com/anephenix/event-emitter#readme",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/anephenix/event-emitter/issues"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/anephenix/event-emitter.git"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "dist/index.js",
|
|
26
|
+
"typings": "dist/index.d.ts",
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"src"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc --project tsconfig.json",
|
|
33
|
+
"cover": "npx nyc --reporter=lcov --reporter=text-summary --nycrc-path=./.nyc.json -- npm t -- --coverage",
|
|
34
|
+
"lint": "biome lint",
|
|
35
|
+
"format": "biome format --fix",
|
|
36
|
+
"prepare": "husky install",
|
|
37
|
+
"prepare-patch-release": "npm run update-changelog && git add CHANGELOG.md && git commit -m \"Updated changelog\" && npm version patch",
|
|
38
|
+
"publish-patch-release": "npm run prepare-patch-release && git push origin main && git push --tags",
|
|
39
|
+
"size": "size-limit",
|
|
40
|
+
"test": "vitest --run",
|
|
41
|
+
"update-changelog": "node --experimental-strip-types scripts/update-changelog.ts"
|
|
42
|
+
},
|
|
43
|
+
"size-limit": [
|
|
44
|
+
{
|
|
45
|
+
"path": "dist/*.js",
|
|
46
|
+
"limit": "10 KB"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@biomejs/biome": "^1.9.4",
|
|
51
|
+
"@size-limit/esbuild-why": "^11.2.0",
|
|
52
|
+
"@size-limit/preset-small-lib": "^11.2.0",
|
|
53
|
+
"@vitest/coverage-v8": "^3.1.3",
|
|
54
|
+
"husky": "^9.1.7",
|
|
55
|
+
"size-limit": "^11.2.0",
|
|
56
|
+
"typescript": "^5.8.3",
|
|
57
|
+
"vitest": "^3.1.3"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Generic type for an event map where each key has a listener signature
|
|
2
|
+
type EventMap = Record<string, (...args: any[]) => void>;
|
|
3
|
+
|
|
4
|
+
class EventEmitter<T extends EventMap> {
|
|
5
|
+
private events: { [K in keyof T]?: T[K][] } = {};
|
|
6
|
+
enableLogging = false;
|
|
7
|
+
|
|
8
|
+
log(...args: unknown[]) {
|
|
9
|
+
if (this.enableLogging) {
|
|
10
|
+
console.log(...args);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
on<K extends keyof T>(event: K, listener: T[K]): void {
|
|
15
|
+
if (!this.events[event]) {
|
|
16
|
+
this.events[event] = [];
|
|
17
|
+
}
|
|
18
|
+
this.events[event]!.push(listener);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
off<K extends keyof T>(event: K, listener: T[K]): void {
|
|
22
|
+
const listeners = this.events[event];
|
|
23
|
+
if (!listeners) return;
|
|
24
|
+
this.events[event] = listeners.filter((l) => l !== listener);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
emit<K extends keyof T>(event: K, ...args: Parameters<T[K]>): void {
|
|
28
|
+
this.log("Emitting event:", event, "with args:", ...args);
|
|
29
|
+
const listeners = this.events[event];
|
|
30
|
+
if (!listeners) return;
|
|
31
|
+
for (const listener of listeners) {
|
|
32
|
+
listener(...args);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default EventEmitter;
|
package/src/index.ts
ADDED