-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement/metadata-cache-events (#21)
* Implement ILogger Interface for Logging System Refactored the Logging class to implement the newly defined ILogger interface for a more structured and formal logging approach. The getLogger method now returns an instance of ILogger, ensuring consistent logging method signatures and enabling potential future extensions where different loggers conforming to the ILogger interface can be used interchangeably. This enhances maintainability and supports adherence to the dependency inversion principle. * Add event handling system with registration and firing Introduced a new events system via the GenericEvents class to facilitate event registration, deregistration, and firing within the application. This system allows defining events with associated types for data and return values, enabling a clear and type-safe handling of app-wide events. Implementations provide registration and deregistration methods, ensuring that events can be dynamically managed at runtime. The fireEvent method executes registered callbacks, and the system incorporates an optional logger for debugging purposes. * Implement event system for MetadataCache updates Introduced a new event handling mechanism within the MetadataCache class, allowing for the registration and firing of events when plugin-related file metadata changes. Notably, an event is emitted for the 'prj-task-management-changed-status' scenario, enabling dynamic reaction to task status updates. This feature facilitates the extensibility of the metadata cache and improves its integration capabilities with task-related plugin functionalities. Additionally, the process of metadata change detection has been refined to include event emission when specific conditions are met. * Add task status file sync on change Implemented syncing of task files to their respective status directories when status changes are detected. A listener on `prj-task-management-changed-status` now triggers `syncStatusToPath`, moving files to an 'Archiv' directory for completed tasks or to the main status folder for other valid statuses. Ensured that file relocations only occur when the new path differs from the current one, logging each action for debugging purposes. Additionally, refactored `StaticPrjTaskManagementModel` to include missing imports and enhance code maintainability. * Version bump to V0.0.30
- Loading branch information
Showing
9 changed files
with
319 additions
and
6 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,41 @@ | ||
/** | ||
* Interface for the logger. | ||
* @remarks You can attach your own logger or `console` as logger. | ||
*/ | ||
export interface ILogger { | ||
/** | ||
* Log a `trace` message. | ||
* @param message The trace message to log. | ||
* @param optionalParams Optional parameters: strings, objects, etc. | ||
*/ | ||
trace(message?: unknown, ...optionalParams: unknown[]): void; | ||
|
||
/** | ||
* Log an `info` message. | ||
* @param message The info message to log. | ||
* @param optionalParams Optional parameters: strings, objects, etc. | ||
*/ | ||
info(message?: unknown, ...optionalParams: unknown[]): void; | ||
|
||
/** | ||
* Log a `debug` message. | ||
* @param message The debug message to log. | ||
* @param optionalParams Optional parameters: strings, objects, etc. | ||
*/ | ||
debug(message?: unknown, ...optionalParams: unknown[]): void; | ||
|
||
/** | ||
* Log a `warn` message. | ||
* @param message The warn message to log. | ||
* @param optionalParams Optional parameters: strings, objects, etc. | ||
*/ | ||
warn(message?: unknown, ...optionalParams: unknown[]): void; | ||
|
||
/** | ||
* Log an `error` message. | ||
* @param message The error message to log. | ||
* @param optionalParams Optional parameters: strings, objects, etc. | ||
*/ | ||
error(message?: unknown, ...optionalParams: unknown[]): 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,140 @@ | ||
import { ILogger } from "src/interfaces/ILogger"; | ||
|
||
/** | ||
* Interface for the callback. | ||
*/ | ||
export interface ICallback { | ||
events: { | ||
[key: string]: IEvent<unknown, unknown>; | ||
}; | ||
} | ||
|
||
/** | ||
* Interface for the events. | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
export interface IEvent<TData, TReturn = void> { | ||
name: string; | ||
data: TData; | ||
} | ||
|
||
/** | ||
* Interface for the events. | ||
*/ | ||
type RegisteredEvent<T extends ICallback, K extends keyof T['events']> = { | ||
eventName: K; | ||
callback: (data: T['events'][K]['data']) => T['events'][K] extends IEvent<unknown, infer TReturn> ? TReturn : unknown; | ||
}; | ||
|
||
/** | ||
* Events class; encapsulates event registration and firing | ||
* @example | ||
* ```typescript | ||
* // Define a concrete interface for your specific events | ||
* interface MyEvents extends ICallback { | ||
* events: { | ||
* 'myEvent1': IEvent<string, number>; // Event with a string as input and a number as output | ||
* 'myEvent2': IEvent<number, void>; // Event with a number as input and no output | ||
* // Add more events here | ||
* }; | ||
* } | ||
* | ||
* // Use the Events class with your concrete interface | ||
* const eventsInstance = new GenericEvents<MyEvents>(); | ||
* | ||
* // Register event one with a string as input and a number as output | ||
* eventsInstance.registerEvent('myEvent1', (data) => { | ||
* console.log(data); | ||
* return 100; | ||
* }); | ||
* // Fire event one with a string as input and a number as output | ||
* eventsInstance.fireEvent('myEvent1', 'Fire event 1', (result) => { | ||
* console.log(result); // Result is a number | ||
* }); | ||
* ``` | ||
*/ | ||
export default class GenericEvents<T extends ICallback> { | ||
private logger: ILogger | undefined; | ||
private _events: Array<RegisteredEvent<T, keyof T['events']>> = []; | ||
|
||
/** | ||
* Creates a new Events instance | ||
* @param logger The logger to use. You can use your own logger or `console` as logger. | ||
*/ | ||
constructor(logger?: ILogger) { | ||
this.logger = logger; | ||
} | ||
|
||
/** | ||
* Registers an event with a callback. | ||
* @param eventName The name of the event to register. | ||
* @param callback The callback to execute when the event is fired. | ||
*/ | ||
public registerEvent<K extends keyof T['events']>( | ||
eventName: K, | ||
callback: (data: T['events'][K]['data']) => T['events'][K] extends IEvent<unknown, infer TReturn> ? TReturn : unknown | ||
): void { | ||
// Add the event to the _events array | ||
this._events.push({ eventName, callback }); | ||
this.logger?.debug(`Event ${eventName.toString()} registered`); | ||
} | ||
|
||
/** | ||
* Deregisters an event with a callback. | ||
* @param eventName The name of the event to deregister. | ||
* @param callback The callback to deregister. | ||
*/ | ||
public deregisterEvent<K extends keyof T['events']>( | ||
eventName: K, | ||
callback: (data: T['events'][K]['data']) => T['events'][K] extends IEvent<unknown, infer TReturn> ? TReturn : unknown | ||
): void { | ||
// Delete the event from the _events array | ||
this._events = this._events.filter(event => event.eventName !== eventName || event.callback !== callback); | ||
this.logger?.debug(`Event ${eventName.toString()} deregistered`); | ||
} | ||
|
||
/** | ||
* Fires an event with a callback. | ||
* @param eventName The name of the event to fire. | ||
* @param eventData The data to pass to the event handler. | ||
* @param callback The callback to execute when the event is fired. | ||
*/ | ||
public fireEvent<K extends keyof T['events']>( | ||
eventName: K, | ||
eventData: T['events'][K]['data'], | ||
callback?: (result: T['events'][K] extends IEvent<unknown, infer TReturn> ? TReturn : unknown) => void | ||
): void { | ||
// Find the event in the _events array and execute the callback | ||
this._events.filter(event => event.eventName === eventName) | ||
.forEach(event => { | ||
this._executeEventHandler(event.callback, eventData, callback); | ||
this.logger?.debug(`Event ${eventName.toString()} fired`); | ||
}); | ||
} | ||
|
||
/** | ||
* Executes an event handler and calls the callback with the result. | ||
* @param handler The event handler to execute. | ||
* @param eventData The data to pass to the event handler. | ||
* @param callback The callback to execute when the event handler is executed. | ||
*/ | ||
private async _executeEventHandler<K extends keyof T['events']>( | ||
handler: (data: T['events'][K]['data']) => T['events'][K] extends IEvent<unknown, infer TReturn> ? TReturn : unknown, | ||
eventData: T['events'][K]['data'], | ||
callback?: (result: T['events'][K] extends IEvent<unknown, infer TReturn> ? TReturn : unknown) => void | ||
): Promise<void> { | ||
try { | ||
// Execute the handler and call the callback with the result | ||
const result = await handler(eventData); | ||
this.logger?.debug(`Event handler for ${handler.toString()} executed`); | ||
if (callback) { | ||
callback(result); | ||
this.logger?.debug(`Callback for ${handler.toString()} executed`); | ||
} | ||
} catch (error) { | ||
this.logger?.error(`Error in event handler for ${handler.toString()}: ${error}`); | ||
} | ||
} | ||
|
||
} |
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
Oops, something went wrong.