Merge branch 'modules-proxy-patches' into immediate-finds-modules-proxy

This commit is contained in:
Nuckyz 2024-06-21 04:58:43 -03:00
commit cd79150a84
No known key found for this signature in database
GPG key ID: 440BF8296E1C4AD9
4 changed files with 39 additions and 36 deletions

View file

@ -86,6 +86,7 @@ function makeShortcuts() {
wpex: extract,
wpexs: (code: string) => extract(Webpack.cacheFindModuleId(code)!),
loadLazyChunks: IS_DEV ? loadLazyChunks : () => { throw new Error("loadLazyChunks is dev only."); },
filters,
find,
findAll: cacheFindAll,
findByProps,

View file

@ -283,7 +283,7 @@ function wrapAndPatchFactory(id: PropertyKey, originalFactory: AnyModuleFactory)
// There are (at the time of writing) 11 modules exporting the window
// Make these non enumerable to improve webpack search performance
if (require.c) {
if (typeof require === "function" && require.c != null) {
let foundWindow = false;
if (exports === window) {
@ -308,13 +308,13 @@ function wrapAndPatchFactory(id: PropertyKey, originalFactory: AnyModuleFactory)
writable: true
});
return;
return factoryReturn;
}
}
for (const callback of moduleListeners) {
try {
callback(exports, { id, factory: originalMod });
callback(exports, { id, factory: wrappedFactory.$$vencordOriginal! });
} catch (err) {
logger.error("Error in Webpack module listener:\n", err, callback);
}
@ -322,15 +322,15 @@ function wrapAndPatchFactory(id: PropertyKey, originalFactory: AnyModuleFactory)
for (const [filter, callback] of waitForSubscriptions) {
try {
if (filter.$$vencordIsFactoryFilter && filter(originalMod)) {
if (filter.$$vencordIsFactoryFilter && filter(wrappedFactory.$$vencordOriginal!)) {
waitForSubscriptions.delete(filter);
callback(exports, { id, exportKey: null, factory: originalMod });
callback(exports, { id, exportKey: null, factory: wrappedFactory.$$vencordOriginal! });
continue;
}
if (filter(exports)) {
waitForSubscriptions.delete(filter);
callback(exports, { id, exportKey: null, factory: originalMod });
callback(exports, { id, exportKey: null, factory: wrappedFactory.$$vencordOriginal! });
continue;
}
@ -340,7 +340,7 @@ function wrapAndPatchFactory(id: PropertyKey, originalFactory: AnyModuleFactory)
if (exports.default != null && filter(exports.default)) {
waitForSubscriptions.delete(filter);
callback(exports.default, { id, exportKey: "default", factory: originalMod });
callback(exports.default, { id, exportKey: "default", factory: wrappedFactory.$$vencordOriginal! });
continue;
}
@ -349,7 +349,7 @@ function wrapAndPatchFactory(id: PropertyKey, originalFactory: AnyModuleFactory)
if (exportValue != null && filter(exportValue)) {
waitForSubscriptions.delete(filter);
callback(exportValue, { id, exportKey, factory: originalMod });
callback(exportValue, { id, exportKey, factory: wrappedFactory.$$vencordOriginal! });
break;
}
}

View file

@ -13,7 +13,7 @@ import { AnyObject } from "@utils/types";
import { traceFunction } from "../debug/Tracer";
import { GenericStore } from "./common";
import { ModuleExports, ModuleFactory, WebpackRequire } from "./wreq";
import { AnyModuleFactory, ModuleExports, ModuleFactory, WebpackRequire } from "./wreq";
const logger = new Logger("Webpack");
@ -95,13 +95,13 @@ export const filters = {
export type ModListenerInfo = {
id: PropertyKey;
factory: ModuleFactory;
factory: AnyModuleFactory;
};
export type ModCallbackInfo = {
id: PropertyKey;
exportKey: PropertyKey | null;
factory: ModuleFactory;
factory: AnyModuleFactory;
};
export type ModListenerFn = (module: ModuleExports, info: ModListenerInfo) => void;
@ -109,7 +109,7 @@ export type ModCallbackFn = ((module: ModuleExports, info: ModCallbackInfo) => v
$$vencordCallbackCalled?: () => boolean;
};
export const factoryListeners = new Set<(factory: ModuleFactory) => void>();
export const factoryListeners = new Set<(factory: AnyModuleFactory) => void>();
export const moduleListeners = new Set<ModListenerFn>();
export const waitForSubscriptions = new Map<FilterFn, ModCallbackFn>();
export const beforeInitListeners = new Set<(wreq: WebpackRequire) => void>();
@ -395,10 +395,10 @@ export function findByFactoryCode<T = AnyObject>(...code: string[]) {
export function findModuleFactory(...code: string[]) {
const filter = filters.byFactoryCode(...code);
const [proxy, setInnerValue] = proxyInner<ModuleFactory>(`Webpack module factory find matched no module. Filter: ${printFilter(filter)}`, "Webpack find with proxy called on a primitive value. This can happen if you try to destructure a primitive in the top level definition of the find.");
const [proxy, setInnerValue] = proxyInner<AnyModuleFactory>(`Webpack module factory find matched no module. Filter: ${printFilter(filter)}`, "Webpack find with proxy called on a primitive value. This can happen if you try to destructure a primitive in the top level definition of the find.");
waitFor(filter, (_, { factory }) => setInnerValue(factory));
if (proxy[SYM_PROXY_INNER_VALUE] != null) return proxy[SYM_PROXY_INNER_VALUE] as ProxyInner<ModuleFactory>;
if (proxy[SYM_PROXY_INNER_VALUE] != null) return proxy[SYM_PROXY_INNER_VALUE] as ProxyInner<AnyModuleFactory>;
return proxy;
}
@ -418,8 +418,8 @@ export function findModuleFactory(...code: string[]) {
* @returns Unmangled exports as specified in mappers
*/
export function mapMangledModule<S extends PropertyKey>(code: string | string[], mappers: Record<S, FilterFn>) {
const result = find<Record<S, any>>(filters.byFactoryCode(...Array.isArray(code) ? code : [code]), exports => {
const mapping = {} as Record<S, any>;
const result = find<Record<S, ModuleExports>>(filters.byFactoryCode(...Array.isArray(code) ? code : [code]), exports => {
const mapping = {} as Record<S, ModuleExports>;
outer:
for (const newName in mappers) {
@ -459,7 +459,7 @@ type CacheFindResult = {
/** The key exporting the result. `null` if the find result was all the module exports, `undefined` if nothing was found */
exportKey?: PropertyKey | null;
/** The factory of the module exporting the result. `undefined` if nothing was found */
factory?: ModuleFactory;
factory?: AnyModuleFactory;
};
/**
@ -476,11 +476,11 @@ export const _cacheFind = traceFunction("cacheFind", function _cacheFind(filter:
if (!mod?.loaded || mod?.exports == null) continue;
if (filter.$$vencordIsFactoryFilter && filter(wreq.m[key])) {
return { result: exports, id: key, exportKey: null, factory: wreq.m[key] };
return { result: exports, id: key, exportKey: null, factory: wreq.m[key] as AnyModuleFactory };
}
if (filter(mod.exports)) {
return { result: exports, id: key, exportKey: null, factory: wreq.m[key] };
return { result: exports, id: key, exportKey: null, factory: wreq.m[key] as AnyModuleFactory };
}
if (typeof mod.exports !== "object") {
@ -488,14 +488,14 @@ export const _cacheFind = traceFunction("cacheFind", function _cacheFind(filter:
}
if (mod.exports.default != null && filter(mod.exports.default)) {
return { result: exports.default, id: key, exportKey: "default ", factory: wreq.m[key] };
return { result: exports.default, id: key, exportKey: "default ", factory: wreq.m[key] as AnyModuleFactory };
}
for (const exportKey in mod.exports) if (exportKey.length <= 3) {
const exportValue = mod.exports[exportKey];
if (exportValue != null && filter(exportValue)) {
return { result: exportValue, id: key, exportKey, factory: wreq.m[key] };
return { result: exportValue, id: key, exportKey, factory: wreq.m[key] as AnyModuleFactory };
}
}
}

32
src/webpack/wreq.d.ts vendored
View file

@ -58,21 +58,21 @@ export type WebpackRequire = ((moduleId: PropertyKey) => ModuleExports) & {
m: Record<PropertyKey, ModuleFactory>;
/** The module cache, where all modules which have been WebpackRequire'd are stored */
c: Record<PropertyKey, Module>;
/**
* Export star. Sets properties of "fromObject" to "toObject" as getters that return the value from "fromObject", like this:
* @example
* const fromObject = { a: 1 };
* Object.keys(fromObject).forEach(key => {
* if (key !== "default" && !Object.hasOwn(toObject, key)) {
* Object.defineProperty(toObject, key, {
* get: () => fromObject[key],
* enumerable: true
* });
* }
* });
* @returns fromObject
*/
es: (this: WebpackRequire, fromObject: Record<PropertyKey, any>, toObject: Record<PropertyKey, any>) => Record<PropertyKey, any>;
// /**
// * Export star. Sets properties of "fromObject" to "toObject" as getters that return the value from "fromObject", like this:
// * @example
// * const fromObject = { a: 1 };
// * Object.keys(fromObject).forEach(key => {
// * if (key !== "default" && !Object.hasOwn(toObject, key)) {
// * Object.defineProperty(toObject, key, {
// * get: () => fromObject[key],
// * enumerable: true
// * });
// * }
// * });
// * @returns fromObject
// */
// es: (this: WebpackRequire, fromObject: Record<PropertyKey, any>, toObject: Record<PropertyKey, any>) => Record<PropertyKey, any>;
/**
* Creates an async module. A module that exports something that is a Promise, or requires an export from an async module.
*
@ -179,6 +179,8 @@ export type WebpackRequire = ((moduleId: PropertyKey) => ModuleExports) & {
v: (this: WebpackRequire, exports: ModuleExports, wasmModuleId: any, wasmModuleHash: string, importsObj?: WebAssembly.Imports) => Promise<any>;
/** Bundle public path, where chunk files are stored. Used by other methods which load chunks to obtain the full asset url */
p: string;
/** The runtime id of the current runtime */
j: string;
/** Document baseURI or WebWorker location.href */
b: string;
};