@nlabs/arkhamjs-middleware-logger
Version:
Add console logging for ArkhamJS
145 lines (144 loc) • 17 kB
JavaScript
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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