1
0
mirror of https://github.com/robonen/tools.git synced 2026-03-20 19:04:46 +00:00

feat(packages/stdlib): add PubSub class and tests to patterns

This commit is contained in:
2024-04-16 16:32:56 +07:00
parent fb76d11725
commit f987f722df
2 changed files with 153 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
export type Subscriber = (...args: any[]) => void;
export type EventsRecord = Record<string, Subscriber>;
export class PubSub<Events extends EventsRecord> {
private events: Map<keyof Events, Set<Events[keyof Events]>>;
constructor() {
this.events = new Map();
}
public on<K extends keyof Events>(event: K, listener: Events[K]) {
const listeners = this.events.get(event);
if (listeners)
listeners.add(listener);
else
this.events.set(event, new Set([listener]));
return this;
}
public off<K extends keyof Events>(event: K, listener: Events[K]) {
const listeners = this.events.get(event);
if (listeners)
listeners.delete(listener);
return this;
}
public once<K extends keyof Events>(event: K, listener: Events[K]) {
const onceListener = (...args: Parameters<Events[K]>) => {
this.off(event, onceListener as Events[K]);
listener(...args);
};
this.on(event, onceListener as Events[K]);
return this;
}
public emit<K extends keyof Events>(event: K, ...args: Parameters<Events[K]>): boolean {
const listeners = this.events.get(event);
if (!listeners)
return false;
listeners.forEach((listener) => listener(...args));
return true;
}
public clear<K extends keyof Events>(event: K) {
this.events.delete(event);
return this;
}
}