This commit is contained in:
Nuckyz 2024-09-18 13:57:33 -03:00
parent 126f2df811
commit 15b7982228
No known key found for this signature in database
GPG key ID: 440BF8296E1C4AD9
6 changed files with 29 additions and 39 deletions

1
src/globals.d.ts vendored
View file

@ -20,6 +20,7 @@ import { LoDashStatic } from "lodash";
declare global {
type AnyRecord = Record<PropertyKey, any>;
type AnyComponentType<P extends AnyRecord> = React.ComponentType<P> & AnyRecord;
/**
* This exists only at build time, so references to it in patches should insert it

View file

@ -19,7 +19,7 @@ type DecorationGridItemComponent = ComponentType<PropsWithChildren<HTMLProps<HTM
export let DecorationGridItem: DecorationGridItemComponent = NoopComponent;
export const setDecorationGridItem = v => DecorationGridItem = v;
export const AvatarDecorationModalPreview = findComponentByCode<any>(".shopPreviewBanner", component => React.memo(component));
export const AvatarDecorationModalPreview = findComponentByCode(".shopPreviewBanner", component => React.memo(component));
type DecorationGridDecorationComponent = React.ComponentType<HTMLProps<HTMLDivElement> & {
avatarDecoration: AvatarDecoration;

View file

@ -17,7 +17,7 @@ export function makeLazy<T>(factory: () => T, attempts = 5, { isIndirect = false
let tries = 0;
let cache: T;
const getter = () => {
const getter: LazyFunction<T> = function () {
if (!cache && attempts > tries) {
tries++;
cache = factory();
@ -30,7 +30,6 @@ export function makeLazy<T>(factory: () => T, attempts = 5, { isIndirect = false
};
getter.$$vencordLazyFailed = () => tries === attempts;
return getter;
}
@ -69,17 +68,11 @@ const handler: ProxyHandler<any> = {
*
* @param factory Factory returning the result
* @param attempts How many times to try to evaluate the factory before giving up
* @param errMsg The error message to throw when the factory fails
* @param primitiveErrMsg The error message to throw when factory result is a primitive
* @param err The error message to throw when the factory fails
* @param primitiveErr The error message to throw when factory result is a primitive
* @returns Result of factory function
*/
export function proxyLazy<T = any>(
factory: () => T,
attempts = 5,
errMsg: string | (() => string) = `proxyLazy factory failed:\n${factory}`,
primitiveErrMsg = "proxyLazy called on a primitive value.",
isChild = false
): T {
export function proxyLazy<T = any>(factory: () => T, attempts = 5, err: string | (() => string) = `proxyLazy factory failed:\n${factory}`, primitiveErr = "proxyLazy called on a primitive value.", isChild = false): T {
const get = makeLazy(factory, attempts, { isIndirect: true });
let isSameTick = true;
@ -93,7 +86,7 @@ export function proxyLazy<T = any>(
}
if (!proxyDummy[SYM_LAZY_CACHED]) {
throw new Error(typeof errMsg === "string" ? errMsg : errMsg());
throw new Error(typeof err === "string" ? err : err());
} else {
if (typeof proxyDummy[SYM_LAZY_CACHED] === "function") {
proxy.toString = proxyDummy[SYM_LAZY_CACHED].toString.bind(proxyDummy[SYM_LAZY_CACHED]);
@ -129,8 +122,8 @@ export function proxyLazy<T = any>(
return Reflect.get(lazyTarget, p, lazyTarget);
},
attempts,
errMsg,
primitiveErrMsg,
err,
primitiveErr,
true
);
}
@ -140,7 +133,7 @@ export function proxyLazy<T = any>(
return Reflect.get(lazyTarget, p, lazyTarget);
}
throw new Error(primitiveErrMsg);
throw new Error(primitiveErr);
}
});

View file

@ -9,7 +9,7 @@ import { makeLazy } from "./lazy";
export const SYM_LAZY_COMPONENT_INNER = Symbol.for("vencord.lazyComponent.inner");
export type LazyComponentType<P extends AnyRecord> = React.FunctionComponent<P> & AnyRecord & {
[SYM_LAZY_COMPONENT_INNER]: () => LazyComponentType<P> | null;
[SYM_LAZY_COMPONENT_INNER]: () => AnyComponentType<P> | null;
};
/**
@ -19,10 +19,10 @@ export type LazyComponentType<P extends AnyRecord> = React.FunctionComponent<P>
* @param attempts How many times to try to get the component before giving up
* @returns Result of factory function
*/
export function LazyComponent<P extends AnyRecord>(factory: () => any, attempts = 5, err: string | (() => string) = `LazyComponent factory failed:\n${factory}`): LazyComponentType<P> {
export function LazyComponent<P extends AnyRecord>(factory: () => AnyComponentType<P>, attempts = 5, err: string | (() => string) = `LazyComponent factory failed:\n${factory}`): LazyComponentType<P> {
const get = makeLazy(factory, attempts, { isIndirect: true });
let InnerComponent = null as LazyComponentType<P> | null;
let InnerComponent = null as AnyComponentType<P> | null;
let lazyFailedLogged = false;
const LazyComponent: LazyComponentType<P> = function (props) {

View file

@ -42,22 +42,18 @@ const handler: ProxyHandler<any> = {
* IMPORTANT:
* Destructuring at top level is not supported for proxyInner.
*
* @param errMsg The error message to throw when the inner value is not set
* @param primitiveErrMsg The error message to throw when the inner value is a primitive
* @param err The error message to throw when the inner value is not set
* @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>(
errMsg: string | (() => string) = "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] {
export function proxyInner<T = any>(err: string | (() => string) = "Proxy inner value is undefined, setInnerValue was never called.", primitiveErr = "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] {
let isSameTick = true;
if (!isChild) setTimeout(() => isSameTick = false, 0);
const proxyDummy = Object.assign(function () { }, {
[SYM_PROXY_INNER_GET]: function () {
if (proxyDummy[SYM_PROXY_INNER_VALUE] == null) {
throw new Error(typeof errMsg === "string" ? errMsg : errMsg());
throw new Error(typeof err === "string" ? err : err());
}
return proxyDummy[SYM_PROXY_INNER_VALUE];
@ -85,7 +81,7 @@ export function proxyInner<T = any>(
"\nConsider not destructuring, using findProp or if you really need to destructure, using mapMangledModule instead."
);
const [recursiveProxy, recursiveSetInnerValue] = proxyInner(errMsg, primitiveErrMsg, true);
const [recursiveProxy, recursiveSetInnerValue] = proxyInner(err, primitiveErr, true);
recursiveSetInnerValues.push((innerValue: T) => {
// Set the inner value of the destructured value as the prop value p of the parent
@ -100,7 +96,7 @@ export function proxyInner<T = any>(
return Reflect.get(innerTarget, p, innerTarget);
}
throw new Error(primitiveErrMsg);
throw new Error(primitiveErr);
}
});

View file

@ -171,8 +171,8 @@ function printFilter(filter: FilterFn) {
return String(filter);
}
function wrapWebpackComponent<P extends AnyRecord>(err: string | (() => string)): [WrapperComponent: LazyComponentType<P>, setInnerComponent: (rawComponent: any, parsedComponent: LazyComponentType<P>) => void] {
let InnerComponent = null as LazyComponentType<P> | null;
function wrapWebpackComponent<P extends AnyRecord>(err: string | (() => string)): [WrapperComponent: LazyComponentType<P>, setInnerComponent: (rawComponent: any, parsedComponent: AnyComponentType<P>) => void] {
let InnerComponent = null as AnyComponentType<P> | null;
let findFailedLogged = false;
const WrapperComponent: LazyComponentType<P> = function (props) {
@ -186,7 +186,7 @@ function wrapWebpackComponent<P extends AnyRecord>(err: string | (() => string))
WrapperComponent[SYM_LAZY_COMPONENT_INNER] = () => InnerComponent;
function setInnerComponent(RawComponent: any, ParsedComponent: LazyComponentType<P>) {
function setInnerComponent(RawComponent: any, ParsedComponent: AnyComponentType<P>) {
InnerComponent = ParsedComponent;
Object.assign(WrapperComponent, RawComponent);
}
@ -281,7 +281,7 @@ export function find<T = any>(filter: FilterFn, parse: (module: ModuleExports) =
* @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component
* @returns The component if found, or a noop component
*/
export function findComponent<P extends AnyRecord>(filter: FilterFn, parse: (component: ModuleExports) => LazyComponentType<P> = m => m, { isIndirect = false }: { isIndirect?: boolean; } = {}) {
export function findComponent<P extends AnyRecord>(filter: FilterFn, parse: (component: ModuleExports) => AnyComponentType<P> = m => m, { isIndirect = false }: { isIndirect?: boolean; } = {}) {
if (typeof filter !== "function") {
throw new Error("Invalid filter. Expected a function got " + typeof filter);
}
@ -311,8 +311,8 @@ export function findComponent<P extends AnyRecord>(filter: FilterFn, parse: (com
* @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component
* @returns The component if found, or a noop component
*/
export function findExportedComponent<P extends AnyRecord>(...props: PropsFilter | [...PropsFilter, (component: ModuleExports) => LazyComponentType<P>]) {
const parse = (typeof props.at(-1) === "function" ? props.pop() : m => m) as (component: ModuleExports) => LazyComponentType<P>;
export function findExportedComponent<P extends AnyRecord>(...props: PropsFilter | [...PropsFilter, (component: ModuleExports) => AnyComponentType<P>]) {
const parse = (typeof props.at(-1) === "function" ? props.pop() : m => m) as (component: ModuleExports) => AnyComponentType<P>;
const newProps = props as PropsFilter;
const filter = filters.byProps(...newProps);
@ -339,8 +339,8 @@ export function findExportedComponent<P extends AnyRecord>(...props: PropsFilter
* @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component
* @returns The component if found, or a noop component
*/
export function findComponentByCode<P extends AnyRecord>(...code: CodeFilter | [...CodeFilter, (component: ModuleExports) => LazyComponentType<P>]) {
const parse = (typeof code.at(-1) === "function" ? code.pop() : m => m) as (component: ModuleExports) => LazyComponentType<P>;
export function findComponentByCode<P extends AnyRecord>(...code: CodeFilter | [...CodeFilter, (component: ModuleExports) => AnyComponentType<P>]) {
const parse = (typeof code.at(-1) === "function" ? code.pop() : m => m) as (component: ModuleExports) => AnyComponentType<P>;
const newCode = code as CodeFilter;
const ComponentResult = findComponent<P>(filters.componentByCode(...newCode), parse, { isIndirect: true });
@ -362,8 +362,8 @@ export function findComponentByCode<P extends AnyRecord>(...code: CodeFilter | [
* @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component
* @returns The component if found, or a noop component
*/
export function findComponentByFields<P extends AnyRecord>(...fields: PropsFilter | [...PropsFilter, (component: ModuleExports) => LazyComponentType<P>]) {
const parse = (typeof fields.at(-1) === "function" ? fields.pop() : m => m) as (component: ModuleExports) => LazyComponentType<P>;
export function findComponentByFields<P extends AnyRecord>(...fields: PropsFilter | [...PropsFilter, (component: ModuleExports) => AnyComponentType<P>]) {
const parse = (typeof fields.at(-1) === "function" ? fields.pop() : m => m) as (component: ModuleExports) => AnyComponentType<P>;
const newFields = fields as PropsFilter;
const ComponentResult = findComponent<P>(filters.componentByFields(...newFields), parse, { isIndirect: true });