Skip to content

Instantly share code, notes, and snippets.

@janpauldahlke
Created March 26, 2019 14:14
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 janpauldahlke/1996cc8357deefcea4fd61bbfdd5c94c to your computer and use it in GitHub Desktop.
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
//-----------------
//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