Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a3bd37c
renamed events legacy
ben-shepherd Nov 1, 2024
fea79ec
refactor(events): entire events domain refactor progress
ben-shepherd Nov 2, 2024
b7c19c9
refactor(events): event progress, generic base event, listener notifi…
ben-shepherd Nov 2, 2024
4c0ef45
refactor(events): Working test and mock assertion
ben-shepherd Nov 2, 2024
7dfb1df
refactor(events): queuable work, worker saving, updated test
ben-shepherd Nov 3, 2024
b4c1f6a
refactor(events) events queable failed test progress (broken)
ben-shepherd Nov 3, 2024
c89f4b9
Fixed tests failing
ben-shepherd Nov 4, 2024
3dda358
yarn fix
ben-shepherd Nov 4, 2024
7bd0acb
renamed create config methods
ben-shepherd Nov 4, 2024
6b5134e
event progress
ben-shepherd Nov 4, 2024
ce38f48
eventAuthRegistered test
ben-shepherd Nov 4, 2024
af2be3b
event auth tests
ben-shepherd Nov 5, 2024
73b646a
add castable concern
ben-shepherd Nov 5, 2024
4cd59f0
added tests for casting
ben-shepherd Nov 5, 2024
4540295
cast event payload
ben-shepherd Nov 5, 2024
a12c0b4
Comments, removed legacy events
ben-shepherd Nov 6, 2024
4a41316
Updated make for subscribers, listeners
ben-shepherd Nov 6, 2024
45bfe40
eslint
ben-shepherd Nov 6, 2024
da1b587
Updated worker migrations to use newest models
ben-shepherd Nov 6, 2024
51aa57f
Removed test event from events config, updated event names, added isR…
ben-shepherd Nov 6, 2024
20c0f33
removed console log
ben-shepherd Nov 6, 2024
c39c350
updated events in config
ben-shepherd Nov 6, 2024
6ab7f84
deleted events legacy config
ben-shepherd Nov 6, 2024
eb007cc
deleted legacy worker command
ben-shepherd Nov 6, 2024
03f9c7a
updated non use of useful variable (newAttempt in worker concern)
ben-shepherd Nov 6, 2024
15b62fe
removed unused interface
ben-shepherd Nov 6, 2024
d69c76a
removed useless interfaces
ben-shepherd Nov 6, 2024
9d2375a
removed legacy events from ICoreContainers
ben-shepherd Nov 6, 2024
b690567
removed comment from test
ben-shepherd Nov 6, 2024
50de6f3
drop worker tables after test, removed test legacy file
ben-shepherd Nov 6, 2024
e28072f
created seperated models, factories, observers for eventAuthRegistere…
ben-shepherd Nov 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions src/app/events/listeners/ExampleListener.ts

This file was deleted.

15 changes: 15 additions & 0 deletions src/app/events/listeners/UserCreatedListener.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import BaseEventListener from "@src/core/domains/events/base/BaseEventListener";

export class UserCreatedListener extends BaseEventListener {

/**
* Optional method to execute before the subscribers are dispatched.
*/
async execute(): Promise<void> {

// const payload = this.getPayload<IUserData>();

// Handle logic
}

}
16 changes: 0 additions & 16 deletions src/app/events/subscribers/ExampleSubscriber.ts

This file was deleted.

28 changes: 28 additions & 0 deletions src/app/events/subscribers/UserCreatedSubscriber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import BaseEvent from "@src/core/domains/events/base/BaseEvent";
import SyncDriver from "@src/core/domains/events/drivers/SyncDriver";

export default class UserCreatedSubscriber extends BaseEvent {

static readonly eventName = 'UserCreatedSubscriber';

protected namespace: string = 'auth';

constructor(payload) {
super(payload, SyncDriver);
}

getName(): string {
return UserCreatedSubscriber.eventName;
}

getQueueName(): string {
return 'default';
}

async execute(): Promise<void> {
// const payload = this.getPayload<IUserData>();

// Handle logic
}

}
11 changes: 11 additions & 0 deletions src/app/observers/UserObserver.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { UserCreatedListener } from "@src/app/events/listeners/UserCreatedListener";
import { IUserData } from "@src/app/models/auth/User";
import hashPassword from "@src/core/domains/auth/utils/hashPassword";
import Observer from "@src/core/domains/observer/services/Observer";
Expand All @@ -22,6 +23,16 @@ export default class UserObserver extends Observer<IUserData> {
return data
}

/**
* Called after the User model has been created.
* @param data The User data that has been created.
* @returns The processed User data.
*/
async created(data: IUserData): Promise<IUserData> {
await App.container('events').dispatch(new UserCreatedListener(data))
return data
}

/**
* Updates the roles of the user based on the groups they belong to.
* Retrieves the roles associated with each group the user belongs to from the permissions configuration.
Expand Down
124 changes: 61 additions & 63 deletions src/config/events.ts
Original file line number Diff line number Diff line change
@@ -1,71 +1,69 @@
import { ExampleListener } from "@src/app/events/listeners/ExampleListener";
import QueueDriver, { QueueDriverOptions } from "@src/core/domains/events/drivers/QueueDriver";
import SynchronousDriver from "@src/core/domains/events/drivers/SynchronousDriver";
import { IEventDrivers, ISubscribers } from "@src/core/domains/events/interfaces/IEventConfig";
import { UserCreatedListener } from "@src/app/events/listeners/UserCreatedListener";
import UserCreatedSubscriber from "@src/app/events/subscribers/UserCreatedSubscriber";
import QueueableDriver, { TQueueDriverOptions } from "@src/core/domains/events/drivers/QueableDriver";
import SyncDriver from "@src/core/domains/events/drivers/SyncDriver";
import { IEventConfig } from "@src/core/domains/events/interfaces/config/IEventConfig";
import FailedWorkerModel from "@src/core/domains/events/models/FailedWorkerModel";
import WorkerModel from "@src/core/domains/events/models/WorkerModel";
import DriverOptions from "@src/core/domains/events/services/QueueDriverOptions";
import EventService from "@src/core/domains/events/services/EventService";

/**
* Default Event Driver Configuration
*
* This setting determines which event driver will be used by default when no specific
* driver is defined for an event. The value is read from the APP_EVENT_DRIVER
* environment variable, falling back to 'sync' if not set.
*
* Options:
* - 'sync': Events are processed immediately.
* - 'queue': Events are queued for background processing.
* Event Drivers Constants
*/
export const defaultEventDriver: string = process.env.APP_EVENT_DRIVER ?? 'sync';
export const EVENT_DRIVERS = {
SYNC: EventService.getDriverName(SyncDriver),
QUEABLE: EventService.getDriverName(QueueableDriver)
}

/**
* Event Drivers Configuration
*
* This object defines the available event drivers and their configurations.
* Each driver can have its own set of options to customize its behavior.
*
* Structure:
* {
* [driverName: string]: {
* driver: Class extending IEventDriver,
* options?: DriverOptions object
* }
* }
*/
export const eventDrivers: IEventDrivers = {
// Synchronous Driver: Processes events immediately
sync: {
driver: SynchronousDriver
},
// Queue Driver: Saves events for background processing
queue: {
driver: QueueDriver,
options: new DriverOptions<QueueDriverOptions>({
queueName: 'default', // Name of the queue
retries: 3, // Number of retry attempts for failed events
failedCollection: 'failedWorkers', // Collection to store failed events
runAfterSeconds: 10, // Delay before processing queued events
workerModelCtor: WorkerModel // Constructor for the Worker model
export const eventConfig: IEventConfig = {

/**
* Default Event Driver
*/
defaultDriver: SyncDriver,

/**
* Event Drivers Configuration
*
* This object defines the available event drivers and their configurations.
* Each driver can have its own set of options to customize its behavior.
*/
drivers: {

// Synchronous Driver: Processes events immediately
[EVENT_DRIVERS.SYNC]: EventService.createConfigDriver(SyncDriver, {}),

// Queue Driver: Saves events for background processing
[EVENT_DRIVERS.QUEABLE]: EventService.createConfigDriver<TQueueDriverOptions>(QueueableDriver, {
queueName: 'default', // Name of the queue
retries: 3, // Number of retry attempts for failed events
runAfterSeconds: 10, // Delay before processing queued events
workerModelCtor: WorkerModel, // Constructor for the Worker model
failedWorkerModelCtor: FailedWorkerModel,
})
}
} as const;

},

/**
* Register Events
*/
events: EventService.createConfigEvents([

]),

/**
* Event Listeners Configuration
*
* These are automatically registered with the event service
* and do not need to be added to 'events' array.
*/
listeners: EventService.createConfigListeners([
{
listener: UserCreatedListener,
subscribers: [
UserCreatedSubscriber
]
}
]),

/**
* Event Subscribers Configuration
*
* This object maps event names to arrays of listener classes. When an event
* is dispatched, all listeners registered for that event will be executed.
*
* Structure:
* {
* [eventName: string]: Array<ListenerClass>
* }
*
* Example usage:
* When an 'OnExample' event is dispatched, the ExampleListener will be triggered.
*/
export const eventSubscribers: ISubscribers = {
'OnExample': [
ExampleListener
]
}
8 changes: 8 additions & 0 deletions src/core/base/BaseCastable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import HasCastableConcern from "@src/core/concerns/HasCastableConcern";
import { IHasCastableConcern } from "@src/core/interfaces/concerns/IHasCastableConcern";
import { ICtor } from "@src/core/interfaces/ICtor";
import compose from "@src/core/util/compose";

const BaseCastable: ICtor<IHasCastableConcern> = compose(class {}, HasCastableConcern)

export default BaseCastable
10 changes: 10 additions & 0 deletions src/core/concerns/HasAttributesConcern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ import { IHasAttributes, IHasAttributesSetAttributeOptions as SetAttributeOption
import { ICtor } from "@src/core/interfaces/ICtor";
import IModelAttributes from "@src/core/interfaces/IModelData";

/**
* Concern that adds the ability to set and retrieve attributes from a model, and to broadcast when attributes change.
* The concern is a mixin and can be applied to any class that implements the IBroadcaster interface.
* The concern adds the following methods to the class: setAttribute, getAttribute, getAttributes, getOriginal, isDirty, and getDirty.
* The concern also adds a constructor that subscribes to the SetAttributeBroadcastEvent and calls the onSetAttributeEvent method when the event is triggered.
* The concern is generic and can be used with any type of model attributes.
* @template Attributes The type of the model's attributes.
* @param {ICtor<IBroadcaster>} Base The base class to extend with the concern.
* @returns {ICtor<IBroadcaster & IHasAttributes>} A class that extends the base class with the concern.
*/
const HasAttributesConcern = <Attributes extends IModelAttributes>(Base: ICtor<IBroadcaster>) => {
return class HasAttributes extends Base implements IHasAttributes {

Expand Down
Loading