Delete internals directory
This commit is contained in:
parent
fdcc756281
commit
4f6f5b636b
3 changed files with 0 additions and 406 deletions
|
|
@ -1,130 +0,0 @@
|
|||
import { fileExists, readFile, writeFile } from "@lib/api/native/fs";
|
||||
import { NativeClientInfoModule } from "@lib/api/native/modules";
|
||||
import { debounce } from "es-toolkit";
|
||||
|
||||
import { ModuleFlags, ModulesMapInternal } from "./enums";
|
||||
|
||||
const CACHE_VERSION = 102;
|
||||
const BUNNY_METRO_CACHE_PATH = "caches/metro_modules.json";
|
||||
|
||||
type ModulesMap = {
|
||||
[flag in number | `_${ModulesMapInternal}`]?: ModuleFlags;
|
||||
};
|
||||
|
||||
let _metroCache = null as unknown as ReturnType<typeof buildInitCache>;
|
||||
|
||||
export const getMetroCache = () => _metroCache;
|
||||
|
||||
function buildInitCache() {
|
||||
const cache = {
|
||||
_v: CACHE_VERSION,
|
||||
_buildNumber: NativeClientInfoModule.getConstants().Build,
|
||||
_modulesCount: Object.keys(window.modules).length,
|
||||
flagsIndex: {} as Record<string, number>,
|
||||
findIndex: {} as Record<string, ModulesMap | undefined>,
|
||||
polyfillIndex: {} as Record<string, ModulesMap | undefined>
|
||||
} as const;
|
||||
|
||||
// Force load all modules so useful modules are pre-cached. Add a minor
|
||||
// delay so the cache is initialized before the modules are loaded.
|
||||
setTimeout(() => {
|
||||
for (const id in window.modules) {
|
||||
require("./modules").requireModule(id);
|
||||
}
|
||||
}, 100);
|
||||
|
||||
_metroCache = cache;
|
||||
return cache;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export async function initMetroCache() {
|
||||
if (!await fileExists(BUNNY_METRO_CACHE_PATH)) return void buildInitCache();
|
||||
const rawCache = await readFile(BUNNY_METRO_CACHE_PATH);
|
||||
|
||||
try {
|
||||
_metroCache = JSON.parse(rawCache);
|
||||
if (_metroCache._v !== CACHE_VERSION) {
|
||||
_metroCache = null!;
|
||||
throw "cache invalidated; cache version outdated";
|
||||
}
|
||||
if (_metroCache._buildNumber !== NativeClientInfoModule.getConstants().Build) {
|
||||
_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();
|
||||
}
|
||||
}
|
||||
|
||||
const saveCache = debounce(() => {
|
||||
writeFile(BUNNY_METRO_CACHE_PATH, JSON.stringify(_metroCache));
|
||||
}, 1000);
|
||||
|
||||
function extractExportsFlags(moduleExports: any) {
|
||||
if (!moduleExports) return undefined;
|
||||
|
||||
const bit = ModuleFlags.EXISTS;
|
||||
return bit;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function indexExportsFlags(moduleId: number, moduleExports: any) {
|
||||
const flags = extractExportsFlags(moduleExports);
|
||||
if (flags && flags !== ModuleFlags.EXISTS) {
|
||||
_metroCache.flagsIndex[moduleId] = flags;
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function indexBlacklistFlag(id: number) {
|
||||
_metroCache.flagsIndex[id] |= ModuleFlags.BLACKLISTED;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function indexAssetModuleFlag(id: number) {
|
||||
_metroCache.flagsIndex[id] |= ModuleFlags.ASSET;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function getCacherForUniq(uniq: string, allFind: boolean) {
|
||||
const indexObject = _metroCache.findIndex[uniq] ??= {};
|
||||
|
||||
return {
|
||||
cacheId(moduleId: number, exports: any) {
|
||||
indexObject[moduleId] ??= extractExportsFlags(exports);
|
||||
|
||||
saveCache();
|
||||
},
|
||||
// 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();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function getPolyfillModuleCacher(name: string) {
|
||||
const indexObject = _metroCache.polyfillIndex[name] ??= {};
|
||||
|
||||
return {
|
||||
getModules() {
|
||||
return require("@metro/internals/modules").getCachedPolyfillModules(name);
|
||||
},
|
||||
cacheId(moduleId: number) {
|
||||
indexObject[moduleId] = 1;
|
||||
saveCache();
|
||||
},
|
||||
finish() {
|
||||
indexObject[`_${ModulesMapInternal.FULL_LOOKUP}`] = 1;
|
||||
saveCache();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
export enum ModuleFlags {
|
||||
EXISTS = 1 << 0,
|
||||
BLACKLISTED = 1 << 1,
|
||||
ASSET = 1 << 2,
|
||||
}
|
||||
|
||||
export enum ModulesMapInternal {
|
||||
FULL_LOOKUP,
|
||||
NOT_FOUND
|
||||
}
|
||||
|
|
@ -1,266 +0,0 @@
|
|||
import {
|
||||
getMetroCache,
|
||||
indexBlacklistFlag,
|
||||
indexExportsFlags,
|
||||
} from "@metro/internals/caches";
|
||||
import { Metro } from "@metro/types";
|
||||
|
||||
import { ModuleFlags, ModulesMapInternal } from "./enums";
|
||||
|
||||
const { before, instead } = require("spitroast");
|
||||
|
||||
export const metroModules: Metro.ModuleList = window.modules;
|
||||
const metroRequire = (id: string | number) => window.__r(+id);
|
||||
|
||||
// eslint-disable-next-line func-call-spacing
|
||||
const moduleSubscriptions = new Map<number, Set<() => void>>();
|
||||
const blacklistedIds = new Set<number>();
|
||||
const noopHandler = () => undefined;
|
||||
const functionToString = Function.prototype.toString;
|
||||
|
||||
let patchedInspectSource = false;
|
||||
let patchedImportTracker = false;
|
||||
let patchedNativeComponentRegistry = false;
|
||||
let _importingModuleId: number = -1;
|
||||
|
||||
for (const key in metroModules) {
|
||||
const id = Number(key);
|
||||
const metroModule = metroModules[id];
|
||||
|
||||
const cache = getMetroCache().flagsIndex[id];
|
||||
if (cache & ModuleFlags.BLACKLISTED) {
|
||||
blacklistModule(id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (metroModule!.factory) {
|
||||
instead("factory", metroModule, ((
|
||||
args: Parameters<Metro.FactoryFn>,
|
||||
origFunc: Metro.FactoryFn,
|
||||
) => {
|
||||
const originalImportingId = _importingModuleId;
|
||||
_importingModuleId = id;
|
||||
|
||||
const { 1: metroRequire, 4: moduleObject } = args;
|
||||
|
||||
args[2 /* metroImportDefault */] = (id) => {
|
||||
const exps = metroRequire(id);
|
||||
return exps && exps.__esModule ? exps.default : exps;
|
||||
};
|
||||
|
||||
args[3 /* metroImportAll */] = (id) => {
|
||||
const exps = metroRequire(id);
|
||||
if (exps && exps.__esModule) return exps;
|
||||
|
||||
const importAll: Record<string, any> = {};
|
||||
if (exps) Object.assign(importAll, exps);
|
||||
importAll.default = exps;
|
||||
return importAll;
|
||||
};
|
||||
|
||||
origFunc(...args);
|
||||
if (!isBadExports(moduleObject.exports)) {
|
||||
onModuleRequire(moduleObject.exports, id);
|
||||
} else {
|
||||
blacklistModule(id);
|
||||
}
|
||||
|
||||
_importingModuleId = originalImportingId;
|
||||
}) as any); // If only spitroast had better types
|
||||
}
|
||||
}
|
||||
|
||||
/** Makes the module associated with the specified ID non-enumberable. */
|
||||
function blacklistModule(id: number) {
|
||||
Object.defineProperty(metroModules, id, { enumerable: false });
|
||||
blacklistedIds.add(id);
|
||||
indexBlacklistFlag(Number(id));
|
||||
}
|
||||
|
||||
function isBadExports(exports: any) {
|
||||
return (
|
||||
!exports ||
|
||||
exports === window ||
|
||||
exports["<!@ pylix was here :fuyusquish: \n Hi pylix! -cocobo1!@>"] ===
|
||||
null ||
|
||||
(exports.__proto__ === Object.prototype &&
|
||||
Reflect.ownKeys(exports).length === 0) ||
|
||||
exports.default?.[Symbol.toStringTag] === "IntlMessagesProxy"
|
||||
);
|
||||
}
|
||||
|
||||
function onModuleRequire(moduleExports: any, id: Metro.ModuleID) {
|
||||
indexExportsFlags(id, moduleExports);
|
||||
|
||||
// Temporary
|
||||
moduleExports.initSentry &&= () => undefined;
|
||||
if (moduleExports.default?.track && moduleExports.default.trackMaker)
|
||||
moduleExports.default.track = () => Promise.resolve();
|
||||
|
||||
if (moduleExports.registerAsset) {
|
||||
require("@lib/api/assets/patches").patchAssets(moduleExports);
|
||||
}
|
||||
|
||||
// There are modules registering the same native component
|
||||
if (
|
||||
!patchedNativeComponentRegistry &&
|
||||
[
|
||||
"customBubblingEventTypes",
|
||||
"customDirectEventTypes",
|
||||
"register",
|
||||
"get",
|
||||
].every((x) => moduleExports[x])
|
||||
) {
|
||||
instead("register", moduleExports, ([name, cb]: any, origFunc: any) => {
|
||||
try {
|
||||
return origFunc(name, cb);
|
||||
} catch {
|
||||
return name;
|
||||
}
|
||||
});
|
||||
|
||||
patchedNativeComponentRegistry = true;
|
||||
}
|
||||
|
||||
// Hook DeveloperExperimentStore
|
||||
if (
|
||||
moduleExports?.default?.constructor?.displayName ===
|
||||
"DeveloperExperimentStore"
|
||||
) {
|
||||
moduleExports.default = new Proxy(moduleExports.default, {
|
||||
get(target, property, receiver) {
|
||||
if (property === "isDeveloper") {
|
||||
// Hopefully won't explode accessing it here :3
|
||||
const { settings } = require("@lib/api/settings");
|
||||
return settings.enableDiscordDeveloperSettings ?? false;
|
||||
}
|
||||
|
||||
return Reflect.get(target, property, receiver);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (!patchedImportTracker && moduleExports.fileFinishedImporting) {
|
||||
before("fileFinishedImporting", moduleExports, ([filePath]: [string]) => {
|
||||
if (_importingModuleId === -1 || !filePath) return;
|
||||
metroModules[_importingModuleId]!.__filePath = filePath;
|
||||
});
|
||||
patchedImportTracker = true;
|
||||
}
|
||||
|
||||
// Funny infinity recursion caused by a race condition
|
||||
if (!patchedInspectSource && window["__core-js_shared__"]) {
|
||||
const inspect = (f: unknown) =>
|
||||
typeof f === "function" && functionToString.apply(f, []);
|
||||
window["__core-js_shared__"].inspectSource = inspect;
|
||||
patchedInspectSource = true;
|
||||
}
|
||||
|
||||
//
|
||||
if (moduleExports.findHostInstance_DEPRECATED) {
|
||||
const prevExports = metroModules[id - 1]?.publicModule.exports;
|
||||
const inc = prevExports.default?.reactProfilingEnabled ? 1 : -1;
|
||||
if (!metroModules[id + inc]?.isInitialized) {
|
||||
blacklistModule(id + inc);
|
||||
}
|
||||
}
|
||||
|
||||
// Hindi timestamps moment
|
||||
if (moduleExports.isMoment) {
|
||||
instead(
|
||||
"defineLocale",
|
||||
moduleExports,
|
||||
(args: [string], orig: (lcl: string) => string) => {
|
||||
const origLocale = moduleExports.locale();
|
||||
orig(...args);
|
||||
moduleExports.locale(origLocale);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
const subs = moduleSubscriptions.get(Number(id));
|
||||
if (subs) {
|
||||
subs.forEach((s) => s());
|
||||
moduleSubscriptions.delete(Number(id));
|
||||
}
|
||||
}
|
||||
|
||||
export function getImportingModuleId() {
|
||||
return _importingModuleId;
|
||||
}
|
||||
|
||||
export function subscribeModule(id: number, cb: () => void): () => void {
|
||||
const subs = moduleSubscriptions.get(id) ?? new Set();
|
||||
|
||||
subs.add(cb);
|
||||
moduleSubscriptions.set(id, subs);
|
||||
|
||||
return () => subs.delete(cb);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
if (metroModules[id]?.isInitialized && !metroModules[id]?.hasError) {
|
||||
return metroRequire(id);
|
||||
}
|
||||
|
||||
// Disable Internal RN error reporting logic
|
||||
const originalHandler = ErrorUtils.getGlobalHandler();
|
||||
ErrorUtils.setGlobalHandler(noopHandler);
|
||||
|
||||
let moduleExports;
|
||||
try {
|
||||
moduleExports = metroRequire(id);
|
||||
} catch {
|
||||
blacklistModule(id);
|
||||
moduleExports = undefined;
|
||||
}
|
||||
|
||||
// Done initializing! Now, revert our hacks
|
||||
ErrorUtils.setGlobalHandler(originalHandler);
|
||||
|
||||
return moduleExports;
|
||||
}
|
||||
|
||||
export function* getModules(uniq: string, all = false) {
|
||||
yield [-1, require("@metro/polyfills/redesign")];
|
||||
|
||||
let cache = getMetroCache().findIndex[uniq];
|
||||
if (all && !cache?.[`_${ModulesMapInternal.FULL_LOOKUP}`]) cache = undefined;
|
||||
if (cache?.[`_${ModulesMapInternal.NOT_FOUND}`]) return;
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
export function* getCachedPolyfillModules(name: string) {
|
||||
const cache = getMetroCache().polyfillIndex[name]!;
|
||||
|
||||
for (const id in cache) {
|
||||
const exports = requireModule(Number(id));
|
||||
if (isBadExports(exports)) continue;
|
||||
yield [id, exports];
|
||||
}
|
||||
|
||||
if (!cache[`_${ModulesMapInternal.FULL_LOOKUP}`]) {
|
||||
for (const id in metroModules) {
|
||||
const exports = requireModule(Number(id));
|
||||
if (isBadExports(exports)) continue;
|
||||
yield [id, exports];
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue