UNPKG

@ngxs/logger-plugin

Version:

logger plugin for @ngxs/store

195 lines (185 loc) 7.28 kB
import * as i0 from '@angular/core'; import { InjectionToken, inject, Injector, runInInjectionContext, Injectable, NgModule, makeEnvironmentProviders } from '@angular/core'; import { Store, withNgxsPlugin } from '@ngxs/store'; import { tap, catchError } from 'rxjs'; import { getActionTypeFromInstance } from '@ngxs/store/plugins'; class LogWriter { constructor(options) { this.options = options; this.options = this.options || {}; this.logger = options.logger || console; } startGroup(message) { const startGroupFn = this.options.collapsed ? this.logger.groupCollapsed : this.logger.group; try { startGroupFn.call(this.logger, message); } catch (e) { console.log(message); } } endGroup() { try { this.logger.groupEnd(); } catch (e) { this.logger.log('—— log end ——'); } } logGrey(title, payload) { const greyStyle = 'color: #9E9E9E; font-weight: bold'; this.log(title, greyStyle, payload); } logGreen(title, payload) { const greenStyle = 'color: #4CAF50; font-weight: bold'; this.log(title, greenStyle, payload); } logRedish(title, payload) { const redishStyle = 'color: #FD8182; font-weight: bold'; this.log(title, redishStyle, payload); } log(title, color, payload) { this.logger.log('%c ' + title, color, payload); } } const repeat = (str, times) => new Array(times + 1).join(str); const pad = (num, maxLength) => repeat('0', maxLength - num.toString().length) + num; function formatTime(time) { return (pad(time.getHours(), 2) + `:` + pad(time.getMinutes(), 2) + `:` + pad(time.getSeconds(), 2) + `.` + pad(time.getMilliseconds(), 3)); } class ActionLogger { constructor(action, store, logWriter) { this.action = action; this.store = store; this.logWriter = logWriter; } dispatched(state) { const actionName = getActionTypeFromInstance(this.action); const formattedTime = formatTime(new Date()); const message = `action ${actionName} @ ${formattedTime}`; this.logWriter.startGroup(message); // print payload only if at least one property is supplied if (this._hasPayload(this.action)) { this.logWriter.logGrey('payload', { ...this.action }); } this.logWriter.logGrey('prev state', state); } completed(nextState) { this.logWriter.logGreen('next state', nextState); this.logWriter.endGroup(); } errored(error) { this.logWriter.logRedish('next state after error', this.store.snapshot()); this.logWriter.logRedish('error', error); this.logWriter.endGroup(); } _hasPayload(event) { const nonEmptyProperties = this._getNonEmptyProperties(event); return nonEmptyProperties.length > 0; } _getNonEmptyProperties(event) { const keys = Object.keys(event); const values = keys.map(key => event[key]); return values.filter(value => value !== undefined); } } const NGXS_LOGGER_PLUGIN_OPTIONS = new InjectionToken('NGXS_LOGGER_PLUGIN_OPTIONS'); class NgxsLoggerPlugin { constructor() { this._options = inject(NGXS_LOGGER_PLUGIN_OPTIONS); this._injector = inject(Injector); } handle(state, event, next) { if (this._options.disabled || this._skipLogging(state, event)) { return next(state, event); } this._logWriter ||= new LogWriter(this._options); // Retrieve lazily to avoid cyclic dependency exception this._store ||= this._injector.get(Store); const actionLogger = new ActionLogger(event, this._store, this._logWriter); actionLogger.dispatched(state); return next(state, event).pipe(tap(nextState => { actionLogger.completed(nextState); }), catchError(error => { actionLogger.errored(error); throw error; })); } _skipLogging(state, event) { // Run the `filter: () => ...` function within the injection context so // that the user can access the dependency injection and inject services // to retrieve properties. This will help determine whether or not to log the action. const allowLogging = runInInjectionContext(this._injector, () => this._options.filter(event, state)); return !allowLogging; } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgxsLoggerPlugin, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgxsLoggerPlugin }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgxsLoggerPlugin, decorators: [{ type: Injectable }] }); const USER_OPTIONS = new InjectionToken('LOGGER_USER_OPTIONS'); function loggerOptionsFactory(options) { const defaultLoggerOptions = { logger: console, collapsed: false, disabled: false, filter: () => true }; return { ...defaultLoggerOptions, ...options }; } class NgxsLoggerPluginModule { static forRoot(options) { return { ngModule: NgxsLoggerPluginModule, providers: [ withNgxsPlugin(NgxsLoggerPlugin), { provide: USER_OPTIONS, useValue: options }, { provide: NGXS_LOGGER_PLUGIN_OPTIONS, useFactory: loggerOptionsFactory, deps: [USER_OPTIONS] } ] }; } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgxsLoggerPluginModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.0", ngImport: i0, type: NgxsLoggerPluginModule }); } /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgxsLoggerPluginModule }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgxsLoggerPluginModule, decorators: [{ type: NgModule }] }); function withNgxsLoggerPlugin(options) { return makeEnvironmentProviders([ withNgxsPlugin(NgxsLoggerPlugin), { provide: USER_OPTIONS, useValue: options }, { provide: NGXS_LOGGER_PLUGIN_OPTIONS, useFactory: loggerOptionsFactory, deps: [USER_OPTIONS] } ]); } /** * The public api for consumers of @ngxs/logger-plugin */ /** * Generated bundle index. Do not edit. */ export { NGXS_LOGGER_PLUGIN_OPTIONS, NgxsLoggerPlugin, NgxsLoggerPluginModule, withNgxsLoggerPlugin }; //# sourceMappingURL=ngxs-logger-plugin.mjs.map