@adonisjs/events 8.1.4-0 → 8.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 +2 -2
- package/build/src/emitter.d.ts +18 -13
- package/build/src/emitter.js +86 -55
- package/build/src/events_buffer.d.ts +7 -6
- package/build/src/events_buffer.js +14 -10
- package/build/src/types.d.ts +18 -9
- package/package.json +16 -16
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[![gh-workflow-image]][gh-workflow-url] [![npm-image]][npm-url] ![][typescript-image] [![license-image]][license-url] [![synk-image]][synk-url]
|
|
6
6
|
|
|
7
7
|
## Introduction
|
|
8
|
-
AdonisJS events is an implementation of the event emitter built on top of [emittery](https://github.com/sindresorhus/emittery). Alongside defining event listeners as inline callbacks, you can also bind modules to events and
|
|
8
|
+
AdonisJS events is an implementation of the event emitter built on top of [emittery](https://github.com/sindresorhus/emittery). Alongside defining event listeners as inline callbacks, you can also bind modules to events and define events as classes.
|
|
9
9
|
|
|
10
10
|
## Official Documentation
|
|
11
11
|
The documentation is available on the [AdonisJS website](https://docs.adonisjs.com/guides/events)
|
|
@@ -21,7 +21,7 @@ In order to ensure that the AdonisJS community is welcoming to all, please revie
|
|
|
21
21
|
## License
|
|
22
22
|
AdonisJS events is open-sourced software licensed under the [MIT license](LICENSE.md).
|
|
23
23
|
|
|
24
|
-
[gh-workflow-image]: https://img.shields.io/github/workflow/status/adonisjs/events/test?style=for-the-badge
|
|
24
|
+
[gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/events/test.yml?style=for-the-badge
|
|
25
25
|
[gh-workflow-url]: https://github.com/adonisjs/events/actions/workflows/test.yml "Github action"
|
|
26
26
|
|
|
27
27
|
[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
|
package/build/src/emitter.d.ts
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type
|
|
1
|
+
import type { Application } from '@adonisjs/application';
|
|
2
|
+
import { type UnsubscribeFunction } from 'emittery';
|
|
3
3
|
import { EventsBuffer } from './events_buffer.js';
|
|
4
|
+
import type { Listener, Constructor, ListenerMethod, AllowedEventTypes } from './types.js';
|
|
4
5
|
export declare class Emitter<EventsList extends Record<string | symbol | number, any>> {
|
|
5
6
|
#private;
|
|
7
|
+
get eventsListeners(): Map<AllowedEventTypes, Map<Listener<any, Constructor<any>>, ListenerMethod<any>>>;
|
|
6
8
|
constructor(app: Application<any, any>);
|
|
7
|
-
onError(callback: (event: keyof EventsList
|
|
8
|
-
on<
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
onError(callback: (event: keyof EventsList | Constructor<any>, error: any, data: any) => void): this;
|
|
10
|
+
on<Event extends Constructor<any>, ListenerClass extends Constructor<any>>(event: Event, listener: Listener<InstanceType<Event>, ListenerClass>): UnsubscribeFunction;
|
|
11
|
+
on<Name extends keyof EventsList, ListenerClass extends Constructor<any>>(event: Name, listener: Listener<EventsList[Name], ListenerClass>): UnsubscribeFunction;
|
|
12
|
+
once<Event extends Constructor<any>, ListenerClass extends Constructor<any>>(event: Event, listener: Listener<InstanceType<Event>, ListenerClass>): void;
|
|
13
|
+
once<Name extends keyof EventsList, ListenerClass extends Constructor<any>>(event: Name, listener: Listener<EventsList[Name], ListenerClass>): void;
|
|
14
|
+
onAny(listener: (event: AllowedEventTypes, data: any) => any | Promise<any>): UnsubscribeFunction;
|
|
15
|
+
emit<Event extends Constructor<any>>(event: Event, data: InstanceType<Event>): Promise<void>;
|
|
11
16
|
emit<Name extends keyof EventsList>(event: Name, data: EventsList[Name]): Promise<void>;
|
|
12
|
-
off
|
|
13
|
-
offAny(
|
|
14
|
-
clearListener
|
|
15
|
-
clearListeners(event: keyof EventsList): void;
|
|
17
|
+
off(event: keyof EventsList | Constructor<any>, listener: Listener<any, Constructor<any>>): void;
|
|
18
|
+
offAny(listener: (event: keyof EventsList | Constructor<any>, data: any) => any | Promise<any>): this;
|
|
19
|
+
clearListener(event: keyof EventsList | Constructor<any>, listener: Listener<any, Constructor<any>>): void;
|
|
20
|
+
clearListeners(event: keyof EventsList | Constructor<any>): void;
|
|
16
21
|
clearAllListeners(): void;
|
|
17
|
-
listenerCount
|
|
18
|
-
hasListeners
|
|
19
|
-
fake(events?: (keyof EventsList)[]): EventsBuffer<EventsList>;
|
|
22
|
+
listenerCount(event?: keyof EventsList | Constructor<any>): number;
|
|
23
|
+
hasListeners(event?: keyof EventsList | Constructor<any>): boolean;
|
|
24
|
+
fake(events?: (keyof EventsList | Constructor<any>)[]): EventsBuffer<EventsList>;
|
|
20
25
|
restore(): void;
|
|
21
26
|
}
|
package/build/src/emitter.js
CHANGED
|
@@ -1,68 +1,98 @@
|
|
|
1
|
+
import is from '@adonisjs/application/helpers/is';
|
|
1
2
|
import Emittery from 'emittery';
|
|
2
|
-
import { moduleExpression } from '@adonisjs/fold';
|
|
3
|
+
import { moduleExpression, moduleCaller, moduleImporter } from '@adonisjs/fold';
|
|
3
4
|
import debug from './debug.js';
|
|
4
5
|
import { EventsBuffer } from './events_buffer.js';
|
|
5
6
|
export class Emitter {
|
|
7
|
+
#eventsClassSymbols = new Map();
|
|
8
|
+
#eventsListeners = new Map();
|
|
6
9
|
#transport = new Emittery();
|
|
7
10
|
#eventsBuffer;
|
|
8
11
|
#eventsToFake = new Set();
|
|
9
12
|
#errorHandler;
|
|
10
|
-
#moduleListeners = new Map();
|
|
11
13
|
#app;
|
|
14
|
+
get eventsListeners() {
|
|
15
|
+
return this.#eventsListeners;
|
|
16
|
+
}
|
|
12
17
|
constructor(app) {
|
|
13
18
|
this.#app = app;
|
|
14
19
|
}
|
|
15
|
-
#
|
|
16
|
-
|
|
20
|
+
#getEventClassSymbol(event) {
|
|
21
|
+
if (!this.#eventsClassSymbols.has(event)) {
|
|
22
|
+
this.#eventsClassSymbols.set(event, Symbol(event.name));
|
|
23
|
+
}
|
|
24
|
+
return this.#eventsClassSymbols.get(event);
|
|
25
|
+
}
|
|
26
|
+
#resolveEvent(event) {
|
|
27
|
+
if (is.class_(event)) {
|
|
28
|
+
return this.#getEventClassSymbol(event);
|
|
29
|
+
}
|
|
30
|
+
return event;
|
|
17
31
|
}
|
|
18
|
-
#
|
|
19
|
-
if (!this.#
|
|
20
|
-
this.#
|
|
32
|
+
#getEventListeners(event) {
|
|
33
|
+
if (!this.#eventsListeners.has(event)) {
|
|
34
|
+
this.#eventsListeners.set(event, new Map());
|
|
21
35
|
}
|
|
22
|
-
return this.#
|
|
36
|
+
return this.#eventsListeners.get(event);
|
|
37
|
+
}
|
|
38
|
+
#normalizeEventListener(listener) {
|
|
39
|
+
if (typeof listener === 'string') {
|
|
40
|
+
return moduleExpression(listener, this.#app.appRoot).toCallable(this.#app.container);
|
|
41
|
+
}
|
|
42
|
+
if (Array.isArray(listener)) {
|
|
43
|
+
const listenerModule = listener[0];
|
|
44
|
+
const method = listener[1] || 'handle';
|
|
45
|
+
if (is.class_(listenerModule)) {
|
|
46
|
+
return moduleCaller(listenerModule, method).toCallable(this.#app.container);
|
|
47
|
+
}
|
|
48
|
+
return moduleImporter(listenerModule, method).toCallable(this.#app.container);
|
|
49
|
+
}
|
|
50
|
+
return listener;
|
|
51
|
+
}
|
|
52
|
+
#resolveEventListener(event, listener) {
|
|
53
|
+
const eventListeners = this.#getEventListeners(event);
|
|
54
|
+
if (!eventListeners.has(listener)) {
|
|
55
|
+
eventListeners.set(listener, this.#normalizeEventListener(listener));
|
|
56
|
+
}
|
|
57
|
+
return eventListeners.get(listener);
|
|
23
58
|
}
|
|
24
59
|
onError(callback) {
|
|
25
60
|
this.#errorHandler = callback;
|
|
26
61
|
return this;
|
|
27
62
|
}
|
|
28
|
-
on(event,
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
return this;
|
|
63
|
+
on(event, listener) {
|
|
64
|
+
if (debug.enabled) {
|
|
65
|
+
debug('registering event listener, event: %O, listener: %O', event, listener);
|
|
32
66
|
}
|
|
33
|
-
this.#
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
});
|
|
42
|
-
return this;
|
|
67
|
+
const normalizedEvent = this.#resolveEvent(event);
|
|
68
|
+
const normalizedListener = this.#resolveEventListener(event, listener);
|
|
69
|
+
this.#transport.on(normalizedEvent, normalizedListener);
|
|
70
|
+
return () => this.off(event, listener);
|
|
71
|
+
}
|
|
72
|
+
once(event, listener) {
|
|
73
|
+
if (debug.enabled) {
|
|
74
|
+
debug('registering one time event listener, event: %O, listener: %O', event, listener);
|
|
43
75
|
}
|
|
44
|
-
const
|
|
76
|
+
const normalizedEvent = this.#resolveEvent(event);
|
|
77
|
+
const normalizedListener = this.#normalizeEventListener(listener);
|
|
78
|
+
const off = this.#transport.on(normalizedEvent, async (data) => {
|
|
45
79
|
off();
|
|
46
|
-
|
|
80
|
+
debug('removing one time event listener, event: %O', event);
|
|
81
|
+
await normalizedListener(data);
|
|
47
82
|
});
|
|
48
|
-
return this;
|
|
49
83
|
}
|
|
50
|
-
onAny(
|
|
51
|
-
|
|
52
|
-
this.#transport.onAny(this.#getSetModuleListener(handler));
|
|
53
|
-
return this;
|
|
54
|
-
}
|
|
55
|
-
this.#transport.onAny(handler);
|
|
56
|
-
return this;
|
|
84
|
+
onAny(listener) {
|
|
85
|
+
return this.#transport.onAny(listener);
|
|
57
86
|
}
|
|
58
87
|
async emit(event, data) {
|
|
59
88
|
if (this.#eventsToFake.has(event) || this.#eventsToFake.has('*')) {
|
|
60
|
-
debug('faking emit. event:
|
|
61
|
-
this.#eventsBuffer.
|
|
89
|
+
debug('faking emit. event: %O, data: %O', event, data);
|
|
90
|
+
this.#eventsBuffer.add(event, data);
|
|
62
91
|
return;
|
|
63
92
|
}
|
|
64
93
|
try {
|
|
65
|
-
|
|
94
|
+
const normalizedEvent = this.#resolveEvent(event);
|
|
95
|
+
await this.#transport.emit(normalizedEvent, data);
|
|
66
96
|
}
|
|
67
97
|
catch (error) {
|
|
68
98
|
if (this.#errorHandler) {
|
|
@@ -73,37 +103,38 @@ export class Emitter {
|
|
|
73
103
|
}
|
|
74
104
|
}
|
|
75
105
|
}
|
|
76
|
-
off(event,
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
this.#transport.off(event, this.#moduleListeners.get(handler));
|
|
80
|
-
}
|
|
81
|
-
return this;
|
|
106
|
+
off(event, listener) {
|
|
107
|
+
if (debug.enabled) {
|
|
108
|
+
debug('removing listener, event: %O, listener: %O', event, listener);
|
|
82
109
|
}
|
|
83
|
-
this.#
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (this.#moduleListeners.has(handler)) {
|
|
89
|
-
this.#transport.offAny(this.#moduleListeners.get(handler));
|
|
90
|
-
}
|
|
91
|
-
return this;
|
|
110
|
+
const normalizedEvent = this.#resolveEvent(event);
|
|
111
|
+
const listeners = this.#getEventListeners(event);
|
|
112
|
+
const normalizedListener = listeners.get(listener);
|
|
113
|
+
if (!normalizedListener) {
|
|
114
|
+
return;
|
|
92
115
|
}
|
|
93
|
-
|
|
116
|
+
listeners.delete(listener);
|
|
117
|
+
this.#transport.off(normalizedEvent, normalizedListener);
|
|
118
|
+
}
|
|
119
|
+
offAny(listener) {
|
|
120
|
+
this.#transport.offAny(listener);
|
|
94
121
|
return this;
|
|
95
122
|
}
|
|
96
|
-
clearListener(event,
|
|
97
|
-
return this.off(event,
|
|
123
|
+
clearListener(event, listener) {
|
|
124
|
+
return this.off(event, listener);
|
|
98
125
|
}
|
|
99
126
|
clearListeners(event) {
|
|
100
|
-
|
|
127
|
+
debug('clearing all listeners for event %O', event);
|
|
128
|
+
this.#transport.clearListeners(this.#resolveEvent(event));
|
|
129
|
+
this.#eventsListeners.delete(event);
|
|
101
130
|
}
|
|
102
131
|
clearAllListeners() {
|
|
132
|
+
debug('clearing all event listeners');
|
|
103
133
|
this.#transport.clearListeners();
|
|
134
|
+
this.#eventsListeners.clear();
|
|
104
135
|
}
|
|
105
136
|
listenerCount(event) {
|
|
106
|
-
return this.#transport.listenerCount(event);
|
|
137
|
+
return this.#transport.listenerCount(event ? this.#resolveEvent(event) : undefined);
|
|
107
138
|
}
|
|
108
139
|
hasListeners(event) {
|
|
109
140
|
return this.listenerCount(event) > 0;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AllowedEventTypes, BufferedEvent, BufferedEventsList, Constructor } from './types.js';
|
|
2
2
|
export declare class EventsBuffer<EventsList extends Record<string | symbol | number, any>> {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
#private;
|
|
4
|
+
add<Name extends AllowedEventTypes>(event: Name, data: any): void;
|
|
5
|
+
all(): BufferedEventsList<EventsList>[];
|
|
5
6
|
size(): number;
|
|
6
|
-
exists
|
|
7
|
-
filter(finder: keyof EventsList | ((event:
|
|
8
|
-
find
|
|
7
|
+
exists<Event extends keyof EventsList | Constructor<any>>(finder: Event | ((event: BufferedEventsList<EventsList>) => boolean)): boolean;
|
|
8
|
+
filter(finder: keyof EventsList | Constructor<any> | ((event: BufferedEventsList<EventsList>) => boolean)): BufferedEventsList<EventsList>[];
|
|
9
|
+
find<Event extends keyof EventsList | Constructor<any>>(finder: Event | ((event: BufferedEventsList<EventsList>) => boolean)): (Event extends keyof EventsList ? BufferedEvent<Event, EventsList[Event]> : Event extends Constructor<infer A> ? BufferedEvent<Event, A> : BufferedEventsList<EventsList>) | null;
|
|
9
10
|
flush(): void;
|
|
10
11
|
}
|
|
@@ -1,27 +1,31 @@
|
|
|
1
|
+
import is from '@adonisjs/application/helpers/is';
|
|
1
2
|
export class EventsBuffer {
|
|
2
|
-
events = [];
|
|
3
|
+
#events = [];
|
|
4
|
+
add(event, data) {
|
|
5
|
+
this.#events.push({ event: event, data });
|
|
6
|
+
}
|
|
3
7
|
all() {
|
|
4
|
-
return this
|
|
8
|
+
return this.#events;
|
|
5
9
|
}
|
|
6
10
|
size() {
|
|
7
|
-
return this
|
|
11
|
+
return this.#events.length;
|
|
8
12
|
}
|
|
9
13
|
exists(finder) {
|
|
10
14
|
return !!this.find(finder);
|
|
11
15
|
}
|
|
12
16
|
filter(finder) {
|
|
13
|
-
if (typeof finder === 'function') {
|
|
14
|
-
return this
|
|
17
|
+
if (typeof finder === 'function' && !is.class_(finder)) {
|
|
18
|
+
return this.#events.filter(finder);
|
|
15
19
|
}
|
|
16
|
-
return this
|
|
20
|
+
return this.#events.filter((event) => event.event === finder);
|
|
17
21
|
}
|
|
18
22
|
find(finder) {
|
|
19
|
-
if (typeof finder === 'function') {
|
|
20
|
-
return this
|
|
23
|
+
if (typeof finder === 'function' && !is.class_(finder)) {
|
|
24
|
+
return (this.#events.find(finder) || null);
|
|
21
25
|
}
|
|
22
|
-
return this
|
|
26
|
+
return (this.#events.find((event) => event.event === finder) || null);
|
|
23
27
|
}
|
|
24
28
|
flush() {
|
|
25
|
-
this
|
|
29
|
+
this.#events = [];
|
|
26
30
|
}
|
|
27
31
|
}
|
package/build/src/types.d.ts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
export type
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
1
|
+
export type AllowedEventTypes = string | symbol | number | Constructor<any>;
|
|
2
|
+
export type Constructor<T> = new (...args: any[]) => T;
|
|
3
|
+
export type LazyImport<DefaultExport> = () => Promise<{
|
|
4
|
+
default: DefaultExport;
|
|
5
|
+
}>;
|
|
6
|
+
export type BufferedEvent<Event, Data> = {
|
|
7
|
+
event: Event;
|
|
8
|
+
data: Data;
|
|
9
|
+
};
|
|
10
|
+
export type BufferedEventsList<EventsList> = {
|
|
11
|
+
[Name in keyof EventsList]: BufferedEvent<Name, EventsList[Name]>;
|
|
12
|
+
}[keyof EventsList] | BufferedEvent<Constructor<any>, any>;
|
|
13
|
+
export type ListenerMethod<Data> = (data: Data, ...args: any[]) => any | Promise<any>;
|
|
14
|
+
export type ListenerFn<Data> = (data: Data) => any | Promise<any>;
|
|
15
|
+
export type GetListenersMethods<Listener extends Constructor<any>, Data> = {
|
|
16
|
+
[K in keyof InstanceType<Listener>]: InstanceType<Listener>[K] extends ListenerMethod<Data> ? K : never;
|
|
17
|
+
}[keyof InstanceType<Listener>];
|
|
18
|
+
export type Listener<Data, ListenerClass extends Constructor<any>> = ListenerFn<Data> | string | [LazyImport<ListenerClass> | ListenerClass, GetListenersMethods<ListenerClass, Data>?];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adonisjs/events",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.2.0-0",
|
|
4
4
|
"description": "An implementation of the event emitter built on top of emittery",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -37,33 +37,33 @@
|
|
|
37
37
|
"author": "virk,adonisjs",
|
|
38
38
|
"license": "MIT",
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@adonisjs/application": "^6.
|
|
41
|
-
"@adonisjs/config": "^4.1.
|
|
42
|
-
"@adonisjs/env": "^4.1.
|
|
43
|
-
"@adonisjs/fold": "^9.
|
|
44
|
-
"@adonisjs/logger": "^5.1.
|
|
45
|
-
"@commitlint/cli": "^17.
|
|
46
|
-
"@commitlint/config-conventional": "^17.
|
|
40
|
+
"@adonisjs/application": "^6.5.1-0",
|
|
41
|
+
"@adonisjs/config": "^4.1.3-0",
|
|
42
|
+
"@adonisjs/env": "^4.1.2-0",
|
|
43
|
+
"@adonisjs/fold": "^9.9.0-0",
|
|
44
|
+
"@adonisjs/logger": "^5.1.1-0",
|
|
45
|
+
"@commitlint/cli": "^17.4.0",
|
|
46
|
+
"@commitlint/config-conventional": "^17.4.0",
|
|
47
47
|
"@japa/assert": "^1.3.6",
|
|
48
48
|
"@japa/expect-type": "^1.0.2",
|
|
49
49
|
"@japa/run-failed-tests": "^1.1.0",
|
|
50
50
|
"@japa/runner": "^2.2.2",
|
|
51
51
|
"@japa/spec-reporter": "^1.3.2",
|
|
52
52
|
"@poppinss/dev-utils": "^2.0.1",
|
|
53
|
-
"@swc/core": "^1.3.
|
|
53
|
+
"@swc/core": "^1.3.24",
|
|
54
54
|
"@types/fs-extra": "^9.0.13",
|
|
55
|
-
"@types/node": "^18.11.
|
|
55
|
+
"@types/node": "^18.11.18",
|
|
56
56
|
"c8": "^7.12.0",
|
|
57
57
|
"cross-env": "^7.0.3",
|
|
58
58
|
"del-cli": "^5.0.0",
|
|
59
|
-
"eslint": "^8.
|
|
60
|
-
"eslint-config-prettier": "^8.
|
|
59
|
+
"eslint": "^8.31.0",
|
|
60
|
+
"eslint-config-prettier": "^8.6.0",
|
|
61
61
|
"eslint-plugin-adonis": "^3.0.3",
|
|
62
62
|
"eslint-plugin-prettier": "^4.2.1",
|
|
63
63
|
"fs-extra": "^11.1.0",
|
|
64
64
|
"github-label-sync": "^2.0.1",
|
|
65
|
-
"husky": "^8.0.
|
|
66
|
-
"np": "^7.6.
|
|
65
|
+
"husky": "^8.0.3",
|
|
66
|
+
"np": "^7.6.3",
|
|
67
67
|
"prettier": "^2.8.1",
|
|
68
68
|
"ts-node": "^10.9.1",
|
|
69
69
|
"typescript": "^4.9.4"
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
"emittery": "^1.0.1"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
|
-
"@adonisjs/application": "^6.
|
|
76
|
-
"@adonisjs/fold": "^9.
|
|
75
|
+
"@adonisjs/application": "^6.5.1-0",
|
|
76
|
+
"@adonisjs/fold": "^9.9.0-0"
|
|
77
77
|
},
|
|
78
78
|
"repository": {
|
|
79
79
|
"type": "git",
|