Clarify more what the find methods return

This commit is contained in:
Nuckyz 2024-05-11 01:11:57 -03:00
parent e15868d499
commit b043d8abb7
No known key found for this signature in database
GPG key ID: 440BF8296E1C4AD9
5 changed files with 42 additions and 25 deletions

View file

@ -489,19 +489,19 @@ async function runtime(token: string) {
result = module.toString().match(Vencord.Util.canonicalizeMatch(matcher)); result = module.toString().match(Vencord.Util.canonicalizeMatch(matcher));
} }
} else { } else {
result = args.shift(); const findResult = args.shift();
if (result != null) { if (findResult != null) {
if (result.$$vencordCallbackCalled != null && !result.$$vencordCallbackCalled()) { if (findResult.$$vencordCallbackCalled != null && findResult.$$vencordCallbackCalled()) {
result = null; result = findResult;
} }
if (result[Vencord.Util.proxyInnerGet] != null) { if (findResult[Vencord.Util.proxyInnerGet] != null) {
result = result[Vencord.Util.proxyInnerValue]; result = findResult[Vencord.Util.proxyInnerValue];
} }
if (result.$$vencordInner != null) { if (findResult.$$vencordInner != null) {
result = result.$$vencordInner(); result = findResult.$$vencordInner();
} }
} }
} }

View file

@ -4,6 +4,16 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
import { AnyObject } from "./types";
export type ProxyLazy<T = AnyObject> = T & {
[proxyLazyGet]: () => T;
[proxyLazyCache]: T | undefined;
};
export const proxyLazyGet = Symbol.for("vencord.lazy.get");
export const proxyLazyCache = Symbol.for("vencord.lazy.cached");
export function makeLazy<T>(factory: () => T, attempts = 5, { isIndirect = false }: { isIndirect?: boolean; } = {}): () => T { export function makeLazy<T>(factory: () => T, attempts = 5, { isIndirect = false }: { isIndirect?: boolean; } = {}): () => T {
let tries = 0; let tries = 0;
let cache: T; let cache: T;
@ -49,9 +59,6 @@ const handler: ProxyHandler<any> = {
} }
}; };
export const proxyLazyGet = Symbol.for("vencord.lazy.get");
export const proxyLazyCache = Symbol.for("vencord.lazy.cached");
/** /**
* Wraps the result of factory in a Proxy you can consume as if it wasn't lazy. * Wraps the result of factory in a Proxy you can consume as if it wasn't lazy.
* On first property access, the factory is evaluated * On first property access, the factory is evaluated
@ -59,7 +66,7 @@ export const proxyLazyCache = Symbol.for("vencord.lazy.cached");
* @param attempts How many times to try to evaluate the factory before giving up * @param attempts How many times to try to evaluate the factory before giving up
* @returns Result of factory function * @returns Result of factory function
*/ */
export function proxyLazy<T = any>(factory: () => T, attempts = 5, isChild = false): T { export function proxyLazy<T = AnyObject>(factory: () => T, attempts = 5, isChild = false): ProxyLazy<T> {
const get = makeLazy(factory, attempts, { isIndirect: true }) as any; const get = makeLazy(factory, attempts, { isIndirect: true }) as any;
let isSameTick = true; let isSameTick = true;
@ -107,5 +114,5 @@ export function proxyLazy<T = any>(factory: () => T, attempts = 5, isChild = fal
throw new Error("proxyLazy called on a primitive value. This can happen if you try to destructure a primitive at the same tick as the proxy was created."); throw new Error("proxyLazy called on a primitive value. This can happen if you try to destructure a primitive at the same tick as the proxy was created.");
} }
}) as T; });
} }

View file

@ -4,6 +4,13 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
import { AnyObject } from "./types";
export type ProxyInner<T = AnyObject> = T & {
[proxyInnerGet]?: () => T;
[proxyInnerValue]?: T | undefined;
};
export const proxyInnerGet = Symbol.for("vencord.proxyInner.get"); export const proxyInnerGet = Symbol.for("vencord.proxyInner.get");
export const proxyInnerValue = Symbol.for("vencord.proxyInner.innerValue"); export const proxyInnerValue = Symbol.for("vencord.proxyInner.innerValue");
@ -39,11 +46,11 @@ const handler: ProxyHandler<any> = {
* @param primitiveErr The error message to throw when the inner value is a primitive * @param primitiveErr The error message to throw when the inner value is a primitive
* @returns A proxy which will act like the inner value when accessed * @returns A proxy which will act like the inner value when accessed
*/ */
export function proxyInner<T = any>( export function proxyInner<T = AnyObject>(
errMsg = "Proxy inner value is undefined, setInnerValue was never called.", errMsg = "Proxy inner value is undefined, setInnerValue was never called.",
primitiveErrMsg = "proxyInner called on a primitive value. This can happen if you try to destructure a primitive at the same tick as the proxy was created.", primitiveErrMsg = "proxyInner called on a primitive value. This can happen if you try to destructure a primitive at the same tick as the proxy was created.",
isChild = false isChild = false
): [proxy: T, setInnerValue: (innerValue: T) => void] { ): [proxy: ProxyInner<T>, setInnerValue: (innerValue: T) => void] {
let isSameTick = true; let isSameTick = true;
if (!isChild) setTimeout(() => isSameTick = false, 0); if (!isChild) setTimeout(() => isSameTick = false, 0);
@ -97,5 +104,5 @@ export function proxyInner<T = any>(
throw new Error(primitiveErrMsg); throw new Error(primitiveErrMsg);
} }
}) as T, setInnerValue]; }), setInnerValue];
} }

View file

