Skip to content

Instantly share code, notes, and snippets.

@mizchi
Created February 24, 2022 10:54
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 mizchi/3929d0d95116ac2f752d08f037851bd9 to your computer and use it in GitHub Desktop.
Save mizchi/3929d0d95116ac2f752d08f037851bd9 to your computer and use it in GitHub Desktop.
function isObject(value: any): value is object {
return value !== null && typeof value === 'object';
}
export const DELETED = Symbol();
export function deepProxy(
original: any,
handler: (path: string[], value: any | typeof DELETED) => void,
selfPath: string[] = [],
): any {
return new Proxy(original, {
get: (target, prop) => {
if (Reflect.has(target, prop) && isObject(target[prop])) {
return deepProxy(target[prop], handler, [...selfPath, prop as string]);
}
return target[prop];
},
set(target, property, value, _receiver) {
if (isObject(value)) {
for (const k of Object.keys(value)) {
const v = (value as any)[k];
if (isObject(v)) {
// @ts-ignore
value[k] = deepProxy(v, handler, [...selfPath, property as string, k]);
}
}
value = deepProxy(value, handler, selfPath);
}
target[property] = value;
handler([...selfPath, property as string], value);
return true;
},
deleteProperty(target, property) {
if (Reflect.has(target, property)) {
const deleted = Reflect.deleteProperty(target, property);
if (deleted) {
handler([...selfPath, property as string], DELETED);
}
return deleted;
}
return false;
},
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment