diff --git a/scripts/generateReport.ts b/scripts/generateReport.ts index 41251c0d4..aed1b0e61 100644 --- a/scripts/generateReport.ts +++ b/scripts/generateReport.ts @@ -386,7 +386,7 @@ async function runtime(token: string) { await Promise.all( Array.from(validChunkGroups) .map(([chunkIds]) => - Promise.all(chunkIds.map(id => wreq.e(id).catch(() => { }))) + Promise.all(chunkIds.map(id => wreq.e(id))) ) ); @@ -440,10 +440,13 @@ async function runtime(token: string) { wreq = webpackRequire; Vencord.Webpack.factoryListeners.add(factory => { - let isResolved = false; - searchAndLoadLazyChunks(factory.toString()).then(() => isResolved = true); + // setImmediate to avoid blocking the factory patching execution while checking for lazy chunks + setTimeout(() => { + let isResolved = false; + searchAndLoadLazyChunks(String(factory)).then(() => isResolved = true); - chunksSearchPromises.push(() => isResolved); + chunksSearchPromises.push(() => isResolved); + }, 0); }); // setImmediate to only search the initial factories after Discord initialized the app @@ -451,7 +454,7 @@ async function runtime(token: string) { setTimeout(() => { for (const factoryId in wreq.m) { let isResolved = false; - searchAndLoadLazyChunks(wreq.m[factoryId].toString()).then(() => isResolved = true); + searchAndLoadLazyChunks(String(wreq.m[factoryId])).then(() => isResolved = true); chunksSearchPromises.push(() => isResolved); } @@ -470,7 +473,7 @@ async function runtime(token: string) { const allChunks = [] as string[]; // Matches "id" or id: - for (const currentMatch of wreq.u.toString().matchAll(/(?:"(\d+?)")|(?:(\d+?):)/g)) { + for (const currentMatch of String(wreq.u).matchAll(/(?:"(\d+?)")|(?:(\d+?):)/g)) { const id = currentMatch[1] ?? currentMatch[2]; if (id == null) continue; @@ -523,7 +526,7 @@ async function runtime(token: string) { const module = Vencord.Webpack.findModuleFactory(...code); if (module) { - result = module.toString().match(Vencord.Util.canonicalizeMatch(matcher)); + result = String(module).match(Vencord.Util.canonicalizeMatch(matcher)); } break; @@ -572,7 +575,7 @@ async function runtime(token: string) { parsedArgs === args && ["waitFor", "find", "findComponent", "webpackDependantLazy", "webpackDependantLazyComponent"].includes(searchType) ) { - let filter = parsedArgs[0].toString(); + let filter = String(parsedArgs[0]); if (filter.length > 150) { filter = filter.slice(0, 147) + "..."; } @@ -583,7 +586,7 @@ async function runtime(token: string) { if (parsedArgs[1] === Vencord.Webpack.DefaultExtractAndLoadChunksRegex) { regexStr = "DefaultExtractAndLoadChunksRegex"; } else { - regexStr = parsedArgs[1].toString(); + regexStr = String(parsedArgs[1]); } logMessage += `([${parsedArgs[0].map((arg: any) => `"${arg}"`).join(", ")}], ${regexStr})`; diff --git a/src/components/VencordSettings/PatchHelperTab.tsx b/src/components/VencordSettings/PatchHelperTab.tsx index e09a1dbf3..f9204669b 100644 --- a/src/components/VencordSettings/PatchHelperTab.tsx +++ b/src/components/VencordSettings/PatchHelperTab.tsx @@ -56,7 +56,7 @@ function ReplacementComponent({ module, match, replacement, setReplacementError const [compileResult, setCompileResult] = React.useState<[boolean, string]>(); const [patchedCode, matchResult, diff] = React.useMemo(() => { - const src: string = fact.toString().replaceAll("\n", ""); + const src: string = String(fact).replaceAll("\n", ""); try { new RegExp(match); diff --git a/src/components/VencordSettings/VencordTab.tsx b/src/components/VencordSettings/VencordTab.tsx index c9702b435..c0a66fdc7 100644 --- a/src/components/VencordSettings/VencordTab.tsx +++ b/src/components/VencordSettings/VencordTab.tsx @@ -66,11 +66,6 @@ function VencordSettings() { title: "Enable React Developer Tools", note: "Requires a full restart" }, - { - key: "eagerPatches", - title: "Apply Vencord patches before they are needed", - note: "Increases startup timing, but may make app usage more fluid. Note that the difference of having this on or off is minimal." - }, !IS_WEB && (!IS_DISCORD_DESKTOP || !isWindows ? { key: "frameless", title: "Disable the window frame", diff --git a/src/plugins/devCompanion.dev/index.tsx b/src/plugins/devCompanion.dev/index.tsx index 056a758ba..852f7abb6 100644 --- a/src/plugins/devCompanion.dev/index.tsx +++ b/src/plugins/devCompanion.dev/index.tsx @@ -160,7 +160,7 @@ function initWs(isManual = false) { return reply("Expected exactly one 'find' matches, found " + keys.length); const mod = candidates[keys[0]]; - let src = mod.toString().replaceAll("\n", ""); + let src = String(mod).replaceAll("\n", ""); if (src.startsWith("function(")) { src = "0," + src; diff --git a/src/webpack/patchWebpack.ts b/src/webpack/patchWebpack.ts index 855678b8b..d1cec1461 100644 --- a/src/webpack/patchWebpack.ts +++ b/src/webpack/patchWebpack.ts @@ -24,7 +24,7 @@ const modulesProxyHandler: ProxyHandler = { [propName, (...args: any[]) => Reflect[propName](...args)] )), get: (target, p) => { - const propValue = Reflect.get(target, p); + const propValue = Reflect.get(target, p, target); // If the property is not a number, we are not dealing with a module factory // $$vencordOriginal means the factory is already patched, $$vencordRequired means it has already been required @@ -36,7 +36,7 @@ const modulesProxyHandler: ProxyHandler = { // This patches factories if eagerPatches are disabled const patchedFactory = patchFactory(p, propValue); - Reflect.set(target, p, patchedFactory); + Reflect.set(target, p, patchedFactory, target); return patchedFactory; }, @@ -44,10 +44,10 @@ const modulesProxyHandler: ProxyHandler = { // $$vencordRequired means we are resetting the factory to its original after being required // If the property is not a number, we are not dealing with a module factory if (!Settings.eagerPatches || newValue?.$$vencordRequired === true || Number.isNaN(Number(p))) { - return Reflect.set(target, p, newValue); + return Reflect.set(target, p, newValue, target); } - const existingFactory = Reflect.get(target, p); + const existingFactory = Reflect.get(target, p, target); // Check if this factory is already patched // @ts-ignore @@ -59,7 +59,7 @@ const modulesProxyHandler: ProxyHandler = { // Modules are only patched once, so we need to set the patched factory on all the modules for (const proxiedModules of allProxiedModules) { - Reflect.set(proxiedModules, p, patchedFactory); + Reflect.set(proxiedModules, p, patchedFactory, proxiedModules); } return true; @@ -91,7 +91,7 @@ Object.defineProperty(Function.prototype, "O", { const originalOnChunksLoaded = onChunksLoaded; onChunksLoaded = function (result, chunkIds, callback, priority) { - if (callback != null && initCallbackRegex.test(callback.toString())) { + if (callback != null && initCallbackRegex.test(String(callback))) { Object.defineProperty(this, "O", { value: originalOnChunksLoaded, configurable: true, @@ -127,10 +127,17 @@ Object.defineProperty(Function.prototype, "O", { configurable: true, set(v: OnChunksLoaded["j"]) { - // @ts-ignore - delete onChunksLoaded.j; - onChunksLoaded.j = v; - originalOnChunksLoaded.j = v; + function setValue(target: any) { + Object.defineProperty(target, "j", { + value: v, + configurable: true, + enumerable: true, + writable: true + }); + } + + setValue(onChunksLoaded); + setValue(originalOnChunksLoaded); } }); } @@ -160,6 +167,8 @@ Object.defineProperty(Function.prototype, "m", { // The new object which will contain the factories const proxiedModules: WebpackRequire["m"] = {}; + // @ts-ignore + proxiedModules[Symbol.toStringTag] = "ProxiedModules"; for (const id in originalModules) { // If we have eagerPatches enabled we have to patch the pre-populated factories @@ -173,9 +182,10 @@ Object.defineProperty(Function.prototype, "m", { delete originalModules[id]; } - // @ts-ignore - originalModules.$$proxiedModules = proxiedModules; allProxiedModules.add(proxiedModules); + + // @ts-ignore + originalModules[Symbol.toStringTag] = "OriginalModules"; Object.setPrototypeOf(originalModules, new Proxy(proxiedModules, modulesProxyHandler)); } @@ -211,7 +221,7 @@ function patchFactory(id: PropertyKey, factory: ModuleFactory) { // cause issues. // // 0, prefix is to turn it into an expression: 0,function(){} would be invalid syntax without the 0, - let code: string = "0," + factory.toString().replaceAll("\n", ""); + let code: string = "0," + String(factory).replaceAll("\n", ""); for (let i = 0; i < patches.length; i++) { const patch = patches[i]; @@ -318,7 +328,7 @@ function patchFactory(id: PropertyKey, factory: ModuleFactory) { // @ts-ignore originalFactory.$$vencordRequired = true; for (const proxiedModules of allProxiedModules) { - proxiedModules[id] = originalFactory; + Reflect.set(proxiedModules, id, originalFactory, proxiedModules); } if (wreq == null && IS_DEV) { diff --git a/src/webpack/webpack.tsx b/src/webpack/webpack.tsx index fab14eaf6..4412e4fd1 100644 --- a/src/webpack/webpack.tsx +++ b/src/webpack/webpack.tsx @@ -480,7 +480,7 @@ export const cacheFindBulk = traceFunction("cacheFindBulk", function cacheFindBu export const findModuleId = traceFunction("findModuleId", function findModuleId(...code: string[]) { outer: for (const id in wreq.m) { - const str = wreq.m[id].toString(); + const str = String(wreq.m[id]); for (const c of code) { if (!str.includes(c)) continue outer; @@ -672,7 +672,7 @@ export async function extractAndLoadChunks(code: string[], matcher: RegExp = Def return; } - const match = module.toString().match(canonicalizeMatch(matcher)); + const match = String(module).match(canonicalizeMatch(matcher)); if (!match) { const err = new Error("extractAndLoadChunks: Couldn't find chunk loading in module factory code"); logger.warn(err, "Code:", code, "Matcher:", matcher); @@ -731,7 +731,7 @@ export function search(...filters: Array) { outer: for (const id in factories) { const factory = factories[id]; - const str: string = factory.toString(); + const str: string = String(factory); for (const filter of filters) { if (typeof filter === "string" && !str.includes(filter)) continue outer; if (filter instanceof RegExp && !filter.test(str)) continue outer; @@ -759,7 +759,7 @@ export function extract(id: PropertyKey) { // WARNING: This module was extracted to be more easily readable. // This module is NOT ACTUALLY USED! This means putting breakpoints will have NO EFFECT!! -0,${mod.toString()} +0,${String(mod)} //# sourceURL=ExtractedWebpackModule${String(id)} `; const extracted: ModuleFactory = (0, eval)(code);