diff --git a/packages/debug/index.ts b/packages/debug/index.ts new file mode 100644 index 0000000..dc37b1a --- /dev/null +++ b/packages/debug/index.ts @@ -0,0 +1,3 @@ +export * from './services'; +export * from './types'; +export * from './interfaces'; diff --git a/packages/debug/interfaces/index.ts b/packages/debug/interfaces/index.ts new file mode 100644 index 0000000..891a6c4 --- /dev/null +++ b/packages/debug/interfaces/index.ts @@ -0,0 +1 @@ +export * from './logger.interfaces'; diff --git a/packages/debug/interfaces/logger.interfaces.ts b/packages/debug/interfaces/logger.interfaces.ts new file mode 100644 index 0000000..ef91ed0 --- /dev/null +++ b/packages/debug/interfaces/logger.interfaces.ts @@ -0,0 +1,37 @@ +import { LogLevel } from '../types/logger.types'; + +/** + * @public + */ +export interface LoggerService { + /** + * Write a 'log' level log. + */ + log(message: any, ...optionalParams: any[]): any; + + /** + * Write an 'error' level log. + */ + error(message: any, ...optionalParams: any[]): any; + + /** + * Write a 'warn' level log. + */ + warn(message: any, ...optionalParams: any[]): any; + + /** + * Write a 'debug' level log. + */ + debug?(message: any, ...optionalParams: any[]): any; + + /** + * Write a 'verbose' level log. + */ + verbose?(message: any, ...optionalParams: any[]): any; + + /** + * Set log levels. + * @param levels log levels + */ + setLogLevels?(levels: LogLevel[]): any; +} diff --git a/packages/debug/package.json b/packages/debug/package.json new file mode 100644 index 0000000..dcc4445 --- /dev/null +++ b/packages/debug/package.json @@ -0,0 +1,12 @@ +{ + "name": "@gland/debug", + "version": "1.0.0", + "author": "Mahdi", + "license": "MIT", + "scripts": { + "build": "tsc" + }, + "devDependencies": { + "typescript": "^5.5.4" + } +} diff --git a/packages/debug/services/index.ts b/packages/debug/services/index.ts new file mode 100644 index 0000000..6820e22 --- /dev/null +++ b/packages/debug/services/index.ts @@ -0,0 +1 @@ +export * from './logger.service'; diff --git a/packages/debug/services/logger.service.ts b/packages/debug/services/logger.service.ts new file mode 100644 index 0000000..87efc3a --- /dev/null +++ b/packages/debug/services/logger.service.ts @@ -0,0 +1,82 @@ +import { LoggerService } from '../interfaces/logger.interfaces'; +import { LogLevel } from '../types/logger.types'; +const DEFAULT_LOGGER = console; + +export class Logger implements LoggerService { + protected static logLevels: LogLevel[] = ['log', 'error', 'warn', 'debug', 'verbose']; + private static staticInstance: LoggerService = DEFAULT_LOGGER; + private static defaultContext = 'Application'; + + constructor(protected context?: string, protected options: { timestamp?: boolean } = {}) {} + + /** + * Write an 'error' level log. + */ + error(message: any, stack?: string, context?: string): void; + error(message: any, ...optionalParams: [...any, string?, string?]): void; + error(message: any, ...optionalParams: any[]) { + this.logWithLevel('error', message, optionalParams); + } + + /** + * Write a 'log' level log. + */ + log(message: any, context?: string): void; + log(message: any, ...optionalParams: [...any, string?]): void; + log(message: any, ...optionalParams: any[]) { + this.logWithLevel('log', message, optionalParams); + } + + /** + * Write a 'warn' level log. + */ + warn(message: any, context?: string): void; + warn(message: any, ...optionalParams: [...any, string?]): void; + warn(message: any, ...optionalParams: any[]) { + this.logWithLevel('warn', message, optionalParams); + } + + /** + * Write a 'debug' level log. + */ + debug(message: any, context?: string): void; + debug(message: any, ...optionalParams: [...any, string?]): void; + debug(message: any, ...optionalParams: any[]) { + this.logWithLevel('debug', message, optionalParams); + } + + /** + * Write a 'verbose' level log. + */ + verbose(message: any, context?: string): void; + verbose(message: any, ...optionalParams: [...any, string?]): void; + verbose(message: any, ...optionalParams: any[]) { + this.logWithLevel('verbose', message, optionalParams); + } + static setLogLevels(levels: LogLevel[]): void { + this.logLevels = levels; + } + + static getTimestamp(): string { + return new Date().toISOString(); + } + + static isLevelEnabled(level: LogLevel): boolean { + return this.logLevels!.includes(level); + } + + private logWithLevel(level: LogLevel, message: any, params: any[]): void { + if (!Logger.isLevelEnabled(level)) return; + + const logger = Logger.staticInstance; + const context = this.context || Logger.defaultContext; + const timestamp = this.options.timestamp ? `[${Logger.getTimestamp()}] ` : ''; + + const formattedMessage = `${timestamp}[${context}] ${message}`; + if (typeof logger[level] === 'function') { + logger[level](formattedMessage, ...params); + } else { + logger.log(formattedMessage, ...params); + } + } +} diff --git a/packages/debug/tsconfig.json b/packages/debug/tsconfig.json new file mode 100644 index 0000000..0b63df2 --- /dev/null +++ b/packages/debug/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "." + }, + "files": [], + "include": ["**/*.ts"], + "exclude": ["node_modules"], + "references": [] +} diff --git a/packages/debug/types/index.ts b/packages/debug/types/index.ts new file mode 100644 index 0000000..e8c8829 --- /dev/null +++ b/packages/debug/types/index.ts @@ -0,0 +1 @@ +export * from './logger.types'; diff --git a/packages/debug/types/logger.types.ts b/packages/debug/types/logger.types.ts new file mode 100644 index 0000000..3435711 --- /dev/null +++ b/packages/debug/types/logger.types.ts @@ -0,0 +1,4 @@ +/** + * @public + */ +export type LogLevel = 'log' | 'error' | 'warn' | 'debug' | 'verbose'; diff --git a/packages/events/core/event-manager.ts b/packages/events/core/event-manager.ts index b432275..9ec5cc6 100644 --- a/packages/events/core/event-manager.ts +++ b/packages/events/core/event-manager.ts @@ -31,13 +31,13 @@ export class EventManager { return new ImmediateStrategy(); } } - async publish(qualified: QualifiedEvent, data: D): Promise { + async publish(qualified: QualifiedEvent, data?: D): Promise { const { phase, type } = EventMapper.parseQualifiedType(qualified); const event: Event = { type, phase, - data, + data: data ?? ({} as D), lifecycle: { startedAt: new Date(), },