@ -335,3 +335,5 @@ export type PluginNative<PluginExports extends Record<string, (event: Electron.I
? (...args: Args) => Return extends Promise<any> ? Return : Promise<Return> ? (...args: Args) => Return extends Promise<any> ? Return : Promise<Return>
: never; : never;
}; };
export type AnyObject = Record<PropertyKey, any> & ((...args: any[]) => any);

View file

@ -8,7 +8,8 @@ import { proxyLazy } from "@utils/lazy";
import { LazyComponent } from "@utils/lazyReact"; import { LazyComponent } from "@utils/lazyReact";
import { Logger } from "@utils/Logger"; import { Logger } from "@utils/Logger";
import { canonicalizeMatch } from "@utils/patches"; import { canonicalizeMatch } from "@utils/patches";
import { proxyInner, proxyInnerValue } from "@utils/proxyInner"; import { ProxyInner, proxyInner, proxyInnerValue } from "@utils/proxyInner";
import { AnyObject } from "@utils/types";
import type { WebpackInstance } from "discord-types/other"; import type { WebpackInstance } from "discord-types/other";
import { traceFunction } from "../debug/Tracer"; import { traceFunction } from "../debug/Tracer";
@ -162,7 +163,7 @@ export function waitFor(filter: FilterFn, callback: ModCallbackFn, { isIndirect
* @param callback A function that takes the found module as its first argument and returns something to use as the proxy inner value. Useful if you want to use a value from the module, instead of all of it. Defaults to the module itself * @param callback A function that takes the found module as its first argument and returns something to use as the proxy inner value. Useful if you want to use a value from the module, instead of all of it. Defaults to the module itself
* @returns A proxy that has the callback return value as its true value, or the callback return value if the callback was called when the function was called * @returns A proxy that has the callback return value as its true value, or the callback return value if the callback was called when the function was called
*/ */
export function find<T = any>(filter: FilterFn, callback: (mod: any) => any = m => m, { isIndirect = false }: { isIndirect?: boolean; } = {}) { export function find<T = AnyObject>(filter: FilterFn, callback: (mod: any) => any = m => m, { isIndirect = false }: { isIndirect?: boolean; } = {}) {
if (typeof filter !== "function") if (typeof filter !== "function")
throw new Error("Invalid filter. Expected a function got " + typeof filter); throw new Error("Invalid filter. Expected a function got " + typeof filter);
if (typeof callback !== "function") if (typeof callback !== "function")
@ -175,7 +176,7 @@ export function find<T = any>(filter: FilterFn, callback: (mod: any) => any = m
webpackSearchHistory.push(["find", [proxy, filter]]); webpackSearchHistory.push(["find", [proxy, filter]]);
} }
if (proxy[proxyInnerValue] != null) return proxy[proxyInnerValue] as T; if (proxy[proxyInnerValue] != null) return proxy[proxyInnerValue] as ProxyInner<T>;
return proxy; return proxy;
} }
@ -228,7 +229,7 @@ export function findComponent<T extends object = any>(filter: FilterFn, parse: (
if (InnerComponent !== null) return InnerComponent; if (InnerComponent !== null) return InnerComponent;
return WrapperComponent; return WrapperComponent as React.ComponentType<T>;
} }
/** /**
@ -318,7 +319,7 @@ export function findComponentByCode<T extends object = any>(...code: string[] |
* *
* @param props A list of props to search the exports for * @param props A list of props to search the exports for
*/ */
export function findByProps<T = any>(...props: string[]) { export function findByProps<T = AnyObject>(...props: string[]) {
const result = find<T>(filters.byProps(...props), m => m, { isIndirect: true }); const result = find<T>(filters.byProps(...props), m => m, { isIndirect: true });
if (IS_DEV) { if (IS_DEV) {
@ -333,7 +334,7 @@ export function findByProps<T = any>(...props: string[]) {
* *
* @param code A list of code to search each export for * @param code A list of code to search each export for
*/ */
export function findByCode<T = any>(...code: string[]) { export function findByCode<T = AnyObject>(...code: string[]) {
const result = find<T>(filters.byCode(...code), m => m, { isIndirect: true }); const result = find<T>(filters.byCode(...code), m => m, { isIndirect: true });
if (IS_DEV) { if (IS_DEV) {
@ -348,7 +349,7 @@ export function findByCode<T = any>(...code: string[]) {
* *
* @param name The store name * @param name The store name
*/ */
export function findStore<T = any>(name: string) { export function findStore<T = AnyObject>(name: string) {
const result = find<T>(filters.byStoreName(name), m => m, { isIndirect: true }); const result = find<T>(filters.byStoreName(name), m => m, { isIndirect: true });
if (IS_DEV) { if (IS_DEV) {
@ -425,7 +426,7 @@ export const cacheFindBulk = traceFunction("cacheFindBulk", function cacheFindBu
throw new Error("bulk called with only one filter. Use find"); throw new Error("bulk called with only one filter. Use find");
} }
return cacheFind(filterFns[0]); return [cacheFind(filterFns[0])];
} }
let found = 0; let found = 0;
@ -519,7 +520,7 @@ export function findModuleFactory(...code: string[]) {
* @param attempts How many times to try to evaluate the factory before giving up * @param attempts How many times to try to evaluate the factory before giving up
* @returns Result of factory function * @returns Result of factory function
*/ */
export function webpackDependantLazy<T = any>(factory: () => any, attempts?: number) { export function webpackDependantLazy<T = AnyObject>(factory: () => T, attempts?: number) {
if (IS_DEV) webpackSearchHistory.push(["webpackDependantLazy", [factory]]); if (IS_DEV) webpackSearchHistory.push(["webpackDependantLazy", [factory]]);
return proxyLazy<T>(factory, attempts); return proxyLazy<T>(factory, attempts);