mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 04:27:21 +00:00
refactor event listener registration
unified listener creation logic under `createEventListener`, adding support for a flexible `RegisterListenerConfig`. Updated associated tests and improved error handling for unregistered events.
This commit is contained in:
@@ -61,6 +61,9 @@ describe("EventManager", async () => {
|
|||||||
"sync"
|
"sync"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// don't allow unknown
|
||||||
|
expect(() => emgr.on("unknown", () => void 0)).toThrow();
|
||||||
|
|
||||||
emgr.onEvent(InformationalEvent, async (event, name) => {
|
emgr.onEvent(InformationalEvent, async (event, name) => {
|
||||||
call();
|
call();
|
||||||
expect(name).toBe("informational-event");
|
expect(name).toBe("informational-event");
|
||||||
@@ -135,14 +138,14 @@ describe("EventManager", async () => {
|
|||||||
const call = mock(() => null);
|
const call = mock(() => null);
|
||||||
const emgr = new EventManager({ InformationalEvent });
|
const emgr = new EventManager({ InformationalEvent });
|
||||||
|
|
||||||
emgr.onEventOnce(
|
emgr.onEvent(
|
||||||
InformationalEvent,
|
InformationalEvent,
|
||||||
async (event, slug) => {
|
async (event, slug) => {
|
||||||
expect(event).toBeInstanceOf(InformationalEvent);
|
expect(event).toBeInstanceOf(InformationalEvent);
|
||||||
expect(slug).toBe("informational-event");
|
expect(slug).toBe("informational-event");
|
||||||
call();
|
call();
|
||||||
},
|
},
|
||||||
"sync"
|
{ mode: "sync", once: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(emgr.getListeners().length).toBe(1);
|
expect(emgr.getListeners().length).toBe(1);
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
import { type Event, InvalidEventReturn } from "./Event";
|
import { type Event, InvalidEventReturn } from "./Event";
|
||||||
import { EventListener, type ListenerHandler, type ListenerMode } from "./EventListener";
|
import { EventListener, type ListenerHandler, type ListenerMode } from "./EventListener";
|
||||||
|
|
||||||
|
export type RegisterListenerConfig =
|
||||||
|
| ListenerMode
|
||||||
|
| {
|
||||||
|
mode?: ListenerMode;
|
||||||
|
once?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
export interface EmitsEvents {
|
export interface EmitsEvents {
|
||||||
emgr: EventManager;
|
emgr: EventManager;
|
||||||
}
|
}
|
||||||
@@ -86,9 +93,11 @@ export class EventManager<
|
|||||||
return !!this.events.find((e) => slug === e.slug);
|
return !!this.events.find((e) => slug === e.slug);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected throwIfEventNotRegistered(event: EventClass) {
|
protected throwIfEventNotRegistered(event: EventClass | Event | string) {
|
||||||
if (!this.eventExists(event)) {
|
if (!this.eventExists(event as any)) {
|
||||||
throw new Error(`Event "${event.slug}" not registered`);
|
// @ts-expect-error
|
||||||
|
const name = event.constructor?.slug ?? event.slug ?? event;
|
||||||
|
throw new Error(`Event "${name}" not registered`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,44 +130,39 @@ export class EventManager<
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
onEvent<ActualEvent extends EventClass, Instance extends InstanceType<ActualEvent>>(
|
protected createEventListener(
|
||||||
event: ActualEvent,
|
_event: EventClass | string,
|
||||||
handler: ListenerHandler<Instance>,
|
handler: ListenerHandler<any>,
|
||||||
mode: ListenerMode = "async"
|
_config: RegisterListenerConfig = "async"
|
||||||
) {
|
) {
|
||||||
this.throwIfEventNotRegistered(event);
|
const event =
|
||||||
|
typeof _event === "string" ? this.events.find((e) => e.slug === _event)! : _event;
|
||||||
const listener = new EventListener(event, handler, mode);
|
const config = typeof _config === "string" ? { mode: _config } : _config;
|
||||||
|
const listener = new EventListener(event, handler, config.mode);
|
||||||
|
if (config.once) {
|
||||||
|
listener.once = true;
|
||||||
|
}
|
||||||
this.addListener(listener as any);
|
this.addListener(listener as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
onEventOnce<ActualEvent extends EventClass, Instance extends InstanceType<ActualEvent>>(
|
onEvent<ActualEvent extends EventClass, Instance extends InstanceType<ActualEvent>>(
|
||||||
event: ActualEvent,
|
event: ActualEvent,
|
||||||
handler: ListenerHandler<Instance>,
|
handler: ListenerHandler<Instance>,
|
||||||
mode: ListenerMode = "async"
|
config?: RegisterListenerConfig
|
||||||
) {
|
) {
|
||||||
this.throwIfEventNotRegistered(event);
|
this.createEventListener(event, handler, config);
|
||||||
|
|
||||||
const listener = new EventListener(event, handler, mode);
|
|
||||||
listener.once = true;
|
|
||||||
this.addListener(listener as any);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
on<Params = any>(
|
on<Params = any>(
|
||||||
slug: string,
|
slug: string,
|
||||||
handler: ListenerHandler<Event<Params>>,
|
handler: ListenerHandler<Event<Params>>,
|
||||||
mode: ListenerMode = "async"
|
config?: RegisterListenerConfig
|
||||||
) {
|
) {
|
||||||
const event = this.events.find((e) => e.slug === slug);
|
this.createEventListener(slug, handler, config);
|
||||||
if (!event) {
|
|
||||||
throw new Error(`Event "${slug}" not registered`);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.onEvent(event, handler, mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onAny(handler: ListenerHandler<Event<unknown>>, mode: ListenerMode = "async") {
|
onAny(handler: ListenerHandler<Event<unknown>>, config?: RegisterListenerConfig) {
|
||||||
this.events.forEach((event) => this.onEvent(event, handler, mode));
|
this.events.forEach((event) => this.onEvent(event, handler, config));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected executeAsyncs(promises: (() => Promise<void>)[]) {
|
protected executeAsyncs(promises: (() => Promise<void>)[]) {
|
||||||
|
|||||||
Reference in New Issue
Block a user