Skip to content

Commit

Permalink
Merge pull request #9 from duxcore/add-any
Browse files Browse the repository at this point in the history
Added `Any` event listener
  • Loading branch information
HoloPanio authored Nov 3, 2023
2 parents ec853d4 + 14696a1 commit 7631f44
Show file tree
Hide file tree
Showing 5 changed files with 780 additions and 649 deletions.
70 changes: 42 additions & 28 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import ListenerArray from "./lib/ListenerArray";
import { DefaultListener, ListenerSignature } from "./types/events";
import { AnyListenerCallback } from "./types/types";

export class Eventra<Events extends ListenerSignature<Events> = DefaultListener> {

export class Eventra<
Events extends ListenerSignature<Events> = DefaultListener
> {
public constructor() {}

private _listeners = new ListenerArray({ mode: "recurring" });
private _singularListeners = new ListenerArray({ mode: "once" });

Expand All @@ -23,14 +25,14 @@ export class Eventra<Events extends ListenerSignature<Events> = DefaultListener>
*/
emit<E extends keyof Events>(event: E, ...args: Parameters<Events[E]>) {
this._listeners.executeEvent(event, ...args);
this._singularListeners.executeEvent(event, ...args)
this._singularListeners.executeEvent(event, ...args);
}

/**
* Returns an array listing the events for which the emitter has registered listeners.
*/
eventNames<E extends keyof Events>(): E[] {
let finalNamesArray: E[] = []
let finalNamesArray: E[] = [];

this._listeners.storage.map((val, key) => {
if (!finalNamesArray.includes(key)) finalNamesArray.push(key);
Expand All @@ -43,17 +45,16 @@ export class Eventra<Events extends ListenerSignature<Events> = DefaultListener>
return finalNamesArray;
}


/**
* Returns the number of listeners listening to the event.
*/
listenerCount<E extends keyof Events>(eventName: E): number {
const recurring = this._listeners.countListeners(eventName);
const singular = this._singularListeners.countListeners(eventName);

return (recurring + singular);
return recurring + singular;
}

/**
* Returns a copy of the array of listeners for the event.
*/
Expand All @@ -63,14 +64,20 @@ export class Eventra<Events extends ListenerSignature<Events> = DefaultListener>

return {
recurring,
singular
}
singular,
};
}
/**
* Adds a listener that will callback after every single event execution.
*/
any(listener: AnyListenerCallback) {
this._listeners.addAny(listener);
return this;
}


/**
* Adds the listener function to the end of the listeners array for the event.
*
* Adds the listener function to the end of the listeners array for the event.
*
* Returns a reference to the eventra instance, so that calls can be chained.
*/
on<E extends keyof Events>(eventName: E, listener: Events[E]): this {
Expand All @@ -81,46 +88,50 @@ export class Eventra<Events extends ListenerSignature<Events> = DefaultListener>
/**
* Adds a one-time listener function for the event.
* The next time the event is triggered, this listener is removed and then invoked.
*
*
* Returns a reference to the eventra instance, so that calls can be chained.
*/
once<E extends keyof Events>(eventName: E, listener: Events[E]): this {
this._singularListeners.add(eventName, listener);
return this;
}


/**
* Adds the listener function to the beginning of the listeners array for the event.
*
*
* Returns a reference to the eventra instance, so that calls can be chained.
*/
prependListener<E extends keyof Events>(eventName: E, listener: Events[E]): this {
prependListener<E extends keyof Events>(
eventName: E,
listener: Events[E]
): this {
this._listeners.prepend(eventName, listener);
return this;
}

/**
* Adds a one-time listener function for the event to the beginning of the listeners array.
* The next time the event is triggered, this listener is removed, and then invoked.
*
*
* Returns a reference to the eventra instance, so that calls can be chained.
*/
prependOnceListener<E extends keyof Events>(eventName: E, listener: Events[E]): this {
prependOnceListener<E extends keyof Events>(
eventName: E,
listener: Events[E]
): this {
this._singularListeners.prepend(eventName, listener);
return this;
}


/**
* Removes all listeners, or those of the specified event(s).
*
*
* Returns a reference to the eventra instance, so that calls can be chained.
*/
removeAllListeners<E extends keyof Events>(...eventName: E[]): this {
const listeners: E[] = [...eventName];
const listeners: E[] = [...eventName];

listeners.map(en => {
listeners.map((en) => {
this._listeners.removeEvent(en);
this._singularListeners.removeEvent(en);
});
Expand All @@ -130,13 +141,16 @@ export class Eventra<Events extends ListenerSignature<Events> = DefaultListener>

/**
* Removes the specified listener from the listener array for the event.
*
*
* Returns a reference to the eventra instance, so that calls can be chained.
*/
removeListener<E extends keyof Events>(eventName: E, listener: Events[E]): this {
*/
removeListener<E extends keyof Events>(
eventName: E,
listener: Events[E]
): this {
this._listeners.removeListener(eventName, listener);
this._singularListeners.removeListener(eventName, listener);

return this;
}
}
}
38 changes: 27 additions & 11 deletions src/lib/ListenerArray.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
import { ListenerArrayMode, ListenerArrayOptions, ListenerCallback } from "../types/types";
import {
AnyListenerCallback,
ListenerArrayMode,
ListenerArrayOptions,
ListenerCallback,
} from "../types/types";
import Collection from "../util/Collection";

type CollectionType = Collection<string | any, ListenerCallback[]>;

export default class ListenerArray {

private _options: ListenerArrayOptions;
private _internalStorage = new Collection<string, ListenerCallback[]>()
private _internalStorage = new Collection<string, ListenerCallback[]>();
private _anyListeners: AnyListenerCallback[] = [];

constructor(options?: ListenerArrayOptions) {
if (!options) this._options = { mode: "recurring" }
if (!options) this._options = { mode: "recurring" };
else this._options = options;
}

get mode(): ListenerArrayMode { return this._options.mode; }
get storage(): CollectionType { return this._internalStorage; }
get mode(): ListenerArrayMode {
return this._options.mode;
}
get storage(): CollectionType {
return this._internalStorage;
}

private _updateInternalStorage(collection: CollectionType) {
if (!collection) return;
Expand Down Expand Up @@ -42,6 +51,11 @@ export default class ListenerArray {
return this;
}

addAny(listener: ListenerCallback): this {
this._anyListeners.push(listener);
return this;
}

prepend(eventName: string | any, listener: ListenerCallback): this {
let carbonCopy = this._cloneInternalStorage();
let event = carbonCopy.get(eventName);
Expand All @@ -63,13 +77,13 @@ export default class ListenerArray {

if (!event) return this;
if (!event.includes(listener)) return this;

if (event.length == 1) {
carbonCopy.delete(eventName);
this._updateInternalStorage(carbonCopy);
return this;
};
}

const index = event.indexOf(listener);
if (index > -1) event.splice(index, 1);

Expand Down Expand Up @@ -105,16 +119,18 @@ export default class ListenerArray {
let carbonCopy = this._cloneInternalStorage();
let event = carbonCopy.get(eventName);

this._anyListeners.map((listener) => listener(eventName, ...args));

if (!event) return this;

event.map((method, index) => {
method(...args);
return;
});

if (this.mode == 'once') carbonCopy.delete(eventName);
if (this.mode == "once") carbonCopy.delete(eventName);
this._updateInternalStorage(carbonCopy);

return this;
}
}
}
5 changes: 3 additions & 2 deletions src/types/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export type ListenerCallback = (...args) => void;
export type AnyListenerCallback = (eventName: string, ...args) => void;

export type ListenerArrayMode = "recurring" | "once";
export interface ListenerArrayOptions {
mode: ListenerArrayMode
}
mode: ListenerArrayMode;
}
Loading

0 comments on commit 7631f44

Please sign in to comment.