Created
March 26, 2019 14:14
-
-
Save janpauldahlke/1996cc8357deefcea4fd61bbfdd5c94c to your computer and use it in GitHub Desktop.
a brief collection of my snippets, i should look here BEFORE googling around
This file contains 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
//----------------- | |
//random a hex color | |
//----------------- | |
const randomColor = () => { | |
return '#'+Math.floor(Math.random()*16777215).toString(16); | |
}; | |
//----------------- | |
//observes a change in an object via proxy | |
//----------------- | |
// this is the source of https://www.npmjs.com/package/on-change | |
// give him credits! | |
const isPrimitive = value => value === null || (typeof value !== 'object' && typeof value !== 'function'); | |
const proxyTarget = Symbol('ProxyTarget'); | |
const onChange = (object, onChange) => { | |
let inApply = false; | |
let changed = false; | |
const propCache = new WeakMap(); | |
const handleChange = () => { | |
if (!inApply) { | |
onChange(); | |
} else if (!changed) { | |
changed = true; | |
} | |
}; | |
const getOwnPropertyDescriptor = (target, property) => { | |
if (!propCache.has(target)) { | |
propCache.set(target, new Map()); | |
} | |
const props = propCache.get(target); | |
if (props.has(property)) { | |
return props.get(property); | |
} | |
const prop = Reflect.getOwnPropertyDescriptor(target, property); | |
props.set(property, prop); | |
return prop; | |
}; | |
const invalidateCachedDescriptor = (target, property) => { | |
if (!propCache.has(target)) { | |
return; | |
} | |
const props = propCache.get(target); | |
props.delete(property); | |
}; | |
const handler = { | |
get(target, property, receiver) { | |
if (property === proxyTarget) { | |
return target; | |
} | |
const value = Reflect.get(target, property, receiver); | |
if (isPrimitive(value) || property === 'constructor') { | |
return value; | |
} | |
// Preserve invariants | |
const descriptor = getOwnPropertyDescriptor(target, property); | |
if (descriptor && !descriptor.configurable) { | |
if (descriptor.set && !descriptor.get) { | |
return undefined; | |
} | |
if (descriptor.writable === false) { | |
return value; | |
} | |
} | |
return new Proxy(value, handler); | |
}, | |
set(target, property, value, receiver) { | |
if (value && value[proxyTarget] !== undefined) { | |
value = value[proxyTarget]; | |
} | |
const previous = Reflect.get(target, property, value, receiver); | |
const result = Reflect.set(target, property, value); | |
if (previous !== value) { | |
handleChange(); | |
} | |
return result; | |
}, | |
defineProperty(target, property, descriptor) { | |
const result = Reflect.defineProperty(target, property, descriptor); | |
invalidateCachedDescriptor(target, property); | |
handleChange(); | |
return result; | |
}, | |
deleteProperty(target, property) { | |
const result = Reflect.deleteProperty(target, property); | |
invalidateCachedDescriptor(target, property); | |
handleChange(); | |
return result; | |
}, | |
apply(target, thisArg, argumentsList) { | |
if (!inApply) { | |
inApply = true; | |
const result = Reflect.apply(target, thisArg, argumentsList); | |
if (changed) { | |
onChange(); | |
} | |
inApply = false; | |
changed = false; | |
return result; | |
} | |
return Reflect.apply(target, thisArg, argumentsList); | |
} | |
}; | |
return new Proxy(object, handler); | |
}; | |
//consume it like this | |
const watchObject = onChange(originalObject, function () { // your stuff here }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment