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));
}
} else {
result = args.shift();
const findResult = args.shift();
if (result != null) {
if (result.$$vencordCallbackCalled != null && !result.$$vencordCallbackCalled()) {
result = null;
if (findResult != null) {
if (findResult.$$vencordCallbackCalled != null && findResult.$$vencordCallbackCalled()) {
result = findResult;
}
if (result[Vencord.Util.proxyInnerGet] != null) {
result = result[Vencord.Util.proxyInnerValue];
if (findResult[Vencord.Util.proxyInnerGet] != null) {
result = findResult[Vencord.Util.proxyInnerValue];
}
if (result.$$vencordInner != null) {
result = result.$$vencordInner();
if (findResult.$$vencordInner != null) {
result = findResult.$$vencordInner();
}
}
}

View file

@ -4,6 +4,16 @@
* 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 {
let tries = 0;
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.
* 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
* @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;
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.");
}
}) as T;
});
}

View file

@ -4,6 +4,13 @@
* 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 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
* @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.",
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
): [proxy: T, setInnerValue: (innerValue: T) => void] {
): [proxy: ProxyInner<T>, setInnerValue: (innerValue: T) => void] {
let isSameTick = true;
if (!isChild) setTimeout(() => isSameTick = false, 0);
@ -97,5 +104,5 @@ export function proxyInner<T = any>(
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>
: 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 { Logger } from "@utils/Logger";
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 { 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
* @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")
throw new Error("Invalid filter. Expected a function got " + typeof filter);
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]]);
}
if (proxy[proxyInnerValue] != null) return proxy[proxyInnerValue] as T;
if (proxy[proxyInnerValue] != null) return proxy[proxyInnerValue] as ProxyInner<T>;
return proxy;
}
@ -228,7 +229,7 @@ export function findComponent<T extends object = any>(filter: FilterFn, parse: (
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
*/
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 });
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
*/
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 });
if (IS_DEV) {
@ -348,7 +349,7 @@ export function findByCode<T = any>(...code: string[]) {
*
* @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 });
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");
}
return cacheFind(filterFns[0]);
return [cacheFind(filterFns[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
* @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]]);
return proxyLazy<T>(factory, attempts);