Created
September 15, 2017 11:03
-
-
Save ptgamr/ea1b711ca7785288a512eefd00b56fb0 to your computer and use it in GitHub Desktop.
dirty.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const isValid = (v) => { | |
return v !== null && v !== undefined; | |
} | |
const isObject = (v) => { | |
return typeof(v) === 'object'; | |
} | |
const isCallable = (v) => { | |
return typeof(v) === 'function'; | |
} | |
const smartString = (v) => { | |
if( isValid(v) ) { | |
return `${v.constructor.name === 'Object' ? JSON.stringify(v) : v}`; | |
} | |
return `${v}`; | |
} | |
const defaultConfig = { | |
date: false, | |
name: 'dirty', | |
meta: 'meta', | |
setLogging: false, | |
getLogging: false | |
} | |
/// configuration | |
let config = Object.assign({}, defaultConfig); | |
const configure = (options = defaultConfig) => { | |
config = Object.assign({}, config, defaultConfig, options); | |
} | |
/// library | |
const __generate__ = (clz, key, val, path) => { | |
let _f = val; | |
return { | |
__proto__: null, | |
enumerable: true, | |
configurable: true, | |
get: function() { | |
if( config.getLogging ) { | |
console.log(`getting prop ${path}.${key}`) | |
} | |
return _f; | |
}, | |
set: function(v) { | |
let meta = clz[config.meta][`${path}.${key}`] | |
if (!meta) { | |
meta = { | |
originalVal: val | |
} | |
clz[config.meta][`${path}.${key}`] = meta | |
} | |
meta.currentVal = v | |
if( config.setLogging ) { | |
console.log(`setting prop ${path}.${key} with ${smartString(v)}`) | |
} | |
_f = v; | |
} | |
} | |
} | |
const observe_child = (obj = {}, root, path) => { | |
if( !root ) root = obj; | |
const keys = Object.keys(obj); | |
for( let key of keys ) { | |
if( `${key}` === config.name ) continue; | |
// copy current value | |
let seed = obj[key]; | |
// ignore functions | |
if( isCallable(seed) ) { | |
continue; | |
} | |
// delete existing value | |
delete obj[key]; | |
Object.defineProperty(obj, key, __generate__(root, key, seed, path ? path : '' )) | |
if( isValid(seed) && isObject(seed) ) { | |
observe_child(seed, root, path ? `${path}.${key}` : key); | |
} | |
} | |
} | |
const observe = (root) => { | |
root[config.name] = false; | |
root[config.meta] = {}; | |
observe_child(root); | |
return root; | |
} | |
const obj = { | |
name: 'anh', | |
address: { | |
line1: 'line1', | |
line2: 'line2', | |
}, | |
child: [ | |
{name: 'frank'}, | |
{name: 'toni'} | |
] | |
} | |
configure({ | |
name: '__dirty__', | |
meta: '__meta__', | |
setLogging: true | |
}); | |
observe(obj) | |
obj.address.line1 = 'anh'; | |
obj.address.line1 = 'em' | |
obj.child[0].name = 'other name'; | |
obj.child[0] = {name: 'kaka'}; | |
obj.child[0].name = 'other name'; | |
console.log(JSON.stringify(obj, null, 2)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment