fix(metro): more checks for the event the cache got faulty (hopefully)
This commit is contained in:
parent
9bd47d28a4
commit
4cca972185
4 changed files with 43 additions and 20 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import { ClientInfoManager, MMKVManager } from "@lib/api/native/modules";
|
||||
import { throttle } from "@lib/utils/throttle";
|
||||
|
||||
const CACHE_VERSION = 24;
|
||||
const CACHE_VERSION = 29;
|
||||
const BUNNY_METRO_CACHE_KEY = `__bunny_metro_cache_key_v${CACHE_VERSION}__`;
|
||||
|
||||
export enum ExportsFlags {
|
||||
|
|
@ -9,9 +9,13 @@ export enum ExportsFlags {
|
|||
BLACKLISTED = 1 << 1
|
||||
}
|
||||
|
||||
export enum ModulesMapInternal {
|
||||
FULL_LOOKUP,
|
||||
NOT_FOUND
|
||||
}
|
||||
|
||||
type ModulesMap = {
|
||||
_?: 1;
|
||||
[id: number]: number;
|
||||
[flag in number | `_${ModulesMapInternal}`]?: 0 | ExportsFlags | undefined;
|
||||
};
|
||||
|
||||
let _metroCache = null as unknown as ReturnType<typeof buildInitCache>;
|
||||
|
|
@ -22,6 +26,7 @@ function buildInitCache() {
|
|||
const cache = {
|
||||
_v: CACHE_VERSION,
|
||||
_buildNumber: ClientInfoManager.Build as number,
|
||||
_modulesCount: Object.keys(window.modules).length,
|
||||
exportsIndex: {} as Record<string, number>,
|
||||
findIndex: {} as Record<string, ModulesMap | undefined>,
|
||||
polyfillIndex: {} as Record<string, ModulesMap | undefined>,
|
||||
|
|
@ -50,6 +55,10 @@ export async function initMetroCache() {
|
|||
_metroCache = null!;
|
||||
throw "cache invalidated; version mismatch";
|
||||
}
|
||||
if (_metroCache._modulesCount !== Object.keys(window.modules).length) {
|
||||
_metroCache = null!;
|
||||
throw "cache invalidated; modules count mismatch";
|
||||
}
|
||||
} catch {
|
||||
buildInitCache();
|
||||
}
|
||||
|
|
@ -78,33 +87,32 @@ export function indexBlacklistFlag(id: number) {
|
|||
}
|
||||
|
||||
export function getCacherForUniq(uniq: string, allFind: boolean) {
|
||||
let indexObject = _metroCache.findIndex[uniq];
|
||||
const indexObject = _metroCache.findIndex[uniq] ??= {};
|
||||
|
||||
return {
|
||||
cacheId(moduleId: number, exports: any) {
|
||||
indexObject ??= _metroCache.findIndex[uniq] ??= {};
|
||||
// TODO: A log here perhaps
|
||||
indexObject[moduleId] ??= extractExportsFlags(exports);
|
||||
|
||||
saveCache();
|
||||
},
|
||||
finish() {
|
||||
indexObject ??= _metroCache.findIndex[uniq] ??= {};
|
||||
if (allFind) indexObject._ = 1;
|
||||
// Finish may not be called by single find
|
||||
finish(notFound: boolean) {
|
||||
if (allFind) indexObject[`_${ModulesMapInternal.FULL_LOOKUP}`] = 1;
|
||||
if (notFound) indexObject[`_${ModulesMapInternal.NOT_FOUND}`] = 1;
|
||||
|
||||
saveCache();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function getPolyfillModuleCacher(name: string) {
|
||||
let indexObject = _metroCache.polyfillIndex[name];
|
||||
const indexObject = _metroCache.polyfillIndex[name] ??= {};
|
||||
|
||||
return {
|
||||
getModules() {
|
||||
return require("@metro/modules").getCachedPolyfillModules(name);
|
||||
},
|
||||
cacheId(moduleId: number) {
|
||||
indexObject ??= _metroCache.polyfillIndex[name] ??= {};
|
||||
indexObject[moduleId] = 1;
|
||||
saveCache();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ export function findModule<A extends unknown[]>(filter: FilterFn<A>) {
|
|||
}
|
||||
}
|
||||
|
||||
finish();
|
||||
finish(true);
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ export function findAllModule<A extends unknown[]>(filter: FilterFn<A>) {
|
|||
}
|
||||
}
|
||||
|
||||
finish();
|
||||
finish(foundExports.length === 0);
|
||||
return foundExports;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { ExportsFlags, getMetroCache, indexBlacklistFlag, indexExportsFlags } from "@metro/caches";
|
||||
import { ExportsFlags, getMetroCache, indexBlacklistFlag, indexExportsFlags, ModulesMapInternal } from "@metro/caches";
|
||||
import { Metro } from "@metro/types";
|
||||
import { before, instead } from "spitroast";
|
||||
|
||||
|
|
@ -166,7 +166,7 @@ export function requireModule(id: Metro.ModuleID) {
|
|||
if (!metroModules[0]?.isInitialized) metroRequire(0);
|
||||
if (blacklistedIds.has(id)) return undefined;
|
||||
|
||||
if (Number(id) === -1) return require("@metro/polyfills/redesign").default;
|
||||
if (Number(id) === -1) return require("@metro/polyfills/redesign");
|
||||
|
||||
if (metroModules[id]?.isInitialized && !metroModules[id]?.hasError) {
|
||||
return metroRequire(id);
|
||||
|
|
@ -191,12 +191,20 @@ export function requireModule(id: Metro.ModuleID) {
|
|||
}
|
||||
|
||||
export function* getModules(uniq: string, all = false) {
|
||||
yield [-1, require("@metro/polyfills/redesign").default];
|
||||
yield [-1, require("@metro/polyfills/redesign")];
|
||||
|
||||
let cache = getMetroCache().findIndex[uniq];
|
||||
if (all && !cache?._) cache = undefined;
|
||||
if (all && !cache?.[`_${ModulesMapInternal.FULL_LOOKUP}`]) cache = undefined;
|
||||
if (cache?.[`_${ModulesMapInternal.NOT_FOUND}`]) return;
|
||||
|
||||
for (const id in cache ?? metroModules) {
|
||||
for (const id in cache) {
|
||||
if (id[0] === "_") continue;
|
||||
const exports = requireModule(Number(id));
|
||||
if (isBadExports(exports)) continue;
|
||||
yield [id, exports];
|
||||
}
|
||||
|
||||
for (const id in metroModules) {
|
||||
const exports = requireModule(Number(id));
|
||||
if (isBadExports(exports)) continue;
|
||||
yield [id, exports];
|
||||
|
|
@ -205,7 +213,14 @@ export function* getModules(uniq: string, all = false) {
|
|||
|
||||
export function* getCachedPolyfillModules(name: string) {
|
||||
const cache = getMetroCache().polyfillIndex[name];
|
||||
for (const id in cache ?? metroModules) {
|
||||
|
||||
for (const id in cache) {
|
||||
const exports = requireModule(Number(id));
|
||||
if (isBadExports(exports)) continue;
|
||||
yield [id, exports];
|
||||
}
|
||||
|
||||
for (const id in metroModules) {
|
||||
const exports = requireModule(Number(id));
|
||||
if (isBadExports(exports)) continue;
|
||||
yield [id, exports];
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ interface FindProxyContext<A extends unknown[]> {
|
|||
function getIndexedSingleFind<A extends unknown[]>(filter: FilterFn<A>) {
|
||||
const modulesMap = getMetroCache().findIndex[filter.uniq];
|
||||
if (!modulesMap) return;
|
||||
const id = Object.keys(modulesMap).filter(k => k !== "_")[0];
|
||||
const id = Object.keys(modulesMap).filter(k => k[0] !== "_")[0];
|
||||
return id ? Number(id) : void 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue