UNPKG

@homer0/events-hub

Version:

A simple implementation of a pubsub service for handling events

132 lines (98 loc) 3.96 kB
# 🚚 Events hub A simple implementation of a pubsub service for handling events. It doesn't require any configuration or have customization options: You listen for an event with `on`, emit an event with `emit`, and, you could reduce a variable through an event with `reduce` (or `reduceSync`). ## 🍿 Usage - ⚙️ [Examples](#%EF%B8%8F-examples) - 🤘 [Development](#-development) ### ⚙️ Examples First, let's create an instance of the hub: ```ts import { eventsHub } from '@homer0/events-hub'; const events = eventsHub(); ``` #### Listen and emit ```ts // Add the listener events.on('my-event', () => { console.log('The event listener was called!'); }); // Emit the event events.emit('my-event'); ``` Quite simple, right? You can also send any number of parameters to the events: ```ts // Define the listener, to get the parameters' types. type LoginListener = (username: string, password: string) => void | Promise<void>; // Add the listener events.on<LoginListener>('user-login', async (username, password) => { try { const userInfo = await someAuthService.login(username, password); events.emit('user-login-successfull', userInfo); } catch (error) { events.emit('user-login-failed', error); } }); //... // Emit the event. events.emit('user-login', 'rosario', 'p4ssword'); ``` #### Multiple events All methods that support an event name also support an `Array` with a list of them, which means you can set the same listener for multiple events: ```ts // Add the listener events.on(['logout-route', 'unauthorized-request'], () => { someAuthService.signout(); }); //... // This would trigger the listener. events.emit('logout-route'); // and this too (if it fails :P). someRequest() .then(() => ... ) .catch((error) => { if (error.code === 401) { events.emit('unauthorized-request'); } }); ``` #### Listening only once You can use the `once` method to create a subscription that will be removed after being called one time. Following the previous examples, let's say that the `signout` method makes a redirection to a different URL (because of reasons); that means that there's no need to keep the listener around once executed: ```ts events.once(['logout-route', 'unauthorized-request'], () => { someAuthService.signout(); }); ``` After `.signout()` gets called, the listener will be removed. > Yeah, technically, if `.signout()` does a redirection, it could stop the execution... but you get the point of the example. #### Reducing a variable The service has a `reduce` method that is basically the same as `emit`, but the first parameter may be modified by the listeners. ```js events.on('filter-users-list', async (list) => { const fromAPI = await getUsersToFilterFromSomeAPI('...', { list }); return list.filter((item) => !fromAPI.includes(item)); }); const usersList = ['Rosario', 'Pilar']; const newUsersList = await events.reduce('filter-users-list', usersList); // `newUsersList` would now be the users that weren't in the API. ``` > After the `target`, you can send any number of parameters for the listeners/reducers. There's also a synchronous version of the `reduce` method: `reduceSync`. ```ts events.on('filter-users-list', (list) => { list.slice(1, 3); return list; }); const usersList = ['charito', 'Rosario', 'Pilar', 'pili']; const newUsersList = events.reduceSync('filter-users-list', usersList); console.log(newUsersList); // Will log ['Rosario', 'Pilar'] ``` ### 🤘 Development As this project is part of the `packages` monorepo, some of the tooling, like `lint-staged` and `husky`, are installed on the root's `package.json`. #### Tasks | Task | Description | | ------------- | ------------------------------- | | `lint` | Lints the package. | | `test` | Runs the unit tests. | | `build` | Transpiles the project. | | `types:check` | Validates the TypeScript types. |