From cb5f23d9b50afc8c89c4aaa6ddc315d7591760a3 Mon Sep 17 00:00:00 2001 From: V Date: Thu, 6 Jul 2023 00:53:43 +0200 Subject: [PATCH] ProxyLazy: Limit attempts --- src/utils/lazy.ts | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/utils/lazy.ts b/src/utils/lazy.ts index 1e1dd5f5..55aae5ea 100644 --- a/src/utils/lazy.ts +++ b/src/utils/lazy.ts @@ -27,8 +27,8 @@ const unconfigurable = ["arguments", "caller", "prototype"]; const handler: ProxyHandler = {}; -const GET_KEY = Symbol.for("vencord.lazy.get"); -const CACHED_KEY = Symbol.for("vencord.lazy.cached"); +const kGET = Symbol.for("vencord.lazy.get"); +const kCACHE = Symbol.for("vencord.lazy.cached"); for (const method of [ "apply", @@ -46,11 +46,11 @@ for (const method of [ "setPrototypeOf" ]) { handler[method] = - (target: any, ...args: any[]) => Reflect[method](target[GET_KEY](), ...args); + (target: any, ...args: any[]) => Reflect[method](target[kGET](), ...args); } handler.ownKeys = target => { - const v = target[GET_KEY](); + const v = target[kGET](); const keys = Reflect.ownKeys(v); for (const key of unconfigurable) { if (!keys.includes(key)) keys.push(key); @@ -62,7 +62,7 @@ handler.getOwnPropertyDescriptor = (target, p) => { if (typeof p === "string" && unconfigurable.includes(p)) return Reflect.getOwnPropertyDescriptor(target, p); - const descriptor = Reflect.getOwnPropertyDescriptor(target[GET_KEY](), p); + const descriptor = Reflect.getOwnPropertyDescriptor(target[kGET](), p); if (descriptor) Object.defineProperty(target, p, descriptor); return descriptor; @@ -72,15 +72,22 @@ handler.getOwnPropertyDescriptor = (target, p) => { * Wraps the result of {@see makeLazy} in a Proxy you can consume as if it wasn't lazy. * On first property access, the lazy is evaluated * @param factory lazy factory + * @param attempts how many times to try to evaluate the lazy before giving up * @returns Proxy * * Note that the example below exists already as an api, see {@link findByPropsLazy} * @example const mod = proxyLazy(() => findByProps("blah")); console.log(mod.blah); */ -export function proxyLazy(factory: () => T): T { - const proxyDummy: { (): void;[CACHED_KEY]?: T;[GET_KEY](): T; } = Object.assign(function () { }, { - [CACHED_KEY]: void 0, - [GET_KEY]: () => proxyDummy[CACHED_KEY] ??= factory(), +export function proxyLazy(factory: () => T, attempts = 5): T { + let tries = 0; + const proxyDummy = Object.assign(function () { }, { + [kCACHE]: void 0 as T | undefined, + [kGET]() { + if (!proxyDummy[kCACHE] && attempts > tries++) { + proxyDummy[kCACHE] = factory(); + } + return proxyDummy[kCACHE]; + } }); return new Proxy(proxyDummy, handler) as any;