Improve typings and other stuff
This commit is contained in:
parent
066ce07512
commit
53dd86fa6e
|
@ -8,6 +8,7 @@ import { Logger } from "@utils/Logger";
|
||||||
import { canonicalizeMatch } from "@utils/patches";
|
import { canonicalizeMatch } from "@utils/patches";
|
||||||
import * as Webpack from "@webpack";
|
import * as Webpack from "@webpack";
|
||||||
import { wreq } from "@webpack";
|
import { wreq } from "@webpack";
|
||||||
|
import { AnyModuleFactory, ModuleFactory } from "webpack";
|
||||||
|
|
||||||
const LazyChunkLoaderLogger = new Logger("LazyChunkLoader");
|
const LazyChunkLoaderLogger = new Logger("LazyChunkLoader");
|
||||||
|
|
||||||
|
@ -109,21 +110,22 @@ export async function loadLazyChunks() {
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Webpack.factoryListeners.add(factory => {
|
function factoryListener(factory: AnyModuleFactory | ModuleFactory) {
|
||||||
let isResolved = false;
|
let isResolved = false;
|
||||||
searchAndLoadLazyChunks(String(factory)).then(() => isResolved = true);
|
searchAndLoadLazyChunks(String(factory))
|
||||||
|
.then(() => isResolved = true)
|
||||||
chunksSearchPromises.push(() => isResolved);
|
.catch(() => isResolved = true);
|
||||||
});
|
|
||||||
|
|
||||||
for (const factoryId in wreq.m) {
|
|
||||||
let isResolved = false;
|
|
||||||
searchAndLoadLazyChunks(String(wreq.m[factoryId])).then(() => isResolved = true);
|
|
||||||
|
|
||||||
chunksSearchPromises.push(() => isResolved);
|
chunksSearchPromises.push(() => isResolved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Webpack.factoryListeners.add(factoryListener);
|
||||||
|
for (const factoryId in wreq.m) {
|
||||||
|
factoryListener(wreq.m[factoryId]);
|
||||||
|
}
|
||||||
|
|
||||||
await chunksSearchingDone;
|
await chunksSearchingDone;
|
||||||
|
Webpack.factoryListeners.delete(factoryListener);
|
||||||
|
|
||||||
// Require deferred entry points
|
// Require deferred entry points
|
||||||
for (const deferredRequire of deferredRequires) {
|
for (const deferredRequire of deferredRequires) {
|
||||||
|
|
|
@ -12,15 +12,7 @@ import { PatchReplacement } from "@utils/types";
|
||||||
|
|
||||||
import { traceFunction } from "../debug/Tracer";
|
import { traceFunction } from "../debug/Tracer";
|
||||||
import { patches } from "../plugins";
|
import { patches } from "../plugins";
|
||||||
import { _initWebpack, factoryListeners, ModuleFactory, moduleListeners, subscriptions, WebpackRequire, wreq } from ".";
|
import { _initWebpack, AnyModuleFactory, AnyWebpackRequire, factoryListeners, moduleListeners, PatchedModuleFactories, PatchedModuleFactory, subscriptions, WebpackRequire, wreq } from ".";
|
||||||
|
|
||||||
type AnyWebpackRequire = Partial<WebpackRequire> & Pick<WebpackRequire, "m">;
|
|
||||||
|
|
||||||
type PatchedModuleFactory = ModuleFactory & {
|
|
||||||
$$vencordOriginal?: ModuleFactory;
|
|
||||||
};
|
|
||||||
|
|
||||||
type PatchedModuleFactories = Record<PropertyKey, PatchedModuleFactory>;
|
|
||||||
|
|
||||||
const logger = new Logger("WebpackInterceptor", "#8caaee");
|
const logger = new Logger("WebpackInterceptor", "#8caaee");
|
||||||
|
|
||||||
|
@ -56,7 +48,7 @@ const define: Define = (target, p, attributes) => {
|
||||||
define(Function.prototype, "O", {
|
define(Function.prototype, "O", {
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
|
|
||||||
set(this: WebpackRequire, onChunksLoaded: WebpackRequire["O"]) {
|
set(this: AnyWebpackRequire, onChunksLoaded: AnyWebpackRequire["O"]) {
|
||||||
define(this, "O", { value: onChunksLoaded });
|
define(this, "O", { value: onChunksLoaded });
|
||||||
|
|
||||||
const { stack } = new Error();
|
const { stack } = new Error();
|
||||||
|
@ -104,7 +96,7 @@ define(Function.prototype, "O", {
|
||||||
const proxiedModuleFactories = new Proxy(this.m, moduleFactoriesHandler);
|
const proxiedModuleFactories = new Proxy(this.m, moduleFactoriesHandler);
|
||||||
/*
|
/*
|
||||||
If Discord ever decides to set module factories using the variable of the modules object directly, instead of wreq.m, switch the proxy to the prototype
|
If Discord ever decides to set module factories using the variable of the modules object directly, instead of wreq.m, switch the proxy to the prototype
|
||||||
Reflect.setPrototypeOf(moduleFactories, new Proxy(moduleFactories, moduleFactoriesHandler));
|
define(this, "m", { value: Reflect.setPrototypeOf(this.m, new Proxy(this.m, moduleFactoriesHandler)) });
|
||||||
*/
|
*/
|
||||||
|
|
||||||
define(this, "m", { value: proxiedModuleFactories });
|
define(this, "m", { value: proxiedModuleFactories });
|
||||||
|
@ -133,7 +125,7 @@ function defineModulesFactoryGetter(id: PropertyKey, factory: PatchedModuleFacto
|
||||||
|
|
||||||
return (factory = patchFactory(id, factory));
|
return (factory = patchFactory(id, factory));
|
||||||
},
|
},
|
||||||
set(v: ModuleFactory) {
|
set(v: AnyModuleFactory) {
|
||||||
if (factory.$$vencordOriginal != null) {
|
if (factory.$$vencordOriginal != null) {
|
||||||
factory.$$vencordOriginal = v;
|
factory.$$vencordOriginal = v;
|
||||||
} else {
|
} else {
|
||||||
|
@ -153,7 +145,7 @@ function defineModulesFactoryGetter(id: PropertyKey, factory: PatchedModuleFacto
|
||||||
* @param ignoreExistingInTarget Whether to ignore checking if the factory already exists in the moduleFactoriesTarget
|
* @param ignoreExistingInTarget Whether to ignore checking if the factory already exists in the moduleFactoriesTarget
|
||||||
* @returns Whether the original factory was updated, or false if it doesn't exist in any Webpack instance
|
* @returns Whether the original factory was updated, or false if it doesn't exist in any Webpack instance
|
||||||
*/
|
*/
|
||||||
function updateExistingFactory(moduleFactoriesTarget: AnyWebpackRequire["m"], id: PropertyKey, newFactory: ModuleFactory, ignoreExistingInTarget: boolean = false) {
|
function updateExistingFactory(moduleFactoriesTarget: AnyWebpackRequire["m"], id: PropertyKey, newFactory: AnyModuleFactory, ignoreExistingInTarget: boolean = false) {
|
||||||
let existingFactory: TypedPropertyDescriptor<PatchedModuleFactory> | undefined;
|
let existingFactory: TypedPropertyDescriptor<PatchedModuleFactory> | undefined;
|
||||||
for (const wreq of allWebpackInstances) {
|
for (const wreq of allWebpackInstances) {
|
||||||
if (ignoreExistingInTarget && wreq.m === moduleFactoriesTarget) continue;
|
if (ignoreExistingInTarget && wreq.m === moduleFactoriesTarget) continue;
|
||||||
|
@ -228,7 +220,7 @@ const moduleFactoriesHandler: ProxyHandler<PatchedModuleFactories> = {
|
||||||
* @param factory The original or patched module factory
|
* @param factory The original or patched module factory
|
||||||
* @returns The wrapper for the patched module factory
|
* @returns The wrapper for the patched module factory
|
||||||
*/
|
*/
|
||||||
function patchFactory(id: PropertyKey, factory: ModuleFactory) {
|
function patchFactory(id: PropertyKey, factory: AnyModuleFactory) {
|
||||||
const originalFactory = factory;
|
const originalFactory = factory;
|
||||||
|
|
||||||
for (const factoryListener of factoryListeners) {
|
for (const factoryListener of factoryListeners) {
|
||||||
|
@ -347,7 +339,7 @@ function patchFactory(id: PropertyKey, factory: ModuleFactory) {
|
||||||
|
|
||||||
// The patched factory wrapper, define it in an object to preserve the name after minification
|
// The patched factory wrapper, define it in an object to preserve the name after minification
|
||||||
const patchedFactory: PatchedModuleFactory = {
|
const patchedFactory: PatchedModuleFactory = {
|
||||||
PatchedFactory(...args: Parameters<ModuleFactory>) {
|
PatchedFactory(...args: Parameters<AnyModuleFactory>) {
|
||||||
// Restore the original factory in all the module factories objects,
|
// Restore the original factory in all the module factories objects,
|
||||||
// because we want to make sure the original factory is restored properly, no matter what is the Webpack instance
|
// because we want to make sure the original factory is restored properly, no matter what is the Webpack instance
|
||||||
for (const wreq of allWebpackInstances) {
|
for (const wreq of allWebpackInstances) {
|
||||||
|
@ -370,7 +362,7 @@ function patchFactory(id: PropertyKey, factory: ModuleFactory) {
|
||||||
`id: ${String(id)}` + interpolateIfDefined`, WebpackInstance origin: ${webpackInstanceFileName}` +
|
`id: ${String(id)}` + interpolateIfDefined`, WebpackInstance origin: ${webpackInstanceFileName}` +
|
||||||
")"
|
")"
|
||||||
);
|
);
|
||||||
_initWebpack(require);
|
_initWebpack(require as WebpackRequire);
|
||||||
} else if (IS_DEV) {
|
} else if (IS_DEV) {
|
||||||
logger.error("WebpackRequire was not initialized, running modules without patches instead.");
|
logger.error("WebpackRequire was not initialized, running modules without patches instead.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { Logger } from "@utils/Logger";
|
||||||
import { canonicalizeMatch } from "@utils/patches";
|
import { canonicalizeMatch } from "@utils/patches";
|
||||||
|
|
||||||
import { traceFunction } from "../debug/Tracer";
|
import { traceFunction } from "../debug/Tracer";
|
||||||
import { ModuleExports, ModuleFactory, WebpackRequire } from "./wreq";
|
import { AnyModuleFactory, ModuleExports, ModuleFactory, WebpackRequire } from "./wreq";
|
||||||
|
|
||||||
const logger = new Logger("Webpack");
|
const logger = new Logger("Webpack");
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ export type CallbackFn = (module: ModuleExports, id: PropertyKey) => void;
|
||||||
|
|
||||||
export const subscriptions = new Map<FilterFn, CallbackFn>();
|
export const subscriptions = new Map<FilterFn, CallbackFn>();
|
||||||
export const moduleListeners = new Set<CallbackFn>();
|
export const moduleListeners = new Set<CallbackFn>();
|
||||||
export const factoryListeners = new Set<(factory: ModuleFactory) => void>();
|
export const factoryListeners = new Set<(factory: AnyModuleFactory) => void>();
|
||||||
|
|
||||||
export function _initWebpack(webpackRequire: WebpackRequire) {
|
export function _initWebpack(webpackRequire: WebpackRequire) {
|
||||||
wreq = webpackRequire;
|
wreq = webpackRequire;
|
||||||
|
|
18
src/webpack/wreq.d.ts
vendored
18
src/webpack/wreq.d.ts
vendored
|
@ -53,7 +53,7 @@ export type OnChunksLoaded = ((this: WebpackRequire, result: any, chunkIds: Prop
|
||||||
j: (this: OnChunksLoaded, chunkId: PropertyKey) => boolean;
|
j: (this: OnChunksLoaded, chunkId: PropertyKey) => boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type WebpackRequire = ((moduleId: PropertyKey) => Module) & {
|
export type WebpackRequire = ((moduleId: PropertyKey) => ModuleExports) & {
|
||||||
/** The module factories, where all modules that have been loaded are stored (pre-loaded or loaded by lazy chunks) */
|
/** The module factories, where all modules that have been loaded are stored (pre-loaded or loaded by lazy chunks) */
|
||||||
m: Record<PropertyKey, ModuleFactory>;
|
m: Record<PropertyKey, ModuleFactory>;
|
||||||
/** The module cache, where all modules which have been WebpackRequire'd are stored */
|
/** The module cache, where all modules which have been WebpackRequire'd are stored */
|
||||||
|
@ -182,3 +182,19 @@ export type WebpackRequire = ((moduleId: PropertyKey) => Module) & {
|
||||||
/** Document baseURI or WebWorker location.href */
|
/** Document baseURI or WebWorker location.href */
|
||||||
b: string;
|
b: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Utility section for Vencord
|
||||||
|
|
||||||
|
export type AnyWebpackRequire = ((moduleId: PropertyKey) => ModuleExports) & Partial<Omit<WebpackRequire, "m" | "O">> & Pick<WebpackRequire, "O"> & {
|
||||||
|
/** The module factories, where all modules that have been loaded are stored (pre-loaded or loaded by lazy chunks) */
|
||||||
|
m: Record<PropertyKey, AnyModuleFactory>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** exports can be anything, however initially it is always an empty object */
|
||||||
|
export type AnyModuleFactory = (this: ModuleExports, module: Module, exports: ModuleExports, require: AnyWebpackRequire) => void;
|
||||||
|
|
||||||
|
export type PatchedModuleFactory = AnyModuleFactory & {
|
||||||
|
$$vencordOriginal?: AnyModuleFactory;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PatchedModuleFactories = Record<PropertyKey, PatchedModuleFactory>;
|
||||||
|
|
Loading…
Reference in a new issue