Skip to content

Instantly share code, notes, and snippets.

@bradennapier
Created May 30, 2018 00:32
Show Gist options
  • Save bradennapier/e1f78f85b46d9acb4bdf704c645946d5 to your computer and use it in GitHub Desktop.
Save bradennapier/e1f78f85b46d9acb4bdf704c645946d5 to your computer and use it in GitHub Desktop.
import { PROXY_SYMBOL } from './src2/context';
const rootDescriptor = { changed: new Map(), path: [] };
const ProxyDescriptors = new WeakMap();
const proxyTraps = {
get(target, prop, receiver) {
if (prop === PROXY_SYMBOL) return target[prop];
if (typeof prop === 'symbol') return Reflect.get(target, prop, receiver);
const descriptor = ProxyDescriptors.get(target[PROXY_SYMBOL]);
const p = Reflect.get(target, prop, receiver);
if (typeof p === 'object') {
if (descriptor.childProxies.has(prop)) {
return descriptor.childProxies.get(prop);
}
const nextProxy = createProxyState(p, prop, descriptor);
descriptor.childProxies.set(prop, nextProxy);
return nextProxy;
}
return p;
},
set(target, prop, value) {
if (prop === PROXY_SYMBOL) return;
let next;
const current = Reflect.get(target, prop);
const descriptor = ProxyDescriptors.get(target[PROXY_SYMBOL]);
if (typeof value !== 'object' && value !== current) {
// Standard value changes, parent references must change
next = Reflect.set(target, prop, value);
descriptor.root.changed.set([...descriptor.path, prop].join('.'), value);
}
if (current !== value) {
// console.log('Value Changing! ', prop, value);
return Reflect.set(target, prop, value);
}
},
};
export function isProxy(value) {
return !!value && !!value[PROXY_SYMBOL];
}
function createStateDescriptor(symbol, key, parentDescriptor = rootDescriptor) {
const descriptor = {
path: (key && parentDescriptor.path.concat(key)) || parentDescriptor.path,
childProxies: new Map(),
};
descriptor.root = parentDescriptor.root || rootDescriptor;
ProxyDescriptors.set(symbol, descriptor);
}
function createProxyState(state, key, parentDescriptor) {
// if already handled, return state directly
if (state[PROXY_SYMBOL]) return state;
const symbol = {};
state[PROXY_SYMBOL] = symbol;
createStateDescriptor(symbol, key, parentDescriptor);
const proxy = new Proxy(state, proxyTraps);
return proxy;
}
export function deepProxy(state) {
return createProxyState(state);
}
const proxy = deepProxy({
one: {
two: 'three',
},
});
// const val2 = proxy.one.two;
proxy.one.three = 'hi';
console.log(proxy.one.three);
console.log(proxy);
console.log('next');
console.log(proxy.one);
const r = ProxyDescriptors.get(proxy[PROXY_SYMBOL]);
console.log(r);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment