UNPKG

ng-commander

Version:

Command pattern for Angular applications

187 lines (180 loc) 7.79 kB
import * as i0 from '@angular/core'; import { Injectable, NgModule } from '@angular/core'; import { BehaviorSubject, Subject, concatMap, catchError } from 'rxjs'; var CommandEventType; (function (CommandEventType) { CommandEventType["START"] = "start"; CommandEventType["SUCCESS"] = "success"; CommandEventType["FAIL"] = "fail"; CommandEventType["RESTART"] = "restart"; })(CommandEventType || (CommandEventType = {})); var CommanderState; (function (CommanderState) { CommanderState[CommanderState["IDLE"] = 0] = "IDLE"; CommanderState[CommanderState["EXECUTING"] = 1] = "EXECUTING"; CommanderState[CommanderState["DONE"] = 2] = "DONE"; CommanderState[CommanderState["ERROR"] = 3] = "ERROR"; })(CommanderState || (CommanderState = {})); var CommandsType; (function (CommandsType) { CommandsType[CommandsType["WAITING"] = 0] = "WAITING"; CommandsType[CommandsType["DONE"] = 1] = "DONE"; CommandsType[CommandsType["ERROR"] = 2] = "ERROR"; })(CommandsType || (CommandsType = {})); class Commander { // Use BehaviorSubjects instead of arrays commandsSubject = new BehaviorSubject([]); commandsDoneSubject = new BehaviorSubject([]); commandsInErrorSubject = new BehaviorSubject([]); stateSubject = new BehaviorSubject(CommanderState.IDLE); // Nouveau sujet pour les événements de commande eventsSubject = new BehaviorSubject([]); processingCommand = new Subject(); // Expose as Observables commands$ = this.commandsSubject.asObservable(); commandsDone$ = this.commandsDoneSubject.asObservable(); commandsInError$ = this.commandsInErrorSubject.asObservable(); state$ = this.stateSubject.asObservable(); events$ = this.eventsSubject.asObservable(); constructor() { this.processingCommand .pipe(concatMap(({ command }) => { this.stateSubject.next(CommanderState.EXECUTING); // Ajouter un événement START this.trackEvent(CommandEventType.START, command); return command.execute().pipe(concatMap((result) => { return [{ command, result, isError: false }]; }), catchError((error) => { return [{ command, error, isError: true }]; })); })) .subscribe({ next: (data) => { if (data.isError) { this.stateSubject.next(CommanderState.ERROR); const currentErrors = this.commandsInErrorSubject.value; this.commandsInErrorSubject.next([...currentErrors, data.command]); // Ajouter un événement FAIL avec l'erreur si disponible this.trackEvent(CommandEventType.FAIL, data.command, 'error' in data ? data.error : undefined); } else { this.stateSubject.next(CommanderState.DONE); const currentDone = this.commandsDoneSubject.value; this.commandsDoneSubject.next([...currentDone, data.command]); // Ajouter un événement SUCCESS avec le résultat si disponible this.trackEvent(CommandEventType.SUCCESS, data.command, 'result' in data ? data.result : undefined); } this.executeNextCommand(); }, error: (errorObj) => { this.stateSubject.next(CommanderState.ERROR); this.executeNextCommand(); }, }); } addCommand(command) { // Initialiser le tableau d'événements si nécessaire if (!command.events) { command.events = []; } const currentCommands = this.commandsSubject.value; this.commandsSubject.next([...currentCommands, command]); if (currentCommands.length === 0) { this.executeNextCommand(); } } replayCommandsInError() { const commandsInError = this.commandsInErrorSubject.value; this.commandsInErrorSubject.next([]); if (commandsInError.length > 0) { // Ajouter un événement RESTART pour chaque commande commandsInError.forEach((command) => { this.trackEvent(CommandEventType.RESTART, command); }); this.commandsSubject.next(commandsInError); this.executeNextCommand(); } } getCommands(type) { switch (type) { case CommandsType.WAITING: return this.commandsSubject.value; case CommandsType.DONE: return this.commandsDoneSubject.value; case CommandsType.ERROR: return this.commandsInErrorSubject.value; } } getState() { return this.stateSubject.value; } // Obtenir tous les événements getEvents() { return this.eventsSubject.value; } // Obtenir les événements pour une commande spécifique getCommandEvents(commandId) { return this.eventsSubject.value.filter((event) => event.command.id === commandId); } // Méthode privée pour tracer un événement trackEvent(type, command, data) { const event = { type, command, data, timestamp: new Date(), }; // Ajouter l'événement à la collection globale const currentEvents = this.eventsSubject.value; this.eventsSubject.next([...currentEvents, event]); // Ajouter l'événement à la commande elle-même if (!command.events) { command.events = [event]; } else { command.events.push(event); } } executeNextCommand() { const currentCommands = this.commandsSubject.value; if (currentCommands.length > 0) { const [command, ...rest] = currentCommands; this.commandsSubject.next(rest); this.stateSubject.next(CommanderState.EXECUTING); this.processingCommand.next({ command, result: null }); } else { this.stateSubject.next(CommanderState.IDLE); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: Commander, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: Commander, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: Commander, decorators: [{ type: Injectable, args: [{ providedIn: 'root', }] }], ctorParameters: () => [] }); class NgCommanderModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NgCommanderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: NgCommanderModule }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NgCommanderModule, providers: [Commander] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NgCommanderModule, decorators: [{ type: NgModule, args: [{ declarations: [], imports: [], providers: [Commander], exports: [], }] }] }); /* * Public API Surface of ng-commander */ /** * Generated bundle index. Do not edit. */ export { Commander, CommanderState, CommandsType, NgCommanderModule }; //# sourceMappingURL=ng-commander.mjs.map