diff --git a/README.md b/README.md index 20b43bd..283a172 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Chiisai Event Emitter -A minimal event emitter library for Node.JS. +A minimal and performant event emitter library for Node.JS. --- @@ -14,8 +14,6 @@ A minimal event emitter library for Node.JS. [![Commitizen Friendly][commitizen-img]][commitizen-url] [![Semantic Release][semantic-release-img]][semantic-release-url] -> My awesome module - ## Install ```bash @@ -25,32 +23,17 @@ npm install chiisai-event-emitter ## Usage ```ts -import { myPackage } from 'chiisai-event-emitter'; - -myPackage('hello'); -//=> 'hello from my package' -``` - -## API - -### myPackage(input, options?) - -#### input +import eventEmitter from 'chiisai-event-emitter'; -Type: `string` +const eventEmitter = new EventEmitter(); -Lorem ipsum. +eventEmitter.subscribe('test-event', () => console.log('test-event handler called!')); +eventEmitter.subscribe('test-event', () => console.log('another test-event handler called!')) -#### options - -Type: `object` - -##### postfix - -Type: `string` -Default: `rainbows` - -Lorem ipsum. +eventEmitter.emit('test-event') +// test-event handler called! +// another test-event handler called! +``` [build-img]:https://github.com/ryansonshine/chiisai-event-emitter/actions/workflows/release.yml/badge.svg [build-url]:https://github.com/ryansonshine/chiisai-event-emitter/actions/workflows/release.yml diff --git a/src/index.ts b/src/index.ts index 0349cbc..73b5d11 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,49 @@ -export const myPackage = (taco = ''): string => `${taco} from my package`; +export type EventCallback = (...args: Array) => T; +export type Subscriptions = Map< + string, + Array<{ id: symbol; callback: EventCallback }> +>; +export type Unsubscribe = { unsubscribe: () => void }; + +export class EventEmitter { + subscriptions: Subscriptions; + + constructor() { + this.subscriptions = new Map(); + } + + /** + * @param {string} eventName + * @param {EventCallback} callback + * @return {Unsubscribe} + */ + subscribe(eventName: string, callback: EventCallback): Unsubscribe { + const id = Symbol(callback.toString()); + this.subscriptions.set( + eventName, + this.subscriptions.has(eventName) + ? [...(this.subscriptions.get(eventName) || []), { id, callback }] + : [{ id, callback }] + ); + + return { + unsubscribe: () => + this.subscriptions.set( + eventName, + (this.subscriptions.get(eventName) || []).filter( + ({ id: subscriptionId }) => subscriptionId !== id + ) + ), + }; + } + + /** + * @param {string} eventName + * @param {Array} args + */ + emit(eventName: string, args: Array = []): void { + (this.subscriptions.get(eventName) || []).forEach(({ callback }) => + callback(...args) + ); + } +}