@eolthar/events 1.0.1 → 2.0.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 +65 -11
- package/main.js +113 -17
- package/package.json +4 -3
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -1,35 +1,89 @@
|
|
|
1
1
|
# @eolthar/events
|
|
2
|
-
A lightweight, high-performance event
|
|
2
|
+
A lightweight, high-performance event emitter for fast and scalable projects.
|
|
3
3
|
|
|
4
4
|
```
|
|
5
5
|
npm i @eolthar/events
|
|
6
6
|
```
|
|
7
7
|
|
|
8
|
+
## Benchmark
|
|
9
|
+
| Category | @eolthar/events | tseep | EventEmitter3 | NanoEvents | mitt |
|
|
10
|
+
| :-------------------------------- | --------------: | --------: | ------------: | ------------: | --------: |
|
|
11
|
+
| **1. Mass subscription and emit** | **4 151 932** | 3 875 026 | 3 225 172 | 3 774 587 | 3 276 026 |
|
|
12
|
+
| **2. Unsubscribe** | 6 198 889 | 6 286 916 | 4 384 381 | **7 885 637** | 5 295 300 |
|
|
13
|
+
| **3. on → emit → off** | 2 348 937 | 2 727 954 | 2 509 048 | **3 543 034** | 2 744 207 |
|
|
14
|
+
| **4. emit (0 arguments)** | **10 397 673** | 8 126 418 | 6 837 431 | 8 565 591 | 6 764 343 |
|
|
15
|
+
| **5. emit (5 arguments)** | **9 915 638** | 8 080 340 | 6 901 530 | 7 531 209 | 6 454 089 |
|
|
16
|
+
| **6. emit (10 arguments)** | **9 183 703** | 7 561 947 | 4 503 834 | 6 767 050 | 6 023 215 |
|
|
17
|
+
|
|
8
18
|
## Usage
|
|
9
19
|
```js
|
|
10
|
-
const {
|
|
20
|
+
const { Emitter } = require("@eolthar/events");
|
|
11
21
|
|
|
12
|
-
const emitter =
|
|
22
|
+
const emitter = new Emitter();
|
|
13
23
|
|
|
14
|
-
|
|
15
|
-
const off = emitter.on("hello", (name) => {
|
|
24
|
+
function handler(name) {
|
|
16
25
|
console.log(`Hello, ${name}!`);
|
|
17
|
-
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Subscribe to an event
|
|
29
|
+
emitter.on("hello", handler);
|
|
18
30
|
|
|
19
31
|
// Emit an event
|
|
20
32
|
emitter.emit("hello", "Alice"); // Hello, Alice!
|
|
21
33
|
|
|
22
34
|
// Unsubscribe from the event
|
|
23
|
-
off();
|
|
35
|
+
emitter.off("hello", handler);
|
|
24
36
|
|
|
25
37
|
// Emitting again won't call the listener
|
|
26
38
|
emitter.emit("hello", "Bob"); // nothing happens
|
|
27
39
|
```
|
|
28
40
|
|
|
29
41
|
## API
|
|
30
|
-
### `
|
|
42
|
+
### `new Emitter()`
|
|
31
43
|
Creates a new event emitter instance.
|
|
32
44
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
45
|
+
### `emitter.on(event, listener)`
|
|
46
|
+
Subscribes a listener to a named event.
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
emitter.on("data", (value) => console.log(value));
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### `emitter.off(event, listener)`
|
|
53
|
+
Removes a specific listener from an event.
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
function handler(value) {
|
|
57
|
+
console.log(value);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
emitter.on("data", handler);
|
|
61
|
+
emitter.off("data", handler);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### `emitter.once(event, listener)`
|
|
65
|
+
Subscribes a listener that is automatically removed after the first call. Returns the internal wrapper function, which can be passed to `off` to manually remove the listener before it fires.
|
|
66
|
+
|
|
67
|
+
```js
|
|
68
|
+
emitter.once("connect", () => console.log("connected!"));
|
|
69
|
+
emitter.emit("connect"); // connected!
|
|
70
|
+
emitter.emit("connect"); // nothing happens
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### `emitter.emit(event, ...args)`
|
|
74
|
+
Emits the specified event, calling all registered listeners in the order they were added.
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
emitter.emit("data", 1, 2, 3);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### `emitter.clear(event?)`
|
|
81
|
+
Removes all listeners for a specific event. If no event is provided, clears all events.
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
emitter.clear("data"); // removes all listeners for "data"
|
|
85
|
+
emitter.clear(); // removes everything
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## License
|
|
89
|
+
MIT
|
package/main.js
CHANGED
|
@@ -1,19 +1,115 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
const forge = new Map();
|
|
2
|
+
const sigs = new Map([
|
|
3
|
+
[0, ""],
|
|
4
|
+
[1, "a0"]
|
|
5
|
+
]);
|
|
6
|
+
|
|
7
|
+
function compile(pool, argc) {
|
|
8
|
+
const len = pool.length;
|
|
9
|
+
const stamp = len + "-" + argc;
|
|
10
|
+
const mold = forge.get(stamp);
|
|
11
|
+
if (mold !== undefined) return mold(pool);
|
|
12
|
+
let args = sigs.get(argc);
|
|
13
|
+
if (args === undefined) {
|
|
14
|
+
args = "a0";
|
|
15
|
+
for (let i = 1; i < argc; i++) args += ",a" + i;
|
|
16
|
+
sigs.set(argc, args);
|
|
17
|
+
}
|
|
18
|
+
let pins = "",
|
|
19
|
+
fire = "";
|
|
20
|
+
for (let i = 0; i < len; i++) {
|
|
21
|
+
pins += "var f" + i + "=c[" + i + "];";
|
|
22
|
+
fire += "f" + i + "(" + args + ");";
|
|
23
|
+
}
|
|
24
|
+
const nep = eval("(function(c){" + pins + "return function(" + args + "){" + fire + "}})");
|
|
25
|
+
forge.set(stamp, nep);
|
|
26
|
+
return nep(pool);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
class Emitter {
|
|
30
|
+
constructor() {
|
|
31
|
+
this.events = new Map();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
on(event, listener) {
|
|
35
|
+
let e = this.events.get(event);
|
|
36
|
+
if (!e) {
|
|
37
|
+
this.events.set(event, { exec: listener, arity: listener.length, pool: null });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (e.pool === null) {
|
|
41
|
+
e.pool = [e.exec, listener];
|
|
42
|
+
} else {
|
|
43
|
+
e.pool.push(listener);
|
|
44
|
+
}
|
|
45
|
+
if (listener.length > e.arity) e.arity = listener.length;
|
|
46
|
+
e.exec = compile(e.pool, e.arity);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
off(event, listener) {
|
|
50
|
+
const e = this.events.get(event);
|
|
51
|
+
if (!e) return;
|
|
52
|
+
if (e.pool === null) {
|
|
53
|
+
if (e.exec === listener) this.events.delete(event);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const pool = e.pool;
|
|
57
|
+
const idx = pool.indexOf(listener);
|
|
58
|
+
if (idx === -1) return;
|
|
59
|
+
const last = pool[pool.length - 1];
|
|
60
|
+
if (last !== listener) pool[idx] = last;
|
|
61
|
+
pool.pop();
|
|
62
|
+
if (pool.length === 1) {
|
|
63
|
+
const single = pool[0];
|
|
64
|
+
e.exec = single;
|
|
65
|
+
e.arity = single.length;
|
|
66
|
+
e.pool = null;
|
|
67
|
+
} else {
|
|
68
|
+
if (listener.length >= e.arity) {
|
|
69
|
+
let max = 0;
|
|
70
|
+
for (let i = 0; i < pool.length; i++) {
|
|
71
|
+
if (pool[i].length > max) max = pool[i].length;
|
|
72
|
+
}
|
|
73
|
+
e.arity = max;
|
|
74
|
+
}
|
|
75
|
+
e.exec = compile(e.pool, e.arity);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
clear(event) {
|
|
80
|
+
if (event === undefined) {
|
|
81
|
+
this.events.clear();
|
|
82
|
+
} else {
|
|
83
|
+
this.events.delete(event);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
once(event, listener) {
|
|
88
|
+
const self = this;
|
|
89
|
+
let called = false;
|
|
90
|
+
const wrapper = function () {
|
|
91
|
+
if (called) return;
|
|
92
|
+
called = true;
|
|
93
|
+
self.off(event, wrapper);
|
|
94
|
+
listener.apply(undefined, arguments);
|
|
95
|
+
};
|
|
96
|
+
Object.defineProperty(wrapper, "length", { value: listener.length });
|
|
97
|
+
this.on(event, wrapper);
|
|
98
|
+
return wrapper;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
emit(event, a, b, c, d, f) {
|
|
102
|
+
const e = this.events.get(event);
|
|
103
|
+
if (!e) return;
|
|
104
|
+
const l = e.arity;
|
|
105
|
+
if (l < 6) {
|
|
106
|
+
e.exec(a, b, c, d, f);
|
|
107
|
+
} else {
|
|
108
|
+
const r = new Array(l);
|
|
109
|
+
for (let i = 0; i < l; i++) r[i] = arguments[i + 1];
|
|
110
|
+
e.exec.apply(undefined, r);
|
|
15
111
|
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
18
114
|
|
|
19
|
-
module.exports = {
|
|
115
|
+
module.exports = { Emitter };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eolthar/events",
|
|
3
|
-
"description": "A lightweight, high-performance event
|
|
4
|
-
"version": "
|
|
3
|
+
"description": "A lightweight, high-performance event emitter for fast and scalable projects.",
|
|
4
|
+
"version": "2.0.0",
|
|
5
5
|
"main": "main.js",
|
|
6
6
|
"author": "Mlad (https://github.com/eolthar)",
|
|
7
7
|
"repository": "https://github.com/eolthar/events",
|
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
"events",
|
|
11
11
|
"emitter",
|
|
12
12
|
"eventemitter",
|
|
13
|
+
"emit",
|
|
13
14
|
"pubsub",
|
|
14
|
-
"
|
|
15
|
+
"fast",
|
|
15
16
|
"performance"
|
|
16
17
|
]
|
|
17
18
|
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Mlad
|
|
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.
|