@piggly/event-bus
Advanced tools
Comparing version 1.0.1 to 2.0.0
@@ -74,2 +74,12 @@ import EventDispatcher from '../EventDispatcher'; | ||
has(event_name: string): boolean; | ||
/** | ||
* Get dispatchers size. | ||
* | ||
* @returns {number} | ||
* @public | ||
* @since 2.0.0 | ||
* @memberof LocalEventDriver | ||
* @author Caique Araujo <caique@piggly.com.br> | ||
*/ | ||
size(): number; | ||
} |
@@ -85,4 +85,16 @@ "use strict"; | ||
} | ||
/** | ||
* Get dispatchers size. | ||
* | ||
* @returns {number} | ||
* @public | ||
* @since 2.0.0 | ||
* @memberof LocalEventDriver | ||
* @author Caique Araujo <caique@piggly.com.br> | ||
*/ | ||
size() { | ||
return this.dispatchers.size; | ||
} | ||
} | ||
exports.default = LocalEventDriver; | ||
//# sourceMappingURL=LocalEventDriver.js.map |
@@ -1,4 +0,3 @@ | ||
import EventHandler from './EventHandler'; | ||
import EventPayload from './EventPayload'; | ||
import { EventBusOptions, EventDriverInterface } from './types'; | ||
import { EventBusOptions, EventDispatcherResponse, EventDriverInterface, EventHandler } from './types'; | ||
/** | ||
@@ -29,3 +28,3 @@ * @file Event bus to subscribe, unsubscribe and publish events. | ||
*/ | ||
private _driver; | ||
private _drivers; | ||
/** | ||
@@ -74,3 +73,3 @@ * Construct with default driver. | ||
*/ | ||
publish<Event extends EventPayload>(event: Event, options?: EventBusOptions): boolean; | ||
publish<Event extends EventPayload>(event: Event, options?: EventBusOptions): Promise<EventDispatcherResponse>; | ||
/** | ||
@@ -88,3 +87,3 @@ * Subscribe handler to an event. | ||
*/ | ||
subscribe(event_name: string, handler: EventHandler, options?: EventBusOptions): boolean; | ||
subscribe<Event extends EventPayload>(event_name: string, handler: EventHandler<Event>, options?: EventBusOptions): boolean; | ||
/** | ||
@@ -102,3 +101,3 @@ * Unsubscribe handler from an event. | ||
*/ | ||
unsubscribe(event_name: string, handler: EventHandler, options?: EventBusOptions): boolean; | ||
unsubscribe<Event extends EventPayload>(event_name: string, handler: EventHandler<Event>, options?: EventBusOptions): boolean; | ||
/** | ||
@@ -105,0 +104,0 @@ * Unsubscribe all handlers from an event. |
@@ -31,3 +31,3 @@ "use strict"; | ||
*/ | ||
_driver; | ||
_drivers; | ||
/** | ||
@@ -43,3 +43,3 @@ * Construct with default driver. | ||
constructor() { | ||
this._driver = new Map(); | ||
this._drivers = new Map(); | ||
this.register(new LocalEventDriver_1.default()); | ||
@@ -74,3 +74,3 @@ } | ||
register(driver) { | ||
this._driver.set(driver.name, driver); | ||
this._drivers.set(driver.name, driver); | ||
} | ||
@@ -88,7 +88,7 @@ /** | ||
*/ | ||
publish(event, options) { | ||
async publish(event, options) { | ||
const driver = this.driver(options); | ||
const dispatcher = driver.get(event.name); | ||
if (dispatcher === undefined) { | ||
return false; | ||
return undefined; | ||
} | ||
@@ -169,5 +169,5 @@ return dispatcher.dispatch(event); | ||
if (options === undefined || options.driver === undefined) { | ||
return this._driver.get('local'); | ||
return this._drivers.get('local'); | ||
} | ||
const driver = this._driver.get(options.driver); | ||
const driver = this._drivers.get(options.driver); | ||
if (driver === undefined) { | ||
@@ -174,0 +174,0 @@ throw new Error(`EventBus driver ${options.driver} not found.`); |
@@ -1,3 +0,3 @@ | ||
import EventHandler from './EventHandler'; | ||
import EventPayload from './EventPayload'; | ||
import type { EventDispatcherResponse, EventHandler } from './types'; | ||
/** | ||
@@ -18,3 +18,3 @@ * @file Event dispatcher, where you can register handlers to an unique event and dispatch to them. | ||
*/ | ||
readonly handlers: Array<EventHandler>; | ||
readonly handlers: Array<EventHandler<any>>; | ||
/** | ||
@@ -46,3 +46,3 @@ * Event name. | ||
* @param {Event} event Event payload object. | ||
* @returns {boolean} | ||
* @returns {Promise<boolean>} | ||
* @public | ||
@@ -53,3 +53,3 @@ * @since 1.0.0 | ||
*/ | ||
dispatch<Event extends EventPayload>(event: Event): boolean; | ||
dispatch<Event extends EventPayload>(event: Event): Promise<EventDispatcherResponse>; | ||
/** | ||
@@ -65,3 +65,3 @@ * Register a new handler to the current event dispatcher. | ||
*/ | ||
register(handler: EventHandler): boolean; | ||
register<Event extends EventPayload>(handler: EventHandler<Event>): boolean; | ||
/** | ||
@@ -77,3 +77,3 @@ * Unregister a handler of the current event dispatcher. | ||
*/ | ||
unregister(handler: EventHandler): boolean; | ||
unregister<Event extends EventPayload>(handler: EventHandler<Event>): boolean; | ||
/** | ||
@@ -80,0 +80,0 @@ * Unregister all handlers of the current event dispatcher. |
@@ -48,3 +48,3 @@ "use strict"; | ||
* @param {Event} event Event payload object. | ||
* @returns {boolean} | ||
* @returns {Promise<boolean>} | ||
* @public | ||
@@ -55,11 +55,17 @@ * @since 1.0.0 | ||
*/ | ||
dispatch(event) { | ||
async dispatch(event) { | ||
if (event.name !== this.name) { | ||
return false; | ||
return undefined; | ||
} | ||
if (this.handlers.length === 0) { | ||
return false; | ||
return undefined; | ||
} | ||
this.handlers.forEach(handler => handler.handle(event)); | ||
return true; | ||
return Promise.allSettled(this.handlers.map(handler => { | ||
try { | ||
return handler(event); | ||
} | ||
catch (err) { | ||
return Promise.reject(err); | ||
} | ||
})); | ||
} | ||
@@ -77,3 +83,3 @@ /** | ||
register(handler) { | ||
if (this.handlers.find(h => h.constructor === handler.constructor)) { | ||
if (this.handlers.find(h => h === handler)) { | ||
return false; | ||
@@ -96,3 +102,3 @@ } | ||
// const index = this.handlers.indexOf(handler); | ||
const index = this.handlers.findIndex(h => h.constructor === handler.constructor); | ||
const index = this.handlers.findIndex(h => h === handler); | ||
if (index === -1) { | ||
@@ -99,0 +105,0 @@ return false; |
/** | ||
* Event payload with data. | ||
*/ | ||
export default class EventPayload<EventData = Record<string, any>> { | ||
export default class EventPayload<EventData extends Record<string, any> = Record<string, any>> { | ||
/** | ||
@@ -67,3 +67,3 @@ * Event id. | ||
* @public | ||
* @since 1.0.0 | ||
* @since 1.2.0 | ||
* @memberof EventPayload | ||
@@ -70,0 +70,0 @@ * @author Caique Araujo <caique@piggly.com.br> |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const uuid_1 = require("uuid"); | ||
/** | ||
@@ -74,3 +75,3 @@ * Event payload with data. | ||
* @public | ||
* @since 1.0.0 | ||
* @since 1.2.0 | ||
* @memberof EventPayload | ||
@@ -80,3 +81,3 @@ * @author Caique Araujo <caique@piggly.com.br> | ||
generateId() { | ||
return (Date.now() * Math.random()).toString() + Math.random().toString(36); | ||
return (0, uuid_1.v4)(); | ||
} | ||
@@ -83,0 +84,0 @@ } |
@@ -1,2 +0,3 @@ | ||
import EventDispatcher from '../EventDispatcher'; | ||
import type EventDispatcher from '../EventDispatcher'; | ||
import type EventPayload from '../EventPayload'; | ||
export interface EventDriverInterface { | ||
@@ -7,2 +8,3 @@ readonly name: string; | ||
has(event_name: string): boolean; | ||
size(): number; | ||
} | ||
@@ -12,1 +14,5 @@ export type EventBusOptions = { | ||
}; | ||
export type EventDispatcherResponse = PromiseSettledResult<boolean>[] | undefined; | ||
export type EventHandlerCallback<Event extends EventPayload = EventPayload> = (event: Event) => boolean; | ||
export type AsyncEventHandlerCallback<Event extends EventPayload = EventPayload> = (event: Event) => Promise<boolean>; | ||
export type EventHandler<Event extends EventPayload = EventPayload> = EventHandlerCallback<Event> | AsyncEventHandlerCallback<Event>; |
@@ -74,2 +74,12 @@ import EventDispatcher from '../EventDispatcher'; | ||
has(event_name: string): boolean; | ||
/** | ||
* Get dispatchers size. | ||
* | ||
* @returns {number} | ||
* @public | ||
* @since 2.0.0 | ||
* @memberof LocalEventDriver | ||
* @author Caique Araujo <caique@piggly.com.br> | ||
*/ | ||
size(): number; | ||
} |
@@ -83,3 +83,15 @@ /** | ||
} | ||
/** | ||
* Get dispatchers size. | ||
* | ||
* @returns {number} | ||
* @public | ||
* @since 2.0.0 | ||
* @memberof LocalEventDriver | ||
* @author Caique Araujo <caique@piggly.com.br> | ||
*/ | ||
size() { | ||
return this.dispatchers.size; | ||
} | ||
} | ||
//# sourceMappingURL=LocalEventDriver.js.map |
@@ -1,4 +0,3 @@ | ||
import EventHandler from './EventHandler'; | ||
import EventPayload from './EventPayload'; | ||
import { EventBusOptions, EventDriverInterface } from './types'; | ||
import { EventBusOptions, EventDispatcherResponse, EventDriverInterface, EventHandler } from './types'; | ||
/** | ||
@@ -29,3 +28,3 @@ * @file Event bus to subscribe, unsubscribe and publish events. | ||
*/ | ||
private _driver; | ||
private _drivers; | ||
/** | ||
@@ -74,3 +73,3 @@ * Construct with default driver. | ||
*/ | ||
publish<Event extends EventPayload>(event: Event, options?: EventBusOptions): boolean; | ||
publish<Event extends EventPayload>(event: Event, options?: EventBusOptions): Promise<EventDispatcherResponse>; | ||
/** | ||
@@ -88,3 +87,3 @@ * Subscribe handler to an event. | ||
*/ | ||
subscribe(event_name: string, handler: EventHandler, options?: EventBusOptions): boolean; | ||
subscribe<Event extends EventPayload>(event_name: string, handler: EventHandler<Event>, options?: EventBusOptions): boolean; | ||
/** | ||
@@ -102,3 +101,3 @@ * Unsubscribe handler from an event. | ||
*/ | ||
unsubscribe(event_name: string, handler: EventHandler, options?: EventBusOptions): boolean; | ||
unsubscribe<Event extends EventPayload>(event_name: string, handler: EventHandler<Event>, options?: EventBusOptions): boolean; | ||
/** | ||
@@ -105,0 +104,0 @@ * Unsubscribe all handlers from an event. |
@@ -28,3 +28,3 @@ import EventDispatcher from './EventDispatcher'; | ||
*/ | ||
_driver; | ||
_drivers; | ||
/** | ||
@@ -40,3 +40,3 @@ * Construct with default driver. | ||
constructor() { | ||
this._driver = new Map(); | ||
this._drivers = new Map(); | ||
this.register(new LocalEventDriver()); | ||
@@ -71,3 +71,3 @@ } | ||
register(driver) { | ||
this._driver.set(driver.name, driver); | ||
this._drivers.set(driver.name, driver); | ||
} | ||
@@ -85,7 +85,7 @@ /** | ||
*/ | ||
publish(event, options) { | ||
async publish(event, options) { | ||
const driver = this.driver(options); | ||
const dispatcher = driver.get(event.name); | ||
if (dispatcher === undefined) { | ||
return false; | ||
return undefined; | ||
} | ||
@@ -166,5 +166,5 @@ return dispatcher.dispatch(event); | ||
if (options === undefined || options.driver === undefined) { | ||
return this._driver.get('local'); | ||
return this._drivers.get('local'); | ||
} | ||
const driver = this._driver.get(options.driver); | ||
const driver = this._drivers.get(options.driver); | ||
if (driver === undefined) { | ||
@@ -171,0 +171,0 @@ throw new Error(`EventBus driver ${options.driver} not found.`); |
@@ -1,3 +0,3 @@ | ||
import EventHandler from './EventHandler'; | ||
import EventPayload from './EventPayload'; | ||
import type { EventDispatcherResponse, EventHandler } from './types'; | ||
/** | ||
@@ -18,3 +18,3 @@ * @file Event dispatcher, where you can register handlers to an unique event and dispatch to them. | ||
*/ | ||
readonly handlers: Array<EventHandler>; | ||
readonly handlers: Array<EventHandler<any>>; | ||
/** | ||
@@ -46,3 +46,3 @@ * Event name. | ||
* @param {Event} event Event payload object. | ||
* @returns {boolean} | ||
* @returns {Promise<boolean>} | ||
* @public | ||
@@ -53,3 +53,3 @@ * @since 1.0.0 | ||
*/ | ||
dispatch<Event extends EventPayload>(event: Event): boolean; | ||
dispatch<Event extends EventPayload>(event: Event): Promise<EventDispatcherResponse>; | ||
/** | ||
@@ -65,3 +65,3 @@ * Register a new handler to the current event dispatcher. | ||
*/ | ||
register(handler: EventHandler): boolean; | ||
register<Event extends EventPayload>(handler: EventHandler<Event>): boolean; | ||
/** | ||
@@ -77,3 +77,3 @@ * Unregister a handler of the current event dispatcher. | ||
*/ | ||
unregister(handler: EventHandler): boolean; | ||
unregister<Event extends EventPayload>(handler: EventHandler<Event>): boolean; | ||
/** | ||
@@ -80,0 +80,0 @@ * Unregister all handlers of the current event dispatcher. |
@@ -46,3 +46,3 @@ /** | ||
* @param {Event} event Event payload object. | ||
* @returns {boolean} | ||
* @returns {Promise<boolean>} | ||
* @public | ||
@@ -53,11 +53,17 @@ * @since 1.0.0 | ||
*/ | ||
dispatch(event) { | ||
async dispatch(event) { | ||
if (event.name !== this.name) { | ||
return false; | ||
return undefined; | ||
} | ||
if (this.handlers.length === 0) { | ||
return false; | ||
return undefined; | ||
} | ||
this.handlers.forEach(handler => handler.handle(event)); | ||
return true; | ||
return Promise.allSettled(this.handlers.map(handler => { | ||
try { | ||
return handler(event); | ||
} | ||
catch (err) { | ||
return Promise.reject(err); | ||
} | ||
})); | ||
} | ||
@@ -75,3 +81,3 @@ /** | ||
register(handler) { | ||
if (this.handlers.find(h => h.constructor === handler.constructor)) { | ||
if (this.handlers.find(h => h === handler)) { | ||
return false; | ||
@@ -94,3 +100,3 @@ } | ||
// const index = this.handlers.indexOf(handler); | ||
const index = this.handlers.findIndex(h => h.constructor === handler.constructor); | ||
const index = this.handlers.findIndex(h => h === handler); | ||
if (index === -1) { | ||
@@ -97,0 +103,0 @@ return false; |
/** | ||
* Event payload with data. | ||
*/ | ||
export default class EventPayload<EventData = Record<string, any>> { | ||
export default class EventPayload<EventData extends Record<string, any> = Record<string, any>> { | ||
/** | ||
@@ -67,3 +67,3 @@ * Event id. | ||
* @public | ||
* @since 1.0.0 | ||
* @since 1.2.0 | ||
* @memberof EventPayload | ||
@@ -70,0 +70,0 @@ * @author Caique Araujo <caique@piggly.com.br> |
@@ -0,1 +1,2 @@ | ||
import { v4 as uuidv4 } from 'uuid'; | ||
/** | ||
@@ -72,3 +73,3 @@ * Event payload with data. | ||
* @public | ||
* @since 1.0.0 | ||
* @since 1.2.0 | ||
* @memberof EventPayload | ||
@@ -78,5 +79,5 @@ * @author Caique Araujo <caique@piggly.com.br> | ||
generateId() { | ||
return (Date.now() * Math.random()).toString() + Math.random().toString(36); | ||
return uuidv4(); | ||
} | ||
} | ||
//# sourceMappingURL=EventPayload.js.map |
@@ -1,2 +0,3 @@ | ||
import EventDispatcher from '../EventDispatcher'; | ||
import type EventDispatcher from '../EventDispatcher'; | ||
import type EventPayload from '../EventPayload'; | ||
export interface EventDriverInterface { | ||
@@ -7,2 +8,3 @@ readonly name: string; | ||
has(event_name: string): boolean; | ||
size(): number; | ||
} | ||
@@ -12,1 +14,5 @@ export type EventBusOptions = { | ||
}; | ||
export type EventDispatcherResponse = PromiseSettledResult<boolean>[] | undefined; | ||
export type EventHandlerCallback<Event extends EventPayload = EventPayload> = (event: Event) => boolean; | ||
export type AsyncEventHandlerCallback<Event extends EventPayload = EventPayload> = (event: Event) => Promise<boolean>; | ||
export type EventHandler<Event extends EventPayload = EventPayload> = EventHandlerCallback<Event> | AsyncEventHandlerCallback<Event>; |
{ | ||
"name": "@piggly/event-bus", | ||
"version": "1.0.1", | ||
"version": "2.0.0", | ||
"description": "An ESM/CommonJS library following Oriented-Object Programming pattern to manager an Event Bus.", | ||
@@ -56,2 +56,3 @@ "scripts": { | ||
"@types/jest": "^29.2.5", | ||
"@types/uuid": "^9.0.6", | ||
"@typescript-eslint/eslint-plugin": "^5.48.0", | ||
@@ -75,3 +76,6 @@ "@typescript-eslint/parser": "^5.48.0", | ||
"typescript": "^4.9.4" | ||
}, | ||
"dependencies": { | ||
"uuid": "^9.0.1" | ||
} | ||
} |
@@ -5,3 +5,3 @@ # Event Bus Library | ||
An ESM/CommonJS library following Oriented-Object Programming pattern to manager an Event Bus. | ||
An ESM/CommonJS library following Oriented-Object Programming pattern to manager an Event Bus. Recommended to server-side application. The main goal is to provide a simple way to publish, subscribe and unsubscribe to local events. | ||
@@ -19,2 +19,15 @@ ## Features | ||
## Use Cases | ||
When you have two microservices, you may want to them comunicate to each other. In the Microservice A you can publish a CLIENT_CREATED event, then: | ||
- A handler send it to RabbitMQ (and Rabbit MQ send it to Microservice B); | ||
- A handler log some event data in a file. | ||
### To remember | ||
1. Before your application starts (or before event to be published), you must subscribe all handlers; | ||
2. Anytime in your application flow, events will be published as needed; | ||
3. Handlers will be executed in the same order that they were subscribed. | ||
## Installation | ||
@@ -36,3 +49,3 @@ | ||
By default, the `publish()`, `subscribe()`, `unsubscrive()` and `unsubscriveAll()` methods will you the `LocalEventDriver`. But, you can change this behavior saying what driver must be loaded. E.g: `publish(event, { driver: 'another' })`. The `another` driver must be registered. | ||
By default, the `publish()`, `subscribe()`, `unsubscribe()` and `unsubscribeAll()` methods will use the `LocalEventDriver`. But, you can change this behavior saying what driver must be loaded. E.g: `publish(event, { driver: 'another' })`. The `another` driver must be registered. | ||
@@ -55,12 +68,35 @@ ```ts | ||
```ts | ||
import EventBus from '@piggly/event-bus'; | ||
import EventBus, { AsyncEventHandlerCallback, EventHandlerCallback, EventPayload } from '@piggly/event-bus'; | ||
// Sync handler | ||
const callback: EventHandlerCallback<EventPayload> = (e) => { | ||
console.log('Do something'); | ||
}; | ||
// Async handler | ||
const asyncCallback: AsyncEventHandlerCallback<EventPayload> = (e) => { | ||
console.log('Do something'); | ||
}; | ||
// You can subscribe handlers to events | ||
EventBus.instance.subscribe('EVENT_NAME', new SomeEventHandler()); | ||
EventBus.instance.subscribe('EVENT_NAME', callback); | ||
EventBus.instance.subscribe('EVENT_NAME', asyncCallback); | ||
// If needed you can unsubscribe, handler must be the same class that was subscribed | ||
EventBus.instance.unsubscrive('EVENT_NAME', new SomeEventHandler()); | ||
EventBus.instance.unsubscribe('EVENT_NAME', callback); | ||
// When event is ready, just publish it and event bus does what is need | ||
EventBus.instance.publish(new EventPayload('EVENT_NAME', {})); | ||
EventBus.instance | ||
.publish(new EventPayload('EVENT_NAME', {})) | ||
.then((solved) => { | ||
if (solved === undefined) { | ||
console.log('Event was not published'); | ||
return; | ||
} | ||
console.log('Event was published'); | ||
}) | ||
.catch(() => { | ||
console.log('Event was not published'); | ||
}); | ||
``` | ||
@@ -70,35 +106,43 @@ | ||
You must create classes for handlers, it allows dispatcher avoid to add the same constructor classes into handler array of an event: | ||
For fast implementations, on version `>=2.x.x` handlers are regular functions. They also can be async/await function or return a Promise. | ||
The `AsyncEventHandlerCallback` and `EventHandlerCallback` helps you to define the handler function. They are just a type definition. | ||
The parameter to an event handler is a `EventPayload` object. This object contains the event name and the event data. You can use the `EventPayload` class or create your own class extending it. | ||
```ts | ||
import { EventHandler, EventPayload } from '@piggly/event-bus'; | ||
// !! USE EVENTPAYLOAD | ||
// Event data | ||
// Type to event data | ||
export type StubEventData = { | ||
value: number; | ||
value: number; | ||
}; | ||
// Event handler | ||
export class StubEventHandler extends EventHandler<StubEventData> { | ||
public handle(event: EventPayload<StubEventData>): void { | ||
console.log(event); | ||
} | ||
} | ||
// !! USE CUSTOMEVENTPAYLOAD | ||
// Custom class for event payload | ||
// You may use it to validate/parse event data | ||
export class StubEventPayload extends EventPayload<StubEventData> { | ||
constructor(data: { value: number }) { | ||
super('STUB_EVENT', data); | ||
} | ||
constructor(data: { value: number }) { | ||
super('STUB_EVENT', data); | ||
} | ||
} | ||
// Event handler | ||
export class StubEventHandler extends EventHandler<StubEventData> { | ||
public handle(event: StubEventPayload): void { | ||
console.log(event); | ||
} | ||
} | ||
const eventPayload = new EventPayload('STUB_EVENT', { value: 1 }); | ||
const customEventPayload = new StubbEventPayload({ value: 1 }); | ||
// Handler for event | ||
const syncHandler = (e: EventPayload<StubEventData>) => { | ||
console.log(e.name); | ||
console.log(e.data); | ||
}; | ||
const syncHandler = async (e: StubEventPayload) => { | ||
console.log(e.name); | ||
console.log(e.data); | ||
}; | ||
``` | ||
## Examples | ||
See [EventBus.integration.spec.ts](./test/core/EventBus.integration.spec.ts) file for more examples. | ||
## Changelog | ||
@@ -105,0 +149,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
70650
1776
166
1
20
45
+ Addeduuid@^9.0.1
+ Addeduuid@9.0.1(transitive)