UNPKG

@nlabs/arkhamjs-middleware-logger

Version:

Add console logging for ArkhamJS

145 lines (144 loc) 17 kB
function _define_property(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /** * Copyright (c) 2018-Present, Nitrogen Labs, Inc. * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. */ /* eslint-disable no-console */ import { cloneDeep } from '@nlabs/utils/objects/clone'; import { isEqual } from '@nlabs/utils/checks/isEqual'; export const LoggerDebugLevel = { DISABLED: 0, LOGS: 1, DISPATCH: 2 }; export class Logger { /** * Set configuration options. * * @param {object} options Configuration options. */ config(options) { this.options = { ...this.defaultOptions, ...options }; } /** * Logs errors in the console. Will also call the debugErrorFnc method set in the config. * * @param {object} obj A list of JavaScript objects to output. The string representations of each of these objects * are appended together in the order listed and output. */ debugError(...obj) { const { debugErrorFnc, debugLevel } = this.options; if (debugLevel) { console.error(...obj); } if (debugErrorFnc) { debugErrorFnc(debugLevel, ...obj); } } /** * Logs informational messages to the console. Will also call the debugInfoFnc method set in the config. * * @param {object} obj A list of JavaScript objects to output. The string representations of each of these objects * are appended together in the order listed and output. */ debugInfo(...obj) { const { debugInfoFnc, debugLevel } = this.options; if (debugLevel) { console.info(...obj); } if (debugInfoFnc) { debugInfoFnc(debugLevel, ...obj); } } /** * Logs data in the console. Only logs when in debug mode. Will also call the debugLogFnc method set in the config. * * @param {object} obj A list of JavaScript objects to output. The string representations of each of these objects * are appended together in the order listed and output. */ debugLog(...obj) { const { debugLogFnc, debugLevel } = this.options; if (debugLevel) { console.log(...obj); } if (debugLogFnc) { debugLogFnc(debugLevel, ...obj); } } /** * Enables the console debugger. * * @param {number} level Enable or disable the debugger. Uses the constants: * LoggerDebugLevel.DISABLED (0) - Disable. * LoggerDebugLevel.LOGS (1) - Enable console logs. * LoggerDebugLevel.DISPATCH (2) - Enable console logs and dispatch action data (default). */ enableDebugger(level = LoggerDebugLevel.DISPATCH) { this.options = { ...this.options, debugLevel: level }; } /** * Get the current FluxLogger options. * * @returns {LoggerOptions} the FluxLogger options object. */ getOptions() { return this.options; } preDispatch(action, store) { this.previousStore = store; return Promise.resolve(action); } postDispatch(action, store) { const { debugLevel } = this.options; if (debugLevel && debugLevel > LoggerDebugLevel.LOGS) { const { type } = action; const hasChanged = !isEqual(store, this.previousStore); const updatedLabel = hasChanged ? 'Changed State' : 'Unchanged State'; const updatedColor = hasChanged ? '#00d484' : '#959595'; const updatedStore = cloneDeep(store); if (console.groupCollapsed) { console.groupCollapsed(`FLUX DISPATCH: ${type}`); console.log('%c Action: ', 'color: #00C4FF', action); console.log('%c Last State: ', 'color: #959595', this.previousStore); console.log(`%c ${updatedLabel}: `, `color: ${updatedColor}`, updatedStore); console.groupEnd(); } else { console.log(`FLUX DISPATCH: ${type}`); console.log('Action: ', action); console.log('Last State: ', this.previousStore); console.log(`${updatedLabel}: `, updatedStore); } } return Promise.resolve(action); } constructor(options){ _define_property(this, "name", 'Logger'); _define_property(this, "previousStore", {}); _define_property(this, "defaultOptions", { debugLevel: LoggerDebugLevel.DISABLED }); _define_property(this, "options", this.defaultOptions); // Methods this.config = this.config.bind(this); this.debugError = this.debugError.bind(this); this.debugInfo = this.debugInfo.bind(this); this.debugLog = this.debugLog.bind(this); this.enableDebugger = this.enableDebugger.bind(this); this.getOptions = this.getOptions.bind(this); this.postDispatch = this.postDispatch.bind(this); this.preDispatch = this.preDispatch.bind(this); // Configuration this.config(options); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L2Fya2hhbWpzL3BhY2thZ2VzL2Fya2hhbWpzLW1pZGRsZXdhcmUtbG9nZ2VyL3NyYy9Mb2dnZXIvTG9nZ2VyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDE4LVByZXNlbnQsIE5pdHJvZ2VuIExhYnMsIEluYy5cbiAqIENvcHlyaWdodHMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgdGhlIGFjY29tcGFueWluZyBMSUNFTlNFIGZpbGUgZm9yIHRlcm1zLlxuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5pbXBvcnQge2Nsb25lRGVlcH0gZnJvbSAnQG5sYWJzL3V0aWxzL29iamVjdHMvY2xvbmUnO1xuaW1wb3J0IHtpc0VxdWFsfSBmcm9tICdAbmxhYnMvdXRpbHMvY2hlY2tzL2lzRXF1YWwnO1xuXG5pbXBvcnQgdHlwZSB7Rmx1eEFjdGlvbn0gZnJvbSAnQG5sYWJzL2Fya2hhbWpzJztcblxuZXhwb3J0IGNvbnN0IExvZ2dlckRlYnVnTGV2ZWwgPSB7XG4gIERJU0FCTEVEOiAwLFxuICBMT0dTOiAxLFxuICBESVNQQVRDSDogMlxufSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgTG9nZ2VyRGVidWdMZXZlbFR5cGUgPSB0eXBlb2YgTG9nZ2VyRGVidWdMZXZlbFtrZXlvZiB0eXBlb2YgTG9nZ2VyRGVidWdMZXZlbF07XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9nZ2VyT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGRlYnVnTGV2ZWw/OiBMb2dnZXJEZWJ1Z0xldmVsVHlwZTtcbiAgcmVhZG9ubHkgZGVidWdFcnJvckZuYz86IChkZWJ1Z0xldmVsOiBudW1iZXIsIC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkO1xuICByZWFkb25seSBkZWJ1Z0luZm9GbmM/OiAoZGVidWdMZXZlbDogbnVtYmVyLCAuLi5hcmdzOiBhbnlbXSkgPT4gdm9pZDtcbiAgcmVhZG9ubHkgZGVidWdMb2dGbmM/OiAoZGVidWdMZXZlbDogbnVtYmVyLCAuLi5hcmdzOiBhbnlbXSkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGNsYXNzIExvZ2dlciB7XG4gIG5hbWU6IHN0cmluZyA9ICdMb2dnZXInO1xuXG4gIHByaXZhdGUgcHJldmlvdXNTdG9yZTogYW55ID0ge307XG4gIHByaXZhdGUgZGVmYXVsdE9wdGlvbnM6IExvZ2dlck9wdGlvbnMgPSB7XG4gICAgZGVidWdMZXZlbDogTG9nZ2VyRGVidWdMZXZlbC5ESVNBQkxFRFxuICB9O1xuICBwcml2YXRlIG9wdGlvbnM6IExvZ2dlck9wdGlvbnMgPSB0aGlzLmRlZmF1bHRPcHRpb25zO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IExvZ2dlck9wdGlvbnMpIHtcbiAgICAvLyBNZXRob2RzXG4gICAgdGhpcy5jb25maWcgPSB0aGlzLmNvbmZpZy5iaW5kKHRoaXMpO1xuICAgIHRoaXMuZGVidWdFcnJvciA9IHRoaXMuZGVidWdFcnJvci5iaW5kKHRoaXMpO1xuICAgIHRoaXMuZGVidWdJbmZvID0gdGhpcy5kZWJ1Z0luZm8uYmluZCh0aGlzKTtcbiAgICB0aGlzLmRlYnVnTG9nID0gdGhpcy5kZWJ1Z0xvZy5iaW5kKHRoaXMpO1xuICAgIHRoaXMuZW5hYmxlRGVidWdnZXIgPSB0aGlzLmVuYWJsZURlYnVnZ2VyLmJpbmQodGhpcyk7XG4gICAgdGhpcy5nZXRPcHRpb25zID0gdGhpcy5nZXRPcHRpb25zLmJpbmQodGhpcyk7XG4gICAgdGhpcy5wb3N0RGlzcGF0Y2ggPSB0aGlzLnBvc3REaXNwYXRjaC5iaW5kKHRoaXMpO1xuICAgIHRoaXMucHJlRGlzcGF0Y2ggPSB0aGlzLnByZURpc3BhdGNoLmJpbmQodGhpcyk7XG5cbiAgICAvLyBDb25maWd1cmF0aW9uXG4gICAgdGhpcy5jb25maWcob3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGNvbmZpZ3VyYXRpb24gb3B0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnMgQ29uZmlndXJhdGlvbiBvcHRpb25zLlxuICAgKi9cbiAgY29uZmlnKG9wdGlvbnM6IExvZ2dlck9wdGlvbnMpOiB2b2lkIHtcbiAgICB0aGlzLm9wdGlvbnMgPSB7Li4udGhpcy5kZWZhdWx0T3B0aW9ucywgLi4ub3B0aW9uc307XG4gIH1cblxuICAvKipcbiAgICogTG9ncyBlcnJvcnMgaW4gdGhlIGNvbnNvbGUuIFdpbGwgYWxzbyBjYWxsIHRoZSBkZWJ1Z0Vycm9yRm5jIG1ldGhvZCBzZXQgaW4gdGhlIGNvbmZpZy5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IG9iaiBBIGxpc3Qgb2YgSmF2YVNjcmlwdCBvYmplY3RzIHRvIG91dHB1dC4gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbnMgb2YgZWFjaCBvZiB0aGVzZSBvYmplY3RzXG4gICAqIGFyZSBhcHBlbmRlZCB0b2dldGhlciBpbiB0aGUgb3JkZXIgbGlzdGVkIGFuZCBvdXRwdXQuXG4gICAqL1xuICBkZWJ1Z0Vycm9yKC4uLm9iajogYW55W10pOiB2b2lkIHtcbiAgICBjb25zdCB7ZGVidWdFcnJvckZuYywgZGVidWdMZXZlbH0gPSB0aGlzLm9wdGlvbnM7XG5cbiAgICBpZihkZWJ1Z0xldmVsKSB7XG4gICAgICBjb25zb2xlLmVycm9yKC4uLm9iaik7XG4gICAgfVxuXG4gICAgaWYoZGVidWdFcnJvckZuYykge1xuICAgICAgZGVidWdFcnJvckZuYyhkZWJ1Z0xldmVsIGFzIG51bWJlciwgLi4ub2JqKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTG9ncyBpbmZvcm1hdGlvbmFsIG1lc3NhZ2VzIHRvIHRoZSBjb25zb2xlLiBXaWxsIGFsc28gY2FsbCB0aGUgZGVidWdJbmZvRm5jIG1ldGhvZCBzZXQgaW4gdGhlIGNvbmZpZy5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IG9iaiBBIGxpc3Qgb2YgSmF2YVNjcmlwdCBvYmplY3RzIHRvIG91dHB1dC4gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbnMgb2YgZWFjaCBvZiB0aGVzZSBvYmplY3RzXG4gICAqIGFyZSBhcHBlbmRlZCB0b2dldGhlciBpbiB0aGUgb3JkZXIgbGlzdGVkIGFuZCBvdXRwdXQuXG4gICAqL1xuICBkZWJ1Z0luZm8oLi4ub2JqOiBhbnlbXSk6IHZvaWQge1xuICAgIGNvbnN0IHtkZWJ1Z0luZm9GbmMsIGRlYnVnTGV2ZWx9ID0gdGhpcy5vcHRpb25zO1xuXG4gICAgaWYoZGVidWdMZXZlbCkge1xuICAgICAgY29uc29sZS5pbmZvKC4uLm9iaik7XG4gICAgfVxuXG4gICAgaWYoZGVidWdJbmZvRm5jKSB7XG4gICAgICBkZWJ1Z0luZm9GbmMoZGVidWdMZXZlbCBhcyBudW1iZXIsIC4uLm9iaik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIExvZ3MgZGF0YSBpbiB0aGUgY29uc29sZS4gT25seSBsb2dzIHdoZW4gaW4gZGVidWcgbW9kZS4gIFdpbGwgYWxzbyBjYWxsIHRoZSBkZWJ1Z0xvZ0ZuYyBtZXRob2Qgc2V0IGluIHRoZSBjb25maWcuXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBvYmogQSBsaXN0IG9mIEphdmFTY3JpcHQgb2JqZWN0cyB0byBvdXRwdXQuIFRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb25zIG9mIGVhY2ggb2YgdGhlc2Ugb2JqZWN0c1xuICAgKiBhcmUgYXBwZW5kZWQgdG9nZXRoZXIgaW4gdGhlIG9yZGVyIGxpc3RlZCBhbmQgb3V0cHV0LlxuICAgKi9cbiAgZGVidWdMb2coLi4ub2JqOiBhbnlbXSk6IHZvaWQge1xuICAgIGNvbnN0IHtkZWJ1Z0xvZ0ZuYywgZGVidWdMZXZlbH0gPSB0aGlzLm9wdGlvbnM7XG5cbiAgICBpZihkZWJ1Z0xldmVsKSB7XG4gICAgICBjb25zb2xlLmxvZyguLi5vYmopO1xuICAgIH1cblxuICAgIGlmKGRlYnVnTG9nRm5jKSB7XG4gICAgICBkZWJ1Z0xvZ0ZuYyhkZWJ1Z0xldmVsIGFzIG51bWJlciwgLi4ub2JqKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRW5hYmxlcyB0aGUgY29uc29sZSBkZWJ1Z2dlci5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IGxldmVsIEVuYWJsZSBvciBkaXNhYmxlIHRoZSBkZWJ1Z2dlci4gVXNlcyB0aGUgY29uc3RhbnRzOlxuICAgKiAgIExvZ2dlckRlYnVnTGV2ZWwuRElTQUJMRUQgKDApIC0gRGlzYWJsZS5cbiAgICogICBMb2dnZXJEZWJ1Z0xldmVsLkxPR1MgKDEpIC0gRW5hYmxlIGNvbnNvbGUgbG9ncy5cbiAgICogICBMb2dnZXJEZWJ1Z0xldmVsLkRJU1BBVENIICgyKSAtIEVuYWJsZSBjb25zb2xlIGxvZ3MgYW5kIGRpc3BhdGNoIGFjdGlvbiBkYXRhIChkZWZhdWx0KS5cbiAgICovXG4gIGVuYWJsZURlYnVnZ2VyKGxldmVsOiBMb2dnZXJEZWJ1Z0xldmVsVHlwZSA9IExvZ2dlckRlYnVnTGV2ZWwuRElTUEFUQ0gpOiB2b2lkIHtcbiAgICB0aGlzLm9wdGlvbnMgPSB7Li4udGhpcy5vcHRpb25zLCBkZWJ1Z0xldmVsOiBsZXZlbH07XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBjdXJyZW50IEZsdXhMb2dnZXIgb3B0aW9ucy5cbiAgICpcbiAgICogQHJldHVybnMge0xvZ2dlck9wdGlvbnN9IHRoZSBGbHV4TG9nZ2VyIG9wdGlvbnMgb2JqZWN0LlxuICAgKi9cbiAgZ2V0T3B0aW9ucygpOiBMb2dnZXJPcHRpb25zIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zO1xuICB9XG5cbiAgcHJlRGlzcGF0Y2goYWN0aW9uOiBGbHV4QWN0aW9uLCBzdG9yZSk6IFByb21pc2U8Rmx1eEFjdGlvbj4ge1xuICAgIHRoaXMucHJldmlvdXNTdG9yZSA9IHN0b3JlO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoYWN0aW9uKTtcbiAgfVxuXG4gIHBvc3REaXNwYXRjaChhY3Rpb246IEZsdXhBY3Rpb24sIHN0b3JlOiBvYmplY3QpOiBQcm9taXNlPEZsdXhBY3Rpb24+IHtcbiAgICBjb25zdCB7ZGVidWdMZXZlbH0gPSB0aGlzLm9wdGlvbnM7XG5cbiAgICBpZihkZWJ1Z0xldmVsICYmIGRlYnVnTGV2ZWwgPiBMb2dnZXJEZWJ1Z0xldmVsLkxPR1MpIHtcbiAgICAgIGNvbnN0IHt0eXBlfSA9IGFjdGlvbjtcbiAgICAgIGNvbnN0IGhhc0NoYW5nZWQgPSAhaXNFcXVhbChzdG9yZSwgdGhpcy5wcmV2aW91c1N0b3JlKTtcbiAgICAgIGNvbnN0IHVwZGF0ZWRMYWJlbCA9IGhhc0NoYW5nZWQgPyAnQ2hhbmdlZCBTdGF0ZScgOiAnVW5jaGFuZ2VkIFN0YXRlJztcbiAgICAgIGNvbnN0IHVwZGF0ZWRDb2xvciA9IGhhc0NoYW5nZWQgPyAnIzAwZDQ4NCcgOiAnIzk1OTU5NSc7XG4gICAgICBjb25zdCB1cGRhdGVkU3RvcmUgPSBjbG9uZURlZXAoc3RvcmUpO1xuXG4gICAgICBpZihjb25zb2xlLmdyb3VwQ29sbGFwc2VkKSB7XG4gICAgICAgIGNvbnNvbGUuZ3JvdXBDb2xsYXBzZWQoYEZMVVggRElTUEFUQ0g6ICR7dHlwZX1gKTtcbiAgICAgICAgY29uc29sZS5sb2coJyVjIEFjdGlvbjogJywgJ2NvbG9yOiAjMDBDNEZGJywgYWN0aW9uKTtcbiAgICAgICAgY29uc29sZS5sb2coJyVjIExhc3QgU3RhdGU6ICcsICdjb2xvcjogIzk1OTU5NScsIHRoaXMucHJldmlvdXNTdG9yZSk7XG4gICAgICAgIGNvbnNvbGUubG9nKGAlYyAke3VwZGF0ZWRMYWJlbH06IGAsIGBjb2xvcjogJHt1cGRhdGVkQ29sb3J9YCwgdXBkYXRlZFN0b3JlKTtcbiAgICAgICAgY29uc29sZS5ncm91cEVuZCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coYEZMVVggRElTUEFUQ0g6ICR7dHlwZX1gKTtcbiAgICAgICAgY29uc29sZS5sb2coJ0FjdGlvbjogJywgYWN0aW9uKTtcbiAgICAgICAgY29uc29sZS5sb2coJ0xhc3QgU3RhdGU6ICcsIHRoaXMucHJldmlvdXNTdG9yZSk7XG4gICAgICAgIGNvbnNvbGUubG9nKGAke3VwZGF0ZWRMYWJlbH06IGAsIHVwZGF0ZWRTdG9yZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShhY3Rpb24pO1xuICB9XG59XG4iXSwibmFtZXMiOlsiY2xvbmVEZWVwIiwiaXNFcXVhbCIsIkxvZ2dlckRlYnVnTGV2ZWwiLCJESVNBQkxFRCIsIkxPR1MiLCJESVNQQVRDSCIsIkxvZ2dlciIsImNvbmZpZyIsIm9wdGlvbnMiLCJkZWZhdWx0T3B0aW9ucyIsImRlYnVnRXJyb3IiLCJvYmoiLCJkZWJ1Z0Vycm9yRm5jIiwiZGVidWdMZXZlbCIsImNvbnNvbGUiLCJlcnJvciIsImRlYnVnSW5mbyIsImRlYnVnSW5mb0ZuYyIsImluZm8iLCJkZWJ1Z0xvZyIsImRlYnVnTG9nRm5jIiwibG9nIiwiZW5hYmxlRGVidWdnZXIiLCJsZXZlbCIsImdldE9wdGlvbnMiLCJwcmVEaXNwYXRjaCIsImFjdGlvbiIsInN0b3JlIiwicHJldmlvdXNTdG9yZSIsIlByb21pc2UiLCJyZXNvbHZlIiwicG9zdERpc3BhdGNoIiwidHlwZSIsImhhc0NoYW5nZWQiLCJ1cGRhdGVkTGFiZWwiLCJ1cGRhdGVkQ29sb3IiLCJ1cGRhdGVkU3RvcmUiLCJncm91cENvbGxhcHNlZCIsImdyb3VwRW5kIiwibmFtZSIsImJpbmQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFBQTs7O0NBR0MsR0FDRCw2QkFBNkIsR0FDN0IsU0FBUUEsU0FBUyxRQUFPLDZCQUE2QjtBQUNyRCxTQUFRQyxPQUFPLFFBQU8sOEJBQThCO0FBSXBELE9BQU8sTUFBTUMsbUJBQW1CO0lBQzlCQyxVQUFVO0lBQ1ZDLE1BQU07SUFDTkMsVUFBVTtBQUNaLEVBQVc7QUFXWCxPQUFPLE1BQU1DO0lBd0JYOzs7O0dBSUMsR0FDREMsT0FBT0MsT0FBc0IsRUFBUTtRQUNuQyxJQUFJLENBQUNBLE9BQU8sR0FBRztZQUFDLEdBQUcsSUFBSSxDQUFDQyxjQUFjO1lBQUUsR0FBR0QsT0FBTztRQUFBO0lB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