Profectus-Demo/src/util/proxies.ts

60 lines
1.9 KiB
TypeScript
Raw Normal View History

2022-01-14 04:25:47 +00:00
import { isRef } from "vue";
import Decimal from "./bignum";
import { isFunction, isPlainObject } from "./common";
2022-01-14 04:25:47 +00:00
export const ProxyState = Symbol("ProxyState");
export const ProxyPath = Symbol("ProxyPath");
export type Proxied<T> = NonNullable<T> extends Record<PropertyKey, unknown>
? {
[K in keyof T]: Proxied<T[K]>;
}
: T;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type ProxiedWithState<T> = NonNullable<T> extends Record<PropertyKey, any>
? NonNullable<T> extends Decimal
? T
: {
[K in keyof T]: ProxiedWithState<T[K]>;
} & {
[ProxyState]: T;
[ProxyPath]: string[];
}
: T;
export function createProxy<T extends Record<string, unknown>>(object: T): T {
if (object.isProxy) {
console.warn(
"Creating a proxy out of a proxy! This may cause unintentional function calls and stack overflows."
);
}
2022-01-25 04:25:34 +00:00
//return new Proxy(object, layerHandler) as T;
return object;
}
2022-01-14 04:25:47 +00:00
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const layerHandler: ProxyHandler<Record<PropertyKey, any>> = {
get(target, key, receiver: typeof Proxy) {
if (key === "isProxy") {
return true;
}
2022-01-14 04:25:47 +00:00
if (
2022-01-25 04:25:34 +00:00
target[key] == null ||
2022-01-14 04:25:47 +00:00
isRef(target[key]) ||
target[key].isProxy ||
target[key] instanceof Decimal ||
2022-01-14 04:25:47 +00:00
typeof key === "symbol" ||
typeof target[key].render === "function"
) {
return target[key];
} else if (isPlainObject(target[key]) || Array.isArray(target[key])) {
target[key] = new Proxy(target[key], layerHandler);
return target[key];
} else if (isFunction(target[key])) {
return target[key].bind(receiver);
}
return target[key];
}
};