Last active
October 17, 2018 09:35
-
-
Save shobhitsharma/b3501ce6b72db9447f42ffd504ee2e5a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Generic emitter of events. | |
*/ | |
export interface IListenerObject { | |
listener: any; | |
remove: any; | |
} | |
export class EventSource<T> { | |
private listeners: Array<{ | |
listener: (message: T) => void | boolean | Promise<boolean>; | |
remove?: boolean | "ifsuccessful"; | |
}> = []; | |
/** | |
* Emit an event | |
*/ | |
public emit(message: T): void { | |
this.listeners.slice().forEach(async (obj: IListenerObject) => { | |
let result; | |
try { | |
result = await obj.listener(message); | |
} catch (err) { | |
this.error_handler(err); | |
} | |
if ( | |
obj.remove === true || | |
(obj.remove === "ifsuccessful" && result === true) | |
) { | |
this.listeners.splice(this.listeners.indexOf(obj), 1); | |
} | |
}); | |
} | |
/** | |
* If there's an error emitting an event, this is called | |
*/ | |
public onError(handler: (err: Error) => void): this { | |
this.error_handler = handler; | |
return this; | |
} | |
/** | |
* Call a function for all events. | |
*/ | |
public on(listener: (message: T) => void): this { | |
this.listeners.push({ | |
listener | |
}); | |
return this; | |
} | |
/** | |
* Call a function for the next event. | |
*/ | |
public once(listener: (message: T) => void): this { | |
this.listeners.push({ | |
listener, | |
remove: true | |
}); | |
return this; | |
} | |
/** | |
* Call a function for all events until the function returns true. | |
*/ | |
private untilTrue( | |
listener: (message: T) => boolean | Promise<boolean> | |
): this { | |
this.listeners.push({ | |
listener, | |
remove: "ifsuccessful" | |
}); | |
return this; | |
} | |
/** | |
* Remove all event listeners | |
*/ | |
private removeAllListeners(): this { | |
this.listeners = []; | |
return this; | |
} | |
/** | |
* Remove a specific listener. | |
*/ | |
private removeListener(listener: (message: T) => void): this { | |
let match = this.listeners.filter( | |
(obj: IListenerObject) => obj.listener === listener | |
); | |
if (match.length) { | |
this.listeners.splice(this.listeners.indexOf(match[0]), 1); | |
} | |
return this; | |
} | |
private error_handler: ((err: Error) => void) = (err: Error) => { | |
throw err; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment