diff --git a/src/lib/api/assets.ts b/src/lib/api/assets.ts index f7f71b7..e835cab 100644 --- a/src/lib/api/assets.ts +++ b/src/lib/api/assets.ts @@ -1,11 +1,11 @@ import { after } from "@lib/api/patcher"; -import { getMetroCache, registerAssetCacheId } from "@metro/caches"; +import { getMetroCache, indexAssetName } from "@metro/caches"; import { getImportingModuleId, requireModule } from "@metro/modules"; // TODO: Deprecate this map, make another that maps to an array of assets (Asset[]) instead /** * Pitfall: Multiple assets may have the same name, this is fine if we require the asset only for display,\ - * but not when used to get the registered id/index. In some condition, this would break some plugins like HideGiftButton that gets id by name.\ + * but not when used to get the registered id/index. In some condition, this would break some plugins like HideGiftButton that gets id by name for patching.\ */ export const assetsMap: Record = new Proxy({}, { get(cache, p) { @@ -13,13 +13,13 @@ export const assetsMap: Record = new Proxy({}, { if (cache[p]) return cache[p]; const moduleIds = getMetroCache().assetsIndex[p]; - if (moduleIds == null || Object.keys(moduleIds).length === 0) return undefined; + if (moduleIds == null) return undefined; for (const id in moduleIds) { const assetIndex = requireModule(Number(id)); - const assetDefinition = assetsModule.getAssetByID(assetIndex); + if (typeof assetIndex !== "number") continue; - // TODO: we shouldn't need this, this should never happen (unreproducible) + const assetDefinition = assetsModule.getAssetByID(assetIndex); if (!assetDefinition) continue; assetDefinition.index ??= assetDefinition.id ??= assetIndex; @@ -34,8 +34,11 @@ export const assetsMap: Record = new Proxy({}, { return cache[p]; }, ownKeys(cache) { - const keys = Reflect.ownKeys(getMetroCache().assetsIndex); - for (const key of keys) cache[key] = this.get!(cache, key, {}); + const keys = [] as Array; + for (const key in getMetroCache().assetsIndex) { + cache[key] = this.get!(cache, key, {}); + if (cache[key]) keys.push(key); + } return keys; }, }); @@ -64,7 +67,7 @@ export function patchAssets(module: AssetModule) { const unpatch = after("registerAsset", assetsModule, ([asset]: Asset[]) => { const moduleId = getImportingModuleId(); - if (moduleId !== -1) registerAssetCacheId(asset.name, moduleId); + if (moduleId !== -1) indexAssetName(asset.name, moduleId); }); return unpatch; diff --git a/src/metro/caches.ts b/src/metro/caches.ts index 5f17591..88a3330 100644 --- a/src/metro/caches.ts +++ b/src/metro/caches.ts @@ -1,7 +1,7 @@ import { ClientInfoManager, MMKVManager } from "@lib/api/native/modules"; import { throttle } from "@lib/utils/throttle"; -const CACHE_VERSION = 33; +const CACHE_VERSION = 34; const BUNNY_METRO_CACHE_KEY = "__bunny_metro_cache_key__"; export enum ExportsFlags { @@ -45,6 +45,7 @@ function buildInitCache() { return cache; } +// Store in file system export async function initMetroCache() { const rawCache = await MMKVManager.getItem(BUNNY_METRO_CACHE_KEY); if (rawCache == null) return void buildInitCache(); @@ -123,7 +124,7 @@ export function getPolyfillModuleCacher(name: string) { }; } -export function registerAssetCacheId(name: string, moduleId: number) { +export function indexAssetName(name: string, moduleId: number) { if (!isNaN(moduleId)) { (_metroCache.assetsIndex[name] ??= {})[moduleId] = 1; saveCache(); diff --git a/src/metro/modules.ts b/src/metro/modules.ts index 869f731..1cc9c8d 100644 --- a/src/metro/modules.ts +++ b/src/metro/modules.ts @@ -27,7 +27,9 @@ for (const key in metroModules) { if (metroModule!.factory) { instead("factory", metroModule, ((args: Parameters, origFunc: Metro.FactoryFn) => { + const originalImportingId = _importingModuleId; _importingModuleId = id; + const { 1: metroRequire, 4: moduleObject } = args; args[2 /* metroImportDefault */] = id => { @@ -52,7 +54,7 @@ for (const key in metroModules) { blacklistModule(id); } - _importingModuleId = -1; + _importingModuleId = originalImportingId; }) as any); // If only spitroast had better types } }