chore: cleanup

This commit is contained in:
PalmDevs 2025-07-05 13:12:57 +07:00
parent e83078abc8
commit 075f33f6c6
No known key found for this signature in database
GPG key ID: 6FAE8F8677ACA8BA
32 changed files with 299 additions and 240 deletions

View file

@ -1,4 +1,4 @@
import type { Asset, CustomAsset } from './types'
export const _customs = new Set<CustomAsset>()
export const _overrides = new WeakMap<Asset, Asset>()
export const aCustoms = new Set<CustomAsset>()
export const aOverrides = new WeakMap<Asset, Asset>()

View file

@ -1,5 +1,5 @@
import { Platform } from 'react-native'
import { _customs, _overrides } from './_internal'
import { aCustoms, aOverrides } from './_internal'
import { cache } from './caches'
import { AssetsRegistry } from './preinit'
import type {
@ -39,7 +39,7 @@ export function* getAssets(): Generator<Asset> {
* Yields all registered custom assets.
*/
export function* getCustomAssets(): Generator<CustomAsset> {
for (const asset of _customs) yield asset
for (const asset of aCustoms) yield asset
}
/**
@ -133,7 +133,7 @@ export function registerAsset(asset: RegisterableAsset): AssetId {
`Asset with name ${asset.name} and type ${asset.type} already exists!`,
)
_customs.add(asset as CustomAsset)
aCustoms.add(asset as CustomAsset)
// @ts-expect-error
return AssetsRegistry.registerAsset(asset)
@ -146,7 +146,7 @@ export function registerAsset(asset: RegisterableAsset): AssetId {
* @param override The custom asset to override with.
*/
export function addAssetOverride(asset: Asset, override: Asset) {
_overrides.set(asset, override)
aOverrides.set(asset, override)
}
/**
@ -156,5 +156,5 @@ export function addAssetOverride(asset: Asset, override: Asset) {
* @returns The asset that was removed.
*/
export function removeAssetOverride(asset: Asset) {
return _overrides.delete(asset)
return aOverrides.delete(asset)
}

View file

@ -1,8 +1,8 @@
import { _initing, _uninits } from '@revenge-mod/modules/_/metro'
import { mInitializingId, mUninitialized } from '@revenge-mod/modules/_/metro'
import { byName, byProps } from '@revenge-mod/modules/finders/filters'
import { waitForModules } from '@revenge-mod/modules/finders/wait'
import { getModuleDependencies } from '@revenge-mod/modules/metro/utils'
import { _overrides } from './_internal'
import { aOverrides } from './_internal'
import { cacheAsset, cached } from './caches'
import type { ReactNative } from '@revenge-mod/react/types'
import type { Asset, PackagerAsset } from './types'
@ -31,7 +31,7 @@ const unsubAR = waitForModules(
// More fragile way, but also more performant:
// There is exactly one asset before the reexported asset registry :/
const firstAssetModuleId = id - 1
for (const mId of _uninits) {
for (const mId of mUninitialized) {
if (mId < firstAssetModuleId) continue
const deps = getModuleDependencies(mId)!
@ -50,8 +50,8 @@ const unsubAR = waitForModules(
// Cache and set moduleId for packager assets only
if ((asset as PackagerAsset).__packager_asset) {
asset.moduleId = _initing!
cacheAsset(asset, _initing!)
asset.moduleId = mInitializingId!
cacheAsset(asset, mInitializingId!)
}
return (asset.id = result)
@ -79,6 +79,6 @@ const unsubRAS = waitForModules(
// Asset overrides
// @ts-expect-error
rAS.addCustomSourceTransformer(({ asset }) => _overrides.get(asset))
rAS.addCustomSourceTransformer(({ asset }) => aOverrides.get(asset))
},
)

View file

@ -1,8 +1,8 @@
import { _uapi } from '@revenge-mod/plugins/_'
import { pUnscopedApi } from '@revenge-mod/plugins/_'
import { defineLazyProperty } from '@revenge-mod/utils/objects'
import type { UnscopedInitPluginApi } from '@revenge-mod/plugins/types'
const uapi = _uapi as UnscopedInitPluginApi
const uapi = pUnscopedApi as UnscopedInitPluginApi
defineLazyProperty(uapi, 'components', () => {
return require('.')

View file

@ -1,4 +1,4 @@
import { _emitter, _uapi } from '@revenge-mod/plugins/_'
import { pEmitter, pUnscopedApi } from '@revenge-mod/plugins/_'
import {
defineLazyProperties,
defineLazyProperty,
@ -8,7 +8,7 @@ import type { UnscopedInitPluginApi } from '@revenge-mod/plugins/types'
import type { PluginApiDiscord } from './types/revenge'
defineLazyProperties(
((_uapi as UnscopedInitPluginApi).discord = {} as PluginApiDiscord),
((pUnscopedApi as UnscopedInitPluginApi).discord = {} as PluginApiDiscord),
{
actions: () => {
return require('@revenge-mod/discord/actions')
@ -35,7 +35,7 @@ defineLazyProperties(
},
)
_emitter.on('init', ({ manifest: { id } }, api) =>
pEmitter.on('init', ({ manifest: { id } }, api) =>
defineLazyProperty(
api,
'logger',

View file

@ -4,7 +4,7 @@ import type {
SettingsSection,
} from '.'
export const _data = [
export const sData = [
// Sections to splice in the SettingsOverviewScreen
{},
// SETTING_RENDERER_CONFIG settings
@ -16,4 +16,4 @@ export const _data = [
loaded: boolean,
]
export const _subs = new Set<SettingsModulesLoadedSubscription>()
export const sSubscriptions = new Set<SettingsModulesLoadedSubscription>()

View file

@ -2,7 +2,7 @@ import { ReactNavigationNative } from '@revenge-mod/externals/react-navigation'
import { findInTree } from '@revenge-mod/utils/trees'
import { Constants } from '../../common'
import { RootNavigationRef } from '../main_tabs_v2'
import { _data, _subs } from './_internal'
import { sData, sSubscriptions } from './_internal'
import type { NavigationState } from '@react-navigation/core'
import type { DiscordModules } from '../../types'
@ -15,7 +15,7 @@ export type SettingsModulesLoadedSubscription = () => void
* Checks if the settings modules are loaded.
*/
export function isSettingsModulesLoaded() {
return _data[2]
return sData[2]
}
/**
@ -29,10 +29,10 @@ export function isSettingsModulesLoaded() {
export function onSettingsModulesLoaded(
subcription: SettingsModulesLoadedSubscription,
) {
if (_data[2]) throw new Error('Settings modules already loaded')
if (sData[2]) throw new Error('Settings modules already loaded')
_subs.add(subcription)
return () => _subs.delete(subcription)
sSubscriptions.add(subcription)
return () => sSubscriptions.delete(subcription)
}
/**
@ -43,8 +43,8 @@ export function onSettingsModulesLoaded(
* @returns A function to unregister the settings section.
*/
export function registerSettingsSection(key: string, section: SettingsSection) {
_data[0][key] = section
return () => delete _data[0][key]
sData[0][key] = section
return () => delete sData[0][key]
}
/**
@ -55,8 +55,8 @@ export function registerSettingsSection(key: string, section: SettingsSection) {
* @returns A function to unregister the settings item.
*/
export function registerSettingsItem(key: string, item: SettingsItem) {
_data[1][key] = item
return () => delete _data[1][key]
sData[1][key] = item
return () => delete sData[1][key]
}
/**
@ -66,10 +66,10 @@ export function registerSettingsItem(key: string, item: SettingsItem) {
* @returns A function to unregister the settings items.
*/
export function registerSettingsItems(record: Record<string, SettingsItem>) {
Object.assign(_data[1], record)
Object.assign(sData[1], record)
return () => {
let ret = true
for (const key in record) ret &&= delete _data[1][key]
for (const key in record) ret &&= delete sData[1][key]
return ret
}
}
@ -82,7 +82,7 @@ export function registerSettingsItems(record: Record<string, SettingsItem>) {
* @returns A function to remove the settings item from the section.
*/
export function addSettingsItemToSection(key: string, item: string) {
const section = _data[0][key]
const section = sData[0][key]
if (!section) throw new Error(`Section "${key}" does not exist`)
const newLength = section.settings.push(item)

View file

@ -1,10 +1,11 @@
import { _uapi } from '@revenge-mod/plugins/_'
import { pUnscopedApi } from '@revenge-mod/plugins/_'
import { defineLazyProperties } from '@revenge-mod/utils/objects'
import type { UnscopedInitPluginApi } from '@revenge-mod/plugins/types'
import type { PluginApiExternals } from './types'
defineLazyProperties(
((_uapi as UnscopedInitPluginApi).externals = {} as PluginApiExternals),
((pUnscopedApi as UnscopedInitPluginApi).externals =
{} as PluginApiExternals),
{
Browserify: () => {
return require('@revenge-mod/externals/browserify')

View file

@ -38,7 +38,7 @@ export type RunFilterReturnExportsOptions<
}
>
const FilterResultFlags = {
export const FilterResultFlags = {
/**
* A module was found, without exports filtering.
*/

View file

@ -1,4 +1,4 @@
import { _inits } from '../metro/_internal'
import { mInitialized } from '../metro/_internal'
import { getModuleDependencies, isModuleInitialized } from '../metro/utils'
import type { If, LogicalOr } from '@revenge-mod/utils/types'
import type { Metro } from '../types'
@ -529,7 +529,7 @@ export const moduleStateAware = createFilterGenerator<
>(
([initializedFilter, uninitializedFilter, strict], id, exports) => {
if (isModuleInitialized(id)) {
if (_inits.has(id) && initializedFilter(id, exports))
if (mInitialized.has(id) && initializedFilter(id, exports))
return strict ? uninitializedFilter(id) : true
return false
}
@ -570,7 +570,7 @@ export type PreferExports = FilterGenerator<
*/
export const preferExports = createFilterGenerator<Parameters<PreferExports>>(
([withExportsFilter, exportslessFilter, strict], id, exports) => {
if (_inits.has(id)) {
if (mInitialized.has(id)) {
if (withExportsFilter(id, exports))
return strict ? exportslessFilter(id) : true
return false

View file

@ -13,9 +13,9 @@ import type { WaitForModulesOptions } from './wait'
export type GetModuleOptions<
ReturnNamespace extends boolean = boolean,
IncludeUninitialized extends boolean = boolean,
Uninitialized extends boolean = boolean,
> = WaitForModulesOptions<ReturnNamespace> &
LookupModulesOptions<ReturnNamespace, IncludeUninitialized> & {
LookupModulesOptions<ReturnNamespace, Uninitialized> & {
/**
* The maximum number of modules to get.
*

View file

@ -1,42 +1,60 @@
import { getCurrentStack } from '@revenge-mod/utils/errors'
import { proxify } from '@revenge-mod/utils/proxy'
import { cache } from '../caches'
import { _inits, _metas, _paths, _uninits } from '../metro/_internal'
import {
mImportedPaths,
mInitialized,
mMetadata,
mUninitialized,
} from '../metro/_internal'
import {
getInitializedModuleExports,
isModuleInitialized,
} from '../metro/utils'
import { exportsFromFilterResultFlag, runFilter } from './_internal'
import type { If } from '@revenge-mod/utils/types'
import type { If, Nullish } from '@revenge-mod/utils/types'
import type { MaybeDefaultExportMatched, Metro } from '../types'
import type { RunFilterReturnExportsOptions } from './_internal'
import type { Filter, FilterResult } from './filters'
interface LookupModulesOptionsWithAll<O extends boolean> {
/**
* Whether to include all modules in the lookup, including blacklisted ones.
*
* **This overrides {@link BaseLookupModulesOptions.initialized} and {@link BaseLookupModulesOptions.uninitialized}.**
*/
all: O
}
type LookupModulesOptionsWithAll<A extends boolean> = If<
A,
{
/**
* Whether to include all modules in the lookup, including blacklisted ones.
*
* **This overrides {@link BaseLookupModulesOptions.initialized} and {@link BaseLookupModulesOptions.uninitialized}.**
*/
all: A
},
{
all?: false
}
>
interface LookupModulesOptionsWithInitializedUninitialized<U extends boolean> {
type LookupModulesOptionsWithInitializedUninitialized<U extends boolean> = {
/**
* Whether to include initialized modules in the lookup.
*
* @default true
*/
initialized?: boolean
/**
* Whether to include uninitialized modules in the lookup.
*
* Set {@link BaseLookupModulesOptions.initialize} `true` to initialize uninitialized modules.
*
* @default false
*/
uninitialized?: U
}
} & If<
U,
{
/**
* Whether to include uninitialized modules in the lookup.
*
* Set {@link BaseLookupModulesOptions.initialize} `true` to initialize uninitialized modules.
*
* @default false
*/
uninitialized: U
},
{
uninitialized?: false
}
>
export type LookupModulesOptions<
ReturnNamespace extends boolean = boolean,
@ -48,13 +66,21 @@ export type LookupModulesOptions<
* Whether to use cached lookup results.
*/
cached?: boolean
/**
* Whether to initialize matching uninitialized modules.
*
* **This will initialize any modules that match the exportsless filter and may cause unintended side effects.**
*/
initialize?: Initialize
} & If<
Initialize,
{
/**
* Whether to initialize matching uninitialized modules.
*
* **This will initialize any modules that match the exportsless filter and may cause unintended side effects.**
*/
initialize?: Initialize
},
{
initialize: false
}
> &
If<
All,
LookupModulesOptionsWithAll<All> & {
[K in keyof LookupModulesOptionsWithInitializedUninitialized<Uninitialized>]?: never
@ -70,7 +96,7 @@ export type LookupModulesResult<
> = [
exports: O extends LookupModulesOptions<boolean, boolean, false, true>
? LookupFilterResult<F, O>
: LookupFilterResult<F, O> | undefined,
: LookupFilterResult<F, O> | Nullish,
id: Metro.ModuleID,
]
@ -107,9 +133,14 @@ export function lookupModules<F extends Filter>(
): Generator<LookupModulesResult<F, object>, undefined>
export function lookupModules<
F extends O extends LookupModulesOptions<boolean, true>
? Filter<any, false>
: Filter,
F extends Filter<
any,
O extends
| LookupModulesOptions<boolean, true>
| LookupModulesOptions<boolean, boolean, true>
? false
: true
>,
const O extends LookupModulesOptions,
>(filter: F, options: O): Generator<LookupModulesResult<F, O>, undefined>
@ -117,9 +148,9 @@ export function* lookupModules(filter: Filter, options?: LookupModulesOptions) {
let notFound = true
let cached: Set<Metro.ModuleID> | undefined
const notInit = !(options?.initialize ?? true)
if (options?.cached ?? true) {
const notInit = !(options?.initialize ?? true)
const reg = cache[filter.key]
// Return early if previous lookup was a full lookup and no modules were found
if (reg === null) return
@ -148,7 +179,7 @@ export function* lookupModules(filter: Filter, options?: LookupModulesOptions) {
// Full lookup
if (options?.all) {
for (const id of _metas.keys()) {
for (const id of mMetadata.keys()) {
if (cached?.has(id)) continue
const exports = getInitializedModuleExports(id)
@ -164,7 +195,7 @@ export function* lookupModules(filter: Filter, options?: LookupModulesOptions) {
// Partial lookup
else {
if (options?.initialized ?? true)
for (const id of _inits) {
for (const id of mInitialized) {
if (cached?.has(id)) continue
const exports = getInitializedModuleExports(id)
@ -179,7 +210,7 @@ export function* lookupModules(filter: Filter, options?: LookupModulesOptions) {
}
if (options?.uninitialized)
for (const id of _uninits) {
for (const id of mUninitialized) {
if (cached?.has(id)) continue
const flag = runFilter(filter, id, undefined, options)
@ -228,9 +259,9 @@ export function lookupModule<
>(filter: F, options: O): LookupModulesResult<F, O> | LookupNotFoundResult
export function lookupModule(filter: Filter, options?: LookupModulesOptions) {
const notInit = !(options?.initialize ?? true)
if (options?.cached ?? true) {
const notInit = !(options?.initialize ?? true)
const reg = cache[filter.key]
// Return early if previous lookup was a full lookup and no modules were found
if (reg === null) return NotFoundResult
@ -254,7 +285,7 @@ export function lookupModule(filter: Filter, options?: LookupModulesOptions) {
// Full lookup
if (options?.all) {
for (const id of _metas.keys()) {
for (const id of mMetadata.keys()) {
const exports = getInitializedModuleExports(id)
const flag = runFilter(filter, id, exports, options)
if (flag)
@ -271,7 +302,7 @@ export function lookupModule(filter: Filter, options?: LookupModulesOptions) {
// Partial lookup
else {
if (options?.initialized ?? true)
for (const id of _inits) {
for (const id of mInitialized) {
const exports = getInitializedModuleExports(id)
const flag = runFilter(filter, id, exports, options)
if (flag)
@ -282,7 +313,7 @@ export function lookupModule(filter: Filter, options?: LookupModulesOptions) {
}
if (options?.uninitialized)
for (const id of _uninits) {
for (const id of mUninitialized) {
const flag = runFilter(filter, id, undefined, options)
if (flag)
return [
@ -318,13 +349,13 @@ export function lookupModule(filter: Filter, options?: LookupModulesOptions) {
export function lookupModuleByImportedPath<T = any>(
path: string,
): [exports: T, id: Metro.ModuleID] | [] {
const id = _paths.get(path)
const id = mImportedPaths.get(path)
if (id == null) return NotFoundResult
return [getInitializedModuleExports(id), id]
}
const __blacklistedFunctions = __BUILD_FLAG_DEBUG_MODULE_LOOKUPS__
const __DEBUG_TRACER_IGNORE_LIST__ = __BUILD_FLAG_DEBUG_MODULE_LOOKUPS__
? proxify(
() => [
require('./get').getModule,
@ -342,7 +373,7 @@ const __blacklistedFunctions = __BUILD_FLAG_DEBUG_MODULE_LOOKUPS__
*/
function warnDeveloperAboutNoFilterMatch(filter: Filter) {
const stack = getCurrentStack()
for (const func of __blacklistedFunctions)
for (const func of __DEBUG_TRACER_IGNORE_LIST__)
if (stack.includes(func.name)) return
nativeLoggingHook(

View file

@ -1,4 +1,4 @@
import { _inits } from '../metro/_internal'
import { mInitialized } from '../metro/_internal'
import {
onAnyModuleInitialized,
onModuleFinishedImporting,
@ -9,15 +9,13 @@ import type { MaybeDefaultExportMatched, Metro } from '../types'
import type { RunFilterReturnExportsOptions } from './_internal'
import type { Filter, FilterResult } from './filters'
export interface BaseWaitForModulesOptions<
IncludeAll extends boolean = boolean,
> {
export interface BaseWaitForModulesOptions<All extends boolean = boolean> {
/**
* Whether to include all modules, including blacklisted ones.
*
* @default false
*/
all?: IncludeAll
all?: All
}
export type WaitForModulesUnsubscribeFunction = () => boolean
@ -26,9 +24,9 @@ export type WaitForModulesCallback<T> = (exports: T, id: Metro.ModuleID) => any
export type WaitForModulesOptions<
ReturnNamespace extends boolean = boolean,
IncludeBadExports extends boolean = boolean,
All extends boolean = boolean,
> = RunFilterReturnExportsOptions<ReturnNamespace> &
BaseWaitForModulesOptions<IncludeBadExports>
BaseWaitForModulesOptions<All>
export type WaitForModulesResult<
F extends Filter,
@ -89,7 +87,7 @@ export function waitForModules(
)
}
: (id, exports) => {
if (_inits.has(id)) {
if (mInitialized.has(id)) {
const flag = runFilter(filter, id, exports, options)
if (flag)
callback(
@ -141,7 +139,7 @@ export function waitForModuleByImportedPath<T = any>(
}
}
: (id, cmpPath) => {
if (path === cmpPath && _inits.has(id)) {
if (path === cmpPath && mInitialized.has(id)) {
unsub()
callback(getInitializedModuleExports(id), id)
}

View file

@ -1,16 +1,19 @@
import { _execInitSubs, _execReqSubs } from './subscriptions/_internal'
import {
executeInitializeSubscriptions,
executeRequireSubscriptions,
} from './subscriptions/_internal'
import { isModuleExportsBad } from './utils'
import type { Metro } from '../types'
/** Initializing ID */
export let _initing: Metro.ModuleID | null = null
export let mInitializingId: Metro.ModuleID | null = null
/** Known uninitialized IDs */
export const _uninits = new Set<Metro.ModuleID>()
export const mUninitialized = new Set<Metro.ModuleID>()
/** Known initialized IDs (not blacklisted) */
export const _inits = new Set<Metro.ModuleID>()
export const mInitialized = new Set<Metro.ModuleID>()
export const _paths = new Map<string, Metro.ModuleID>()
export const _metas = new Map<Metro.ModuleID, Metadata>()
export const mImportedPaths = new Map<string, Metro.ModuleID>()
export const mMetadata = new Map<Metro.ModuleID, Metadata>()
export type Metadata = [
deps: Metro.DependencyMap,
@ -22,8 +25,8 @@ export function patchMetroDefine(metroDefine: Metro.DefineFn) {
return ((origFactory, id, deps) => {
// deps won't be undefined last time I checked
const metadata = [deps!, false] satisfies Metadata
_metas.set(id, metadata)
_uninits.add(id)
mMetadata.set(id, metadata)
mUninitialized.add(id)
metroDefine(
((global, req, importDefault, importAll, module, exports, deps) => {
@ -60,10 +63,10 @@ function handleFactoryCall(
) {
metadata[2] = module
const prevIId = _initing
_initing = id
const prevIId = mInitializingId
mInitializingId = id
_execReqSubs(id)
executeRequireSubscriptions(id)
try {
factory(global, req, importDefault, importAll, module, exports, deps)
@ -71,10 +74,10 @@ function handleFactoryCall(
// Add the module to the initialized set only if the factory doesn't error or the exports aren't bad
// Don't use exports here, as modules can set module.exports to a different object
if (!isModuleExportsBad(module.exports)) _inits.add(id)
_execInitSubs(id, module.exports)
if (!isModuleExportsBad(module.exports)) mInitialized.add(id)
executeInitializeSubscriptions(id, module.exports)
} catch {}
_initing = prevIId
_uninits.delete(id)
mInitializingId = prevIId
mUninitialized.delete(id)
}

View file

@ -1,7 +1,7 @@
import { byProps } from '../finders/filters'
import { waitForModules } from '../finders/wait'
import { _initing, _paths } from './_internal'
import { _execPathSubs } from './subscriptions/_internal'
import { mImportedPaths, mInitializingId } from './_internal'
import { executeImportedPathSubscriptions } from './subscriptions/_internal'
const unsubFFI = waitForModules(byProps('fileFinishedImporting'), exports => {
unsubFFI()
@ -9,8 +9,8 @@ const unsubFFI = waitForModules(byProps('fileFinishedImporting'), exports => {
const orig = exports.fileFinishedImporting
exports.fileFinishedImporting = (path: string) => {
orig(path)
const id = _initing!
_paths.set(path, id)
_execPathSubs(id, path)
const id = mInitializingId!
mImportedPaths.set(path, id)
executeImportedPathSubscriptions(id, path)
}
})

View file

@ -5,31 +5,40 @@ import type {
ModuleInitializedCallback,
} from '.'
export const _reqAll = new Set<ModuleFirstRequiredCallback>()
export const _req = new Map<Metro.ModuleID, Set<ModuleFirstRequiredCallback>>()
export const _initAll = new Set<ModuleInitializedCallback>()
export const _init = new Map<Metro.ModuleID, Set<ModuleInitializedCallback>>()
export const _path = new Set<ModuleFinishedImportingCallback>()
export const sRequireAny = new Set<ModuleFirstRequiredCallback>()
export const sRequire = new Map<
Metro.ModuleID,
Set<ModuleFirstRequiredCallback>
>()
export const sInitializeAny = new Set<ModuleInitializedCallback>()
export const sInitialize = new Map<
Metro.ModuleID,
Set<ModuleInitializedCallback>
>()
export const sImportedPath = new Set<ModuleFinishedImportingCallback>()
export function _execReqSubs(id: Metro.ModuleID) {
for (const cb of _reqAll) cb(id)
if (_req.has(id)) {
for (const cb of _req.get(id)!) cb(id)
_req.delete(id)
export function executeRequireSubscriptions(id: Metro.ModuleID) {
for (const cb of sRequireAny) cb(id)
if (sRequire.has(id)) {
for (const cb of sRequire.get(id)!) cb(id)
sRequire.delete(id)
}
}
export function _execInitSubs(
export function executeInitializeSubscriptions(
id: Metro.ModuleID,
exports: Metro.ModuleExports,
) {
for (const cb of _initAll) cb(id, exports)
if (_init.has(id)) {
for (const cb of _init.get(id)!) cb(id, exports)
_init.delete(id)
for (const cb of sInitializeAny) cb(id, exports)
if (sInitialize.has(id)) {
for (const cb of sInitialize.get(id)!) cb(id, exports)
sInitialize.delete(id)
}
}
export function _execPathSubs(id: Metro.ModuleID, path: string) {
for (const cb of _path) cb(id, path)
export function executeImportedPathSubscriptions(
id: Metro.ModuleID,
path: string,
) {
for (const cb of sImportedPath) cb(id, path)
}

View file

@ -1,4 +1,10 @@
import { _init, _initAll, _path, _req, _reqAll } from './_internal'
import {
sImportedPath,
sInitialize,
sInitializeAny,
sRequire,
sRequireAny,
} from './_internal'
import type { Metro } from '../../types'
export type ModuleFirstRequiredCallback = (id: Metro.ModuleID) => void
@ -23,8 +29,8 @@ export type ModuleFinishedImportingCallback = (
* @returns A function that unregisters the callback.
*/
export function onAnyModuleInitialized(callback: ModuleInitializedCallback) {
_initAll.add(callback)
return () => _initAll.delete(callback)
sInitializeAny.add(callback)
return () => sInitializeAny.delete(callback)
}
/**
@ -43,10 +49,10 @@ export function onModuleInitialized(
id: Metro.ModuleID,
callback: ModuleInitializedCallback,
) {
let set = _init.get(id)
let set = sInitialize.get(id)
if (!set) {
set = new Set()
_init.set(id, set)
sInitialize.set(id, set)
}
set.add(callback)
@ -64,8 +70,8 @@ export function onModuleInitialized(
export function onModuleFinishedImporting(
callback: ModuleFinishedImportingCallback,
) {
_path.add(callback)
return () => _path.delete(callback)
sImportedPath.add(callback)
return () => sImportedPath.delete(callback)
}
/**
@ -81,8 +87,8 @@ export function onModuleFinishedImporting(
export function onAnyModuleFirstRequired(
callback: ModuleFirstRequiredCallback,
) {
_reqAll.add(callback)
return () => _reqAll.delete(callback)
sRequireAny.add(callback)
return () => sRequireAny.delete(callback)
}
/**
@ -100,10 +106,10 @@ export function onModuleFirstRequired(
id: Metro.ModuleID,
callback: ModuleFirstRequiredCallback,
) {
let set = _req.get(id)
let set = sRequire.get(id)
if (!set) {
set = new Set()
_req.set(id, set)
sRequire.set(id, set)
}
set.add(callback)

View file

@ -1,5 +1,5 @@
import { isProxy } from '@revenge-mod/utils/proxy'
import { _metas } from './_internal'
import { mMetadata } from './_internal'
import type { Metro } from '../types'
/**
@ -10,7 +10,7 @@ import type { Metro } from '../types'
export function getModuleDependencies(
id: Metro.ModuleID,
): Metro.DependencyMap | undefined {
return _metas.get(id)?.[0]
return mMetadata.get(id)?.[0]
}
/**
@ -19,7 +19,7 @@ export function getModuleDependencies(
* @returns `true` if the module is initialized, `false` if it is not initialized, or `undefined` if the module does not exist.
*/
export function isModuleInitialized(id: Metro.ModuleID): boolean | undefined {
return _metas.get(id)?.[1]
return mMetadata.get(id)?.[1]
}
/**
@ -33,7 +33,7 @@ export function isModuleInitialized(id: Metro.ModuleID): boolean | undefined {
export function getInitializedModuleExports(
id: Metro.ModuleID,
): Metro.ModuleExports | undefined {
return _metas.get(id)?.[2]?.exports
return mMetadata.get(id)?.[2]?.exports
}
/**

View file

@ -1,6 +1,6 @@
import { TypedEventEmitter } from '@revenge-mod/discord/common/utils'
import { allSettled, sleepReject } from '@revenge-mod/utils/promises'
import { _uapi as uapi } from './apis'
import { pUnscopedApi as uapi } from './apis'
import { PluginFlags as Flag, PluginStatus as Status } from './constants'
import type {
InitPluginApi,
@ -13,9 +13,9 @@ import type {
PreInitPluginApi,
} from './types'
export const _uapi = uapi
export const pUnscopedApi = uapi
export const _emitter = new TypedEventEmitter<{
export const pEmitter = new TypedEventEmitter<{
register: [InternalPlugin, PluginOptions<any>]
disabled: [InternalPlugin]
enabled: [InternalPlugin]
@ -32,8 +32,8 @@ export const _emitter = new TypedEventEmitter<{
error: [InternalPlugin, unknown]
}>()
export const _plugins = new Map<PluginManifest['id'], InternalPlugin>()
export const _metas = new Map<
export const pList = new Map<PluginManifest['id'], InternalPlugin>()
export const pMetadata = new Map<
PluginManifest['id'],
[
api: PreInitPluginApi | InitPluginApi | PluginApi | undefined,
@ -50,7 +50,7 @@ export function registerPlugin<O extends PluginApiExtensionsOptions>(
iflags: number,
) {
// TODO(plugins): verify plugin manifest
if (_plugins.has(manifest.id))
if (pList.has(manifest.id))
throw new Error(`Plugin with ID "${manifest.id}" already registered`)
const plugin: InternalPlugin = {
@ -70,27 +70,27 @@ export function registerPlugin<O extends PluginApiExtensionsOptions>(
stop: () => stopPlugin(plugin),
}
_metas.set(manifest.id, [undefined, [], iflags, PluginApiLevel.None])
_plugins.set(manifest.id, plugin)
pMetadata.set(manifest.id, [undefined, [], iflags, PluginApiLevel.None])
pList.set(manifest.id, plugin)
_emitter.emit('register', plugin, options)
pEmitter.emit('register', plugin, options)
}
function handlePluginError(e: unknown, plugin: InternalPlugin) {
plugin.errors.push(e)
plugin.flags |= Flag.Errored
const [api, , iflags] = _metas.get(plugin.manifest.id)!
const [api, , iflags] = pMetadata.get(plugin.manifest.id)!
const log = (api as InitPluginApi).logger ?? console
log.error('Plugin encountered an error', e)
_emitter.emit('error', plugin, e)
pEmitter.emit('error', plugin, e)
if (!(iflags & InternalPluginFlags.Essential)) return plugin.disable()
}
function preparePluginPreInit(plugin: InternalPlugin) {
const meta = _metas.get(plugin.manifest.id)!
const meta = pMetadata.get(plugin.manifest.id)!
// Clear errors from previous runs
plugin.errors = []
@ -101,24 +101,24 @@ function preparePluginPreInit(plugin: InternalPlugin) {
plugin._c.push(...items)
},
plugin,
unscoped: _uapi,
unscoped: pUnscopedApi,
})
_emitter.emit('preInit', plugin, api)
pEmitter.emit('preInit', plugin, api)
meta[3] = PluginApiLevel.PreInit
}
function preparePluginInit(plugin: InternalPlugin) {
const meta = _metas.get(plugin.manifest.id)!
const meta = pMetadata.get(plugin.manifest.id)!
_emitter.emit('init', plugin, meta[0] as InitPluginApi)
pEmitter.emit('init', plugin, meta[0] as InitPluginApi)
meta[3] = PluginApiLevel.Init
}
function preparePluginStart(plugin: InternalPlugin) {
const meta = _metas.get(plugin.manifest.id)!
const meta = pMetadata.get(plugin.manifest.id)!
_emitter.emit('start', plugin, meta[0] as PluginApi)
pEmitter.emit('start', plugin, meta[0] as PluginApi)
meta[3] = PluginApiLevel.Start
}
@ -126,7 +126,7 @@ async function disablePlugin(plugin: InternalPlugin) {
if (!(plugin.flags & Flag.Enabled))
throw new Error(`Plugin "${plugin.manifest.id}" is not enabled`)
const iflags = _metas.get(plugin.manifest.id)![2] ?? 0
const iflags = pMetadata.get(plugin.manifest.id)![2] ?? 0
if (iflags & InternalPluginFlags.Essential)
throw new Error(
`Plugin "${plugin.manifest.id}" is essential and cannot be disabled`,
@ -139,7 +139,7 @@ async function disablePlugin(plugin: InternalPlugin) {
// TODO(plugins): write to storage
plugin.flags &= ~Flag.Enabled
_emitter.emit('disabled', plugin)
pEmitter.emit('disabled', plugin)
}
export function enablePlugin(plugin: InternalPlugin, late: boolean) {
@ -150,7 +150,7 @@ export function enablePlugin(plugin: InternalPlugin, late: boolean) {
plugin.flags |= Flag.Enabled
if (late) plugin.flags |= Flag.EnabledLate
_emitter.emit('enabled', plugin)
pEmitter.emit('enabled', plugin)
}
export async function preInitPlugin(plugin: InternalPlugin) {
@ -161,7 +161,7 @@ export async function preInitPlugin(plugin: InternalPlugin) {
try {
if (!lifecycles.preInit) return
const meta = _metas.get(id)!
const meta = pMetadata.get(id)!
const [, promises] = meta
if (!(plugin.flags & Flag.Enabled))
@ -187,7 +187,7 @@ export async function preInitPlugin(plugin: InternalPlugin) {
await handlePluginError(e, plugin)
}
} finally {
_emitter.emit('preInited', plugin)
pEmitter.emit('preInited', plugin)
}
}
@ -200,7 +200,7 @@ export async function initPlugin(plugin: InternalPlugin) {
try {
if (!lifecycles.init) return
const meta = _metas.get(id)!
const meta = pMetadata.get(id)!
const [, promises, , apiLevel] = meta
if (!(plugin.flags & Flag.Enabled))
@ -227,7 +227,7 @@ export async function initPlugin(plugin: InternalPlugin) {
await handlePluginError(e, plugin)
}
} finally {
_emitter.emit('inited', plugin)
pEmitter.emit('inited', plugin)
}
}
@ -240,7 +240,7 @@ export async function startPlugin(plugin: InternalPlugin) {
try {
if (!lifecycles.start) return
const meta = _metas.get(id)!
const meta = pMetadata.get(id)!
const [, promises, , apiLevel] = meta
if (!(plugin.flags & Flag.Enabled))
@ -268,7 +268,7 @@ export async function startPlugin(plugin: InternalPlugin) {
await handlePluginError(e, plugin)
}
} finally {
_emitter.emit('started', plugin)
pEmitter.emit('started', plugin)
}
}
@ -279,7 +279,7 @@ export async function stopPlugin(plugin: InternalPlugin) {
manifest: { id },
lifecycles,
} = plugin
const meta = _metas.get(id)!
const meta = pMetadata.get(id)!
const [, promises, iflags, apiLevel] = meta
if (iflags & InternalPluginFlags.Essential)
@ -366,7 +366,7 @@ export async function stopPlugin(plugin: InternalPlugin) {
// Reset status
plugin.status = 0
_emitter.emit('stopped', plugin)
pEmitter.emit('stopped', plugin)
}
}

View file

@ -7,7 +7,7 @@ import type {
UnscopedPreInitPluginApi,
} from '../types'
export const _uapi:
export const pUnscopedApi:
| UnscopedPreInitPluginApi
| UnscopedInitPluginApi
| UnscopedPluginApi = {

View file

@ -1,22 +1,22 @@
import * as AssetsLibrary from '@revenge-mod/assets'
import { onRunApplication } from '@revenge-mod/react/native'
import { _plugins, initPlugin, startPlugin } from './_internal'
import { _uapi } from './apis'
import { initPlugin, pList, startPlugin } from './_internal'
import { pUnscopedApi } from './apis'
import { react } from './apis/react'
import { PluginFlags } from './constants'
import type { UnscopedInitPluginApi } from './types'
// Setup init plugin APIs
const uapi = _uapi as UnscopedInitPluginApi
const uapi = pUnscopedApi as UnscopedInitPluginApi
uapi.assets = AssetsLibrary
uapi.react = react
for (const plugin of _plugins.values())
for (const plugin of pList.values())
if (plugin.flags & PluginFlags.Enabled) initPlugin(plugin)
const unsub = onRunApplication(() => {
unsub()
for (const plugin of _plugins.values())
for (const plugin of pList.values())
if (plugin.flags & PluginFlags.Enabled) startPlugin(plugin)
})

View file

@ -1,5 +1,5 @@
import { _plugins, preInitPlugin } from './_internal'
import { pList, preInitPlugin } from './_internal'
import { PluginFlags } from './constants'
for (const plugin of _plugins.values())
for (const plugin of pList.values())
if (plugin.flags & PluginFlags.Enabled) preInitPlugin(plugin)

View file

@ -1,4 +1,4 @@
import { _ara, _bra } from './patches'
import { sAfterRunApplication, sBeforeRunApplication } from './patches'
/**
* Registers a callback to be run when a call to {@link AppRegistry.runApplication} is made.
@ -7,8 +7,8 @@ import { _ara, _bra } from './patches'
* @returns A function to unregister the callback.
*/
export function onRunApplication(callback: RunApplicationCallback) {
_bra.add(callback)
return () => _bra.delete(callback)
sBeforeRunApplication.add(callback)
return () => sBeforeRunApplication.delete(callback)
}
/**
@ -18,8 +18,8 @@ export function onRunApplication(callback: RunApplicationCallback) {
* @returns A function to unregister the callback.
*/
export function onRunApplicationFinished(callback: RunApplicationCallback) {
_ara.add(callback)
return () => _ara.delete(callback)
sAfterRunApplication.add(callback)
return () => sAfterRunApplication.delete(callback)
}
export type RunApplicationCallback = () => any

View file

@ -4,19 +4,19 @@ import { after, before } from '@revenge-mod/patcher'
import { ReactNative } from '..'
import type { RunApplicationCallback } from '.'
export const _bra = new Set<RunApplicationCallback>()
export const _ara = new Set<RunApplicationCallback>()
export const sBeforeRunApplication = new Set<RunApplicationCallback>()
export const sAfterRunApplication = new Set<RunApplicationCallback>()
const unsub = waitForModules(byProps('AppRegistry'), () => {
unsub()
before(ReactNative.AppRegistry, 'runApplication', args => {
for (const cb of _bra) cb()
for (const cb of sBeforeRunApplication) cb()
return args
})
after(ReactNative.AppRegistry, 'runApplication', res => {
for (const cb of _ara) cb()
for (const cb of sAfterRunApplication) cb()
return res
})
})

View file

@ -1,9 +1,9 @@
import { _emitter } from '@revenge-mod/plugins/_'
import { pEmitter } from '@revenge-mod/plugins/_'
import { PluginsStorageDirectory } from '@revenge-mod/plugins/constants'
import { defineLazyProperty } from '@revenge-mod/utils/objects'
import { getStorage } from '.'
_emitter.on('init', ({ _s: storageOptions, manifest: { id } }, api) =>
pEmitter.on('init', ({ _s: storageOptions, manifest: { id } }, api) =>
defineLazyProperty(api, 'storage', () =>
getStorage(`${PluginsStorageDirectory}/${id}.json`, {
...storageOptions,

View file

@ -1,5 +1,5 @@
import { _emitter } from '@revenge-mod/plugins/_'
import { pEmitter } from '@revenge-mod/plugins/_'
_emitter.on('register', (plugin, options) => {
pEmitter.on('register', (plugin, options) => {
plugin._s = options.storage
})

View file

@ -4,10 +4,10 @@ import FormSwitch from '@revenge-mod/components/FormSwitch'
import { Tokens } from '@revenge-mod/discord/common'
import { Design } from '@revenge-mod/discord/design'
import {
_emitter,
enablePlugin,
InternalPluginFlags,
initPlugin,
pEmitter,
preInitPlugin,
startPlugin,
} from '@revenge-mod/plugins/_'
@ -52,12 +52,12 @@ export function InstalledPluginCard({
const listener = (p: InternalPlugin) =>
id === p.manifest.id && reRender()
_emitter.on('disabled', listener)
_emitter.on('enabled', listener)
pEmitter.on('disabled', listener)
pEmitter.on('enabled', listener)
return () => {
_emitter.off('disabled', listener)
_emitter.off('enabled', listener)
pEmitter.off('disabled', listener)
pEmitter.off('enabled', listener)
}
})

View file

@ -2,7 +2,7 @@ import TableRowAssetIcon from '@revenge-mod/components/TableRowAssetIcon'
import { AlertActionCreators } from '@revenge-mod/discord/actions'
import { Design } from '@revenge-mod/discord/design'
import { BundleUpdaterManager } from '@revenge-mod/discord/native'
import { _emitter, _plugins } from '@revenge-mod/plugins/_'
import { pEmitter, pList } from '@revenge-mod/plugins/_'
import { PluginFlags } from '@revenge-mod/plugins/constants'
import { useReRender } from '@revenge-mod/utils/react'
import { useEffect } from 'react'
@ -28,14 +28,14 @@ const RevengePluginsSetting: SettingsItem = {
let enabledCount = 0
for (const plugin of _plugins.values())
for (const plugin of pList.values())
if (plugin.flags & PluginFlags.Enabled) enabledCount++
_emitter.on('disabled', () => {
pEmitter.on('disabled', () => {
enabledCount--
})
_emitter.on('enabled', () => {
pEmitter.on('enabled', () => {
enabledCount++
})
@ -43,20 +43,20 @@ export function useUpdateOnPluginStatesChange() {
const reRender = useReRender()
useEffect(() => {
_emitter.on('disabled', reRender)
_emitter.on('enabled', reRender)
pEmitter.on('disabled', reRender)
pEmitter.on('enabled', reRender)
return () => {
_emitter.off('disabled', reRender)
_emitter.off('enabled', reRender)
pEmitter.off('disabled', reRender)
pEmitter.off('enabled', reRender)
}
}, [reRender])
}
const { AlertActionButton, AlertModal, Text } = Design
_emitter.on('started', showReloadRequiredAlertIfNeeded)
_emitter.on('stopped', showReloadRequiredAlertIfNeeded)
pEmitter.on('started', showReloadRequiredAlertIfNeeded)
pEmitter.on('stopped', showReloadRequiredAlertIfNeeded)
function showReloadRequiredAlertIfNeeded(plugin: InternalPlugin) {
if (plugin.flags & PluginFlags.ReloadRequired) {

View file

@ -1,4 +1,4 @@
import { _data, _subs } from '@revenge-mod/discord/_/modules/settings'
import { sData, sSubscriptions } from '@revenge-mod/discord/_/modules/settings'
import { onSettingsModulesLoaded } from '@revenge-mod/discord/modules/settings'
import { byName, byProps } from '@revenge-mod/modules/finders/filters'
import { waitForModules } from '@revenge-mod/modules/finders/wait'
@ -33,7 +33,7 @@ registerPlugin(
'Settings modules loaded, running subscriptions and patching...',
)
for (const sub of _subs)
for (const sub of sSubscriptions)
try {
sub()
} catch (e) {
@ -44,8 +44,8 @@ registerPlugin(
}
// We don't ever need to call this again
_subs.clear()
_data[2] = true
sSubscriptions.clear()
sData[2] = true
let ORIGINAL_RENDERER_CONFIG =
SettingRendererConfig.SETTING_RENDERER_CONFIG
@ -57,7 +57,7 @@ registerPlugin(
get: () =>
({
...ORIGINAL_RENDERER_CONFIG,
..._data[1],
...sData[1],
}) as Record<string, SettingsItem>,
set: v => (ORIGINAL_RENDERER_CONFIG = v),
},
@ -70,7 +70,7 @@ registerPlugin(
exports => {
unsubSOS()
const customSections = _data[0]
const customSections = sData[0]
after(exports as { default: FC }, 'default', tree => {
const {

View file

@ -6,7 +6,7 @@ import { ActionSheetActionCreators } from '@revenge-mod/discord/actions'
import { Design } from '@revenge-mod/discord/design'
import { ReactNavigationNative } from '@revenge-mod/externals/react-navigation'
import { FlashList } from '@revenge-mod/externals/shopify'
import { _metas, _plugins, InternalPluginFlags } from '@revenge-mod/plugins/_'
import { InternalPluginFlags, pList, pMetadata } from '@revenge-mod/plugins/_'
import { PluginFlags } from '@revenge-mod/plugins/constants'
import { debounce } from '@revenge-mod/utils/callbacks'
import { useCallback, useMemo, useState } from 'react'
@ -107,8 +107,9 @@ function Screen() {
const allPlugins = useMemo(
() =>
[..._plugins.values()].map(
plugin => [plugin, _metas.get(plugin.manifest.id)![2]] as const,
[...pList.values()].map(
plugin =>
[plugin, pMetadata.get(plugin.manifest.id)![2]] as const,
),
[],
)

View file

@ -3,10 +3,11 @@ import { Tokens } from '@revenge-mod/discord/common'
import { Stores } from '@revenge-mod/discord/common/flux'
import { Design } from '@revenge-mod/discord/design'
import { RootNavigationRef } from '@revenge-mod/discord/modules/main_tabs_v2'
import { _metas } from '@revenge-mod/plugins/_'
import { pMetadata } from '@revenge-mod/plugins/_'
import { createElement } from 'react'
import { Image } from 'react-native'
import { RouteNames, Setting } from './constants'
import type { DiscordModules } from '@revenge-mod/discord/types'
import type { ReactNavigationParamList } from '@revenge-mod/externals/react-navigation'
import type { Plugin, PluginApi } from '@revenge-mod/plugins/types'
@ -15,7 +16,7 @@ const { NavigatorHeader } = Design
// TODO(plugins/settings): Register a custom route instead, so plugin "settings" can actually be pinned and navigated to without hassle.
// This would require us to implement the event-based plugin management system first, so we can listen to plugin enable/disable events and update the settings accordingly.
export function navigatePluginSettings(plugin: Plugin) {
const [api] = _metas.get(plugin.manifest.id)!
const [api] = pMetadata.get(plugin.manifest.id)!
const navigation =
RootNavigationRef.getRootNavigationRef<ReactNavigationParamList>()
if (!navigation.isReady()) return
@ -37,7 +38,11 @@ export function navigatePluginSettings(plugin: Plugin) {
marginEnd: 8,
tintColor:
Tokens.default.internal.resolveSemanticColor(
Stores.ThemeStore.theme,
(
Stores.ThemeStore as DiscordModules.Flux.Store<{
theme: string
}>
).theme,
Tokens.default.colors
.HEADER_PRIMARY,
),

View file

@ -5,6 +5,7 @@ import { getModule } from '@revenge-mod/modules/finders/get'
import { instead } from '@revenge-mod/patcher'
import { InternalPluginFlags, registerPlugin } from '@revenge-mod/plugins/_'
import { PluginFlags } from '@revenge-mod/plugins/constants'
import type { DiscordModules } from '@revenge-mod/discord/types'
registerPlugin(
{
@ -17,27 +18,26 @@ registerPlugin(
{
start({ cleanup, logger }) {
function reset() {
getStore<{ initialize(): void }>(
'DeveloperExperimentStore',
store => {
logger.log(
'Reinitializing DeveloperExperimentStore to apply changes...',
)
getStore<{
initialize(): void
}>('DeveloperExperimentStore', store => {
logger.log(
'Reinitializing DeveloperExperimentStore to apply changes...',
)
const unpatch = instead(
Object,
'defineProperties',
args => args[0],
)
const unpatch = instead(
Object,
'defineProperties',
args => args[0],
)
store.initialize()
unpatch()
store.initialize()
unpatch()
setTimeout(() => {
refreshSettingsOverviewScreen(true)
})
},
)
setTimeout(() => {
refreshSettingsOverviewScreen(true)
})
})
}
cleanup(
@ -49,7 +49,12 @@ registerPlugin(
UserStoreUtils,
'isStaffEnv',
([user]) =>
user === Stores.UserStore.getCurrentUser(),
user ===
(
Stores.UserStore as DiscordModules.Flux.Store<{
getCurrentUser(): unknown
}>
).getCurrentUser(),
),
reset,
)