feat(patcher): resolvable proxy patch
This commit is contained in:
parent
b0acf895e4
commit
dd6742d08d
4 changed files with 38 additions and 12 deletions
|
|
@ -5,8 +5,11 @@ import {
|
||||||
instead as _instead
|
instead as _instead
|
||||||
} from "spitroast";
|
} from "spitroast";
|
||||||
|
|
||||||
function shim<T extends (...args: any) => any>(fn: T) {
|
type ParametersAfterOneArgs<F> = F extends (x: any, y: any, ...args: infer P) => unknown ? P : never;
|
||||||
return function shimmed(this: any, ...args: Parameters<T>) {
|
type ProxyPatchParameters<T, P> = [func: string, parent: [P, (t: P) => any], ...args: ParametersAfterOneArgs<T>];
|
||||||
|
|
||||||
|
function shim<T extends (func: string, parent: any, ...args: ParametersAfterOneArgs<T>) => any>(fn: T) {
|
||||||
|
function shimmed(this: any, ...args: Parameters<T>) {
|
||||||
const proxyInfo = getFindProxyInfo(args[1]);
|
const proxyInfo = getFindProxyInfo(args[1]);
|
||||||
if (proxyInfo && !proxyInfo.cache && proxyInfo.indexed) {
|
if (proxyInfo && !proxyInfo.cache && proxyInfo.indexed) {
|
||||||
let cancel = false;
|
let cancel = false;
|
||||||
|
|
@ -20,7 +23,28 @@ function shim<T extends (...args: any) => any>(fn: T) {
|
||||||
return () => unpatch();
|
return () => unpatch();
|
||||||
}
|
}
|
||||||
return fn.apply(this, args);
|
return fn.apply(this, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
shimmed.proxy = function proxyPatch<P>(this: any, ...args: ProxyPatchParameters<T, P>) {
|
||||||
|
const [target, resolve] = args[1];
|
||||||
|
const proxyInfo = getFindProxyInfo(target);
|
||||||
|
if (!proxyInfo) {
|
||||||
|
args[1] = resolve(target);
|
||||||
|
return shimmed(...args as unknown as Parameters<T>);
|
||||||
|
}
|
||||||
|
|
||||||
|
let cancel = false;
|
||||||
|
let unpatch = () => cancel = true;
|
||||||
|
proxyInfo.getExports(exp => {
|
||||||
|
if (cancel) return;
|
||||||
|
args[1] = resolve(exp);
|
||||||
|
unpatch = shimmed(...args as unknown as Parameters<T>);
|
||||||
|
});
|
||||||
|
|
||||||
|
return unpatch;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return shimmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const after = shim(_after);
|
export const after = shim(_after);
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ const tabs: Tab[] = [
|
||||||
{ id: "componentStack", title: () => Strings.COMPONENT, trimWhitespace: true },
|
{ id: "componentStack", title: () => Strings.COMPONENT, trimWhitespace: true },
|
||||||
];
|
];
|
||||||
|
|
||||||
export default () => after("render", ErrorBoundary.prototype, function (this: any, _, ret) {
|
export default () => after.proxy("render", [ErrorBoundary, r => r.prototype], function (this: any, _, ret) {
|
||||||
if (!this.state.error) return;
|
if (!this.state.error) return;
|
||||||
|
|
||||||
// Not using setState here as we don't want to cause a re-render, we want this to be set in the initial render
|
// Not using setState here as we don't want to cause a re-render, we want this to be set in the initial render
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { getCacherForUniq } from "./caches";
|
||||||
import { getModules, requireModule } from "./modules";
|
import { getModules, requireModule } from "./modules";
|
||||||
import { FilterFn } from "./types";
|
import { FilterFn } from "./types";
|
||||||
|
|
||||||
export function filterExports<A extends unknown[]>(
|
function filterExports<A extends unknown[]>(
|
||||||
moduleExports: any,
|
moduleExports: any,
|
||||||
moduleId: number, filter:
|
moduleId: number, filter:
|
||||||
FilterFn<A>
|
FilterFn<A>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { proxyLazy } from "@lib/utils/lazy";
|
import { proxyLazy } from "@lib/utils/lazy";
|
||||||
|
|
||||||
import { getMetroCache } from "./caches";
|
import { getMetroCache } from "./caches";
|
||||||
import { filterExports, findExports } from "./finders";
|
import { findExports } from "./finders";
|
||||||
import { requireModule, subscribeModule } from "./modules";
|
import { metroModules, subscribeModule } from "./modules";
|
||||||
import type { FilterFn } from "./types";
|
import type { FilterFn } from "./types";
|
||||||
|
|
||||||
const proxyInfoMap = new WeakMap<{}, FindProxyInfo<any[]>>();
|
const proxyInfoMap = new WeakMap<{}, FindProxyInfo<any[]>>();
|
||||||
|
|
@ -11,6 +11,7 @@ interface FindProxyInfo<A extends unknown[]> {
|
||||||
filter: FilterFn<A>;
|
filter: FilterFn<A>;
|
||||||
indexed: boolean;
|
indexed: boolean;
|
||||||
moduleId: number | undefined;
|
moduleId: number | undefined;
|
||||||
|
getExports(cb: (exports: any) => void): () => void;
|
||||||
subscribe(cb: (exports: any) => void): () => void;
|
subscribe(cb: (exports: any) => void): () => void;
|
||||||
unproxy(): any;
|
unproxy(): any;
|
||||||
get cache(): any;
|
get cache(): any;
|
||||||
|
|
@ -29,12 +30,7 @@ function subscribeModuleForFind(proxy: any, callback: (exports: any) => void) {
|
||||||
if (!info.indexed) throw new Error("Attempting to subscribe to a non-indexed find");
|
if (!info.indexed) throw new Error("Attempting to subscribe to a non-indexed find");
|
||||||
|
|
||||||
return subscribeModule(info.moduleId!, () => {
|
return subscribeModule(info.moduleId!, () => {
|
||||||
const [exp] = filterExports(
|
callback(findExports(info.filter));
|
||||||
requireModule(info.moduleId!),
|
|
||||||
info.moduleId!,
|
|
||||||
info.filter
|
|
||||||
);
|
|
||||||
callback(exp);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,6 +46,12 @@ export function createFindProxy<A extends unknown[]>(filter: FilterFn<A>) {
|
||||||
filter,
|
filter,
|
||||||
indexed: !!moduleId,
|
indexed: !!moduleId,
|
||||||
moduleId,
|
moduleId,
|
||||||
|
getExports(cb: (exports: any) => void) {
|
||||||
|
if (moduleId && metroModules[moduleId!]?.isInitialized) {
|
||||||
|
return cb(findExports(filter)), () => { };
|
||||||
|
}
|
||||||
|
return this.subscribe(cb);
|
||||||
|
},
|
||||||
subscribe(cb: (exports: any) => void) {
|
subscribe(cb: (exports: any) => void) {
|
||||||
return subscribeModuleForFind(proxy, cb);
|
return subscribeModuleForFind(proxy, cb);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue