Skip to content

Instantly share code, notes, and snippets.

@sebinsua
Created June 29, 2022 10:24
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 sebinsua/724fa9d4390bd2c738da13389e0508ed to your computer and use it in GitHub Desktop.
Save sebinsua/724fa9d4390bd2c738da13389e0508ed to your computer and use it in GitHub Desktop.
Debugging the properties in an object which are in use
import DeepProxy from 'proxy-deep';
export function withDeepPropertyAccessEmitter<T extends object>(
object: T,
emit: (info: {
path: (string | symbol)[];
target: T;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value: any;
}) => void
): T {
return new DeepProxy(object, {
get(target, handler, receiver) {
const propertyKey = handler.valueOf();
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const value = Reflect.get(target, propertyKey, receiver);
if (typeof value === 'object' && value !== null) {
return this.nest(value);
}
if (typeof value === 'function') {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return value;
}
if (propertyKey === 'then') {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return value;
}
if (propertyKey === 'length' && Array.isArray(target)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return value;
}
const fullPath = [...this.path, propertyKey].map((p) =>
typeof p === 'number' || (typeof p === 'string' && /^\d+$/.test(p)) ? '<number>' : p
);
emit({
path: fullPath,
target,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
value,
});
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return value;
},
});
}
export function withDeepPropertyAccessLogger<T extends object>(objectName: string, object: T, intervalMs = 5_000): T {
const paths = new Set<string>();
setInterval(() => {
if (paths.size > 0) {
console.table(Array.from(paths).map((path) => ({ [`${objectName} (read access)`]: path })));
}
paths.clear();
}, intervalMs);
return withDeepPropertyAccessEmitter(object, ({ path }) => paths.add([objectName, ...path].join('.')));
}
@sebinsua
Copy link
Author

sebinsua commented Aug 3, 2022

Note: this handles .then strangely because often code awaits on values. We should probably try to detect if this is a function and then treat it differently if so.

@sebinsua
Copy link
Author

Might be able to learn how to do improvements to this by reading proxy-compare's source code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment