fix(metro): magical fixes
This commit is contained in:
parent
ee6669f514
commit
af6ba01079
4 changed files with 41 additions and 32 deletions
|
|
@ -1,40 +1,45 @@
|
|||
const factorySymbol = Symbol.for("bunny.lazyFactory");
|
||||
const cacheSymbol = Symbol("bunny.lazyCache");
|
||||
const dummySymbol = Symbol("bunny.lazyDummy");
|
||||
const factorySymbol = Symbol("lazyFactory");
|
||||
const cacheSymbol = Symbol("lazyCache");
|
||||
|
||||
const unconfigurable = ["arguments", "caller", "prototype"];
|
||||
const isUnconfigurable = (key: PropertyKey) => typeof key === "string" && unconfigurable.includes(key);
|
||||
|
||||
const lazyHandler: ProxyHandler<any> = {
|
||||
...Object.fromEntries(Object.getOwnPropertyNames(Reflect).map(fnName => {
|
||||
return [fnName, (target: any, ...args: any[]) => {
|
||||
// @ts-ignore
|
||||
const func = s => Reflect[fnName](s, ...args);
|
||||
return func(target[factorySymbol]()) ?? func(target[dummySymbol]);
|
||||
}];
|
||||
})),
|
||||
ownKeys: target => {
|
||||
const cacheKeys = Reflect.ownKeys(target[factorySymbol]() ?? target[dummySymbol]);
|
||||
const cacheKeys = Reflect.ownKeys(target[factorySymbol]());
|
||||
unconfigurable.forEach(key => isUnconfigurable(key) && cacheKeys.push(key));
|
||||
return cacheKeys;
|
||||
},
|
||||
getOwnPropertyDescriptor: (target, p) => {
|
||||
if (isUnconfigurable(p)) return Reflect.getOwnPropertyDescriptor(target, p);
|
||||
|
||||
const descriptor = Reflect.getOwnPropertyDescriptor(target[factorySymbol]() ?? target[dummySymbol], p);
|
||||
const descriptor = Reflect.getOwnPropertyDescriptor(target[factorySymbol](), p);
|
||||
if (descriptor) Object.defineProperty(target, p, descriptor);
|
||||
return descriptor;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
// Mirror all Reflect methods
|
||||
Object.getOwnPropertyNames(Reflect).forEach(fnName => {
|
||||
// @ts-ignore
|
||||
lazyHandler[fnName] ??= (target: any, ...args: any[]) => {
|
||||
// @ts-ignore
|
||||
return Reflect[fnName](target[factorySymbol](), ...args);
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Lazy proxy that will only call the factory function when needed (when a property is accessed)
|
||||
* @param factory Factory function to create the object
|
||||
* @param fallback A fallback value to return if the factory returns undefined
|
||||
* @returns A proxy that will call the factory function only when needed
|
||||
* @example const ChannelStore = proxyLazy(() => findByProps("getChannelId"));
|
||||
*/
|
||||
export function proxyLazy<T>(factory: () => T, dummy: any = () => void 0): T {
|
||||
dummy[factorySymbol] = () => dummy[cacheSymbol] ??= factory();
|
||||
dummy[dummySymbol] = dummy;
|
||||
export function proxyLazy<T>(factory: () => T, fallback?: any): T {
|
||||
const dummy = function () { } as any;
|
||||
dummy[factorySymbol] = () => {
|
||||
return (dummy[cacheSymbol] ??= factory()) ?? fallback;
|
||||
};
|
||||
|
||||
return new Proxy(dummy, lazyHandler) as any;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
import { ClientInfoManager, MMKVManager } from "@lib/api/native/modules";
|
||||
import { throttle } from "@lib/utils/throttle";
|
||||
|
||||
import { getCachedPolyfillModules } from "./modules";
|
||||
|
||||
type ModulesMap = {
|
||||
_?: 1;
|
||||
[id: number]: 1 | void;
|
||||
|
|
@ -22,6 +20,7 @@ let _metroCache = null as unknown as MetroCacheStore;
|
|||
export function getMetroCache() {
|
||||
return _metroCache;
|
||||
}
|
||||
window.getMetroCache = getMetroCache;
|
||||
|
||||
function buildInitCache() {
|
||||
_metroCache = {
|
||||
|
|
@ -59,14 +58,16 @@ export async function initMetroCache() {
|
|||
const saveCache = throttle(() => MMKVManager.setItem(BUNNY_METRO_CACHE_KEY, JSON.stringify(_metroCache)));
|
||||
|
||||
export function getCacherForUniq(uniq: string, allFind: boolean) {
|
||||
const indexObject = _metroCache.findIndex[uniq] ??= {};
|
||||
let indexObject = _metroCache.findIndex[uniq];
|
||||
|
||||
return {
|
||||
cacheId(moduleId: number) {
|
||||
indexObject = _metroCache.findIndex[uniq] ??= {};
|
||||
indexObject[moduleId] = 1;
|
||||
saveCache();
|
||||
},
|
||||
finish() {
|
||||
indexObject = _metroCache.findIndex[uniq] ??= {};
|
||||
if (allFind) indexObject._ = 1;
|
||||
saveCache();
|
||||
}
|
||||
|
|
@ -74,13 +75,14 @@ export function getCacherForUniq(uniq: string, allFind: boolean) {
|
|||
}
|
||||
|
||||
export function getPolyfillModuleCacher(name: string) {
|
||||
const indexObject = _metroCache.polyfillIndex[name] ??= {};
|
||||
let indexObject = _metroCache.polyfillIndex[name];
|
||||
|
||||
return {
|
||||
getModules() {
|
||||
return getCachedPolyfillModules(name);
|
||||
return require("@metro/modules").getCachedPolyfillModules(name);
|
||||
},
|
||||
cacheId(moduleId: number) {
|
||||
indexObject = _metroCache.polyfillIndex[name] ??= {};
|
||||
indexObject[moduleId] = 1;
|
||||
saveCache();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { FilterFn } from "./types";
|
|||
|
||||
function testExports<A extends unknown[]>(moduleExports: any, moduleId: number, filter: FilterFn<A>) {
|
||||
if (moduleExports.default && moduleExports.__esModule && filter(moduleExports.default, moduleId, true)) {
|
||||
return [moduleExports.default, true];
|
||||
return [filter.defaultFilter ? moduleExports : moduleExports.default, !filter.defaultFilter];
|
||||
}
|
||||
|
||||
if (!filter.defaultFilter && filter(moduleExports, moduleId, false)) {
|
||||
|
|
|
|||
|
|
@ -13,16 +13,6 @@ let patchedInspectSource = false;
|
|||
let patchedImportTracker = false;
|
||||
let _importingModuleId: string | null = null;
|
||||
|
||||
/** Makes the module associated with the specified ID non-enumberable. */
|
||||
function blacklistModule(id: string) {
|
||||
Object.defineProperty(metroModules, id, { enumerable: false });
|
||||
blacklistedIds.add(id);
|
||||
}
|
||||
|
||||
function isBadExports(exports: any) {
|
||||
return !exports || exports === window || exports["<!@ pylix was here :fuyusquish: !@>"] === null;
|
||||
}
|
||||
|
||||
for (const id in metroModules) {
|
||||
const metroModule = metroModules[id];
|
||||
|
||||
|
|
@ -57,6 +47,16 @@ for (const id in metroModules) {
|
|||
}
|
||||
}
|
||||
|
||||
/** Makes the module associated with the specified ID non-enumberable. */
|
||||
function blacklistModule(id: string) {
|
||||
Object.defineProperty(metroModules, id, { enumerable: false });
|
||||
blacklistedIds.add(id);
|
||||
}
|
||||
|
||||
function isBadExports(exports: any) {
|
||||
return !exports || exports === window || exports["<!@ pylix was here :fuyusquish: !@>"] === null;
|
||||
}
|
||||
|
||||
function onModuleRequire(moduleExports: any, id: Metro.ModuleID) {
|
||||
// Temporary
|
||||
moduleExports.initSentry &&= () => undefined;
|
||||
|
|
@ -136,6 +136,8 @@ export function requireModule(id: Metro.ModuleID) {
|
|||
if (!metroModules[0]?.isInitialized) metroRequire(0);
|
||||
if (blacklistedIds.has(String(id))) return undefined;
|
||||
|
||||
if (Number(id) === -1) return require("@metro/polyfills/redesign");
|
||||
|
||||
if (metroModules[id]?.isInitialized && !metroModules[id]?.hasError) {
|
||||
return metroRequire(id);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue