Skip to content

Instantly share code, notes, and snippets.

@artalar
Created March 15, 2018 11:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save artalar/a371329b1047dbfc0e93210881f62d4a to your computer and use it in GitHub Desktop.
Save artalar/a371329b1047dbfc0e93210881f62d4a to your computer and use it in GitHub Desktop.
import { inDevMode } from './enviroment';
const isObject = object => typeof object === 'object' && object !== null;
function Logger(location, addSnapshot) {
const logs = [];
this.setLog = (previosObject, newObject, key, description = 'objects not equal') => {
const log = {
previosObject,
newObject,
key,
description,
location,
};
if (addSnapshot) {
try {
log.previosObjectSnapshot = JSON.parse(JSON.stringify(previosObject));
// eslint-disable-next-line
} catch (e) {}
try {
log.newObjectSnapshot = JSON.parse(JSON.stringify(newObject));
// eslint-disable-next-line
} catch (e) {}
}
logs.push(log);
};
this.setLogs = newLogs => logs.push(newLogs);
this.getLogs = () => logs;
}
export const getChangedValues = ({
previosObject,
newObject,
location = '',
deep = true,
addSnapshot = false,
resultToPlainArray = false,
}) => {
// FIXME: определиться с возможной глубиной
if (location.length > 200) {
// eslint-disable-next-line
if (inDevMode()) console.error('too deep object in', location);
return [];
}
const logger = new Logger(location, addSnapshot);
const keysOfPreviosObject = Object.getOwnPropertyNames(previosObject);
const keysOfNewObject = Object.getOwnPropertyNames(newObject);
keysOfNewObject.forEach(newKey => {
if (keysOfPreviosObject.indexOf(newKey) === -1) {
logger.setLog(previosObject, newObject, newKey, 'no key in the previos object');
}
});
keysOfPreviosObject.forEach(prevKey => {
const previosValue = previosObject[prevKey];
const newValue = newObject[prevKey];
if (keysOfNewObject.indexOf(prevKey) === -1) {
logger.setLog(previosObject, newObject, prevKey, 'no key in the new object');
} else if (previosValue !== newValue) {
logger.setLog(previosObject, newObject, prevKey, 'key values is not equal');
if (deep && isObject(previosValue) && isObject(newValue) && prevKey !== 'children') {
const deepLogs = getChangedValues({
previosObject: previosValue,
newObject: newValue,
location: `${location}.${prevKey}`,
});
if (deepLogs.length) {
if (resultToPlainArray) deepLogs.forEach(log => logger.setLog(log));
else logger.setLogs(deepLogs);
}
}
}
});
return logger.getLogs();
};
export const paintLogs = (log, i, arr) => {
if (Array.isArray(log)) {
// eslint-disable-next-line
console.groupCollapsed(`${arr.length} changes`);
log.forEach(paintLogs);
} else {
// eslint-disable-next-line
console.groupCollapsed(
`${log.description.replace('key', `"${log.key}" key`)} in ${log.location || '.'}`,
);
// eslint-disable-next-line
console.log('previosObject', log.previosObject);
// eslint-disable-next-line
console.log('newObject', log.newObject);
// eslint-disable-next-line
if (log.previosObjectSnapshot) console.log('previosObjectSnapshot', log.previosObjectSnapshot);
// eslint-disable-next-line
if (log.newObjectSnapshot) console.log('newObjectSnapshot', log.newObjectSnapshot);
}
// eslint-disable-next-line
console.groupEnd();
};
export const logChangedValues = (handler = () => {}) =>
function(nextProps) {
const changedLog = getChangedValues({
previosObject: this.props,
newObject: nextProps,
addSnapshot: true,
});
if (changedLog.length) {
const { name } = this.constructor;
// eslint-disable-next-line
console.groupCollapsed(`${name}: ${changedLog.length} changes`);
changedLog.forEach(paintLogs);
// eslint-disable-next-line
console.groupEnd();
}
handler(nextProps);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment