-
-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
29 changed files
with
437 additions
and
14 deletions.
There are no files selected for viewing
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[install] | ||
# set default registry as a string | ||
registry = "https://registry.npmmirror.com" |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import "reflect-metadata" | ||
|
||
import type { BaseEvent } from "@undb/domain" | ||
import type { Class } from "type-fest" | ||
import { v4 } from "uuid" | ||
import { EVENT_HANDLER_METADATA, EVENT_METADATA } from "./constants" | ||
|
||
export const eventHandler = (event: Class<BaseEvent>): ClassDecorator => { | ||
return (target: object) => { | ||
if (!Reflect.hasOwnMetadata(EVENT_METADATA, event)) { | ||
Reflect.defineMetadata(EVENT_METADATA, { id: v4() }, event) | ||
} | ||
Reflect.defineMetadata(EVENT_HANDLER_METADATA, event, target) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from "./command-handler.decorator" | ||
export * from "./event-handler.decorator" | ||
export * from "./query-handler.decorator" |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import type { BaseEvent, IEventPublisher } from "@undb/domain" | ||
import { Subject } from "rxjs" | ||
|
||
export class DefaultEventPubSub<E extends BaseEvent> implements IEventPublisher<E> { | ||
constructor(public subject$: Subject<E>) {} | ||
|
||
async publish(event: E): Promise<void> { | ||
this.subject$.next(event) | ||
} | ||
|
||
async publishMany(events: E[]): Promise<void> { | ||
events.forEach((event) => this.subject$.next(event)) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { container, singleton } from "@undb/di" | ||
import type { BaseEvent, EventMetadata, IEventBus, IEventHandler, IEventPublisher } from "@undb/domain" | ||
import { Subject } from "rxjs" | ||
import type { Class } from "type-fest" | ||
import { EVENT_HANDLER_METADATA, EVENT_METADATA } from "./decorators/constants" | ||
import { DefaultEventPubSub } from "./default-event-publisher" | ||
import { EventHandlerNotFoundException } from "./exceptions/event-handler-not-found.exception" | ||
import { InvalidEventHandlerException } from "./exceptions/invalid-event-handler.exception" | ||
|
||
export type EventHandlerType = Class<IEventHandler<BaseEvent, any>> | ||
|
||
@singleton() | ||
export class EventBus<TEvent extends BaseEvent = BaseEvent> implements IEventBus<TEvent> { | ||
private subject = new Subject<TEvent>() | ||
private readonly publisher: IEventPublisher = new DefaultEventPubSub(this.subject) | ||
|
||
#handlers = new Map<string, IEventHandler<TEvent, any>>() | ||
|
||
async publish(event: TEvent): Promise<void> { | ||
console.log("publish event", event) | ||
const eventId = this.getEventId(event) | ||
const handler = this.#handlers.get(eventId) | ||
if (!handler) { | ||
const eventName = this.getEventName(event) | ||
throw new EventHandlerNotFoundException(eventName) | ||
} | ||
this.publisher.publish(event) | ||
return handler.handle(event) | ||
} | ||
|
||
async publishMany(events: TEvent[]): Promise<void> { | ||
await Promise.all(events.map((event) => this.publish(event))) | ||
} | ||
|
||
register(handlers: EventHandlerType[]) { | ||
handlers.forEach((handler) => this.registerHandler(handler)) | ||
} | ||
|
||
private bind<T extends TEvent>(handler: IEventHandler<T, any>, id: string) { | ||
this.#handlers.set(id, handler) | ||
} | ||
|
||
protected registerHandler(handler: EventHandlerType) { | ||
const instance = container.resolve(handler) | ||
if (!instance) { | ||
return | ||
} | ||
const target = this.reflectEventId(handler) | ||
if (!target) { | ||
throw new InvalidEventHandlerException() | ||
} | ||
this.bind(instance as IEventHandler<TEvent, any>, target) | ||
} | ||
|
||
private reflectEventId(handler: EventHandlerType): string | undefined { | ||
const event: BaseEvent = Reflect.getMetadata(EVENT_HANDLER_METADATA, handler) | ||
const eventMetadata: EventMetadata = Reflect.getMetadata(EVENT_METADATA, event) | ||
return eventMetadata.id | ||
} | ||
|
||
private getEventId(event: TEvent): string { | ||
const { constructor: eventType } = Object.getPrototypeOf(event) | ||
const eventMetadata: EventMetadata = Reflect.getMetadata(EVENT_METADATA, eventType) | ||
if (!eventMetadata) { | ||
throw new EventHandlerNotFoundException(eventType.name) | ||
} | ||
return eventMetadata.id | ||
} | ||
|
||
private getEventName(event: TEvent): string { | ||
const { constructor } = Object.getPrototypeOf(event) | ||
return constructor.name as string | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
packages/cqrs/src/exceptions/event-handler-not-found.exception.ts
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export class EventHandlerNotFoundException extends Error { | ||
constructor(eventId: string) { | ||
super(`The event handler for the "${eventId}" event was not found!`) | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
packages/cqrs/src/exceptions/invalid-event-handler.exception.ts
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export class InvalidEventHandlerException extends Error { | ||
constructor() { | ||
super(`Invalid event handler exception (missing @eventHandler() decorator?)`) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from "./command-bus" | ||
export * from "./decorators" | ||
export * from "./event-bus" | ||
export * from "./query-bus" |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import type { BaseEvent } from "./event.js" | ||
|
||
export interface IEventBus<TEvent extends BaseEvent = BaseEvent> { | ||
publish(event: TEvent): Promise<void> | ||
publishMany(events: TEvent[]): Promise<void> | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export interface EventMetadata { | ||
id: string | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import type { BaseEvent } from "./event" | ||
|
||
export interface IEventPublisher<TEvent extends BaseEvent = BaseEvent> { | ||
publish(event: TEvent): Promise<void> | ||
publishMany(events: TEvent[]): Promise<void> | ||
} |
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
Oops, something went wrong.