fix(lib/modules/finders/get): only lookup initialized modules

This commit is contained in:
PalmDevs 2026-04-01 13:35:05 +07:00
parent 2c0203d42e
commit bf967de902
No known key found for this signature in database
GPG key ID: 6FAE8F8677ACA8BA

View file

@ -1,4 +1,7 @@
import { onModuleInitialized } from '@revenge-mod/modules/metro/subscriptions'
import { isModuleInitialized } from '@revenge-mod/modules/metro/utils'
import { asap, noop } from '@revenge-mod/utils/callback'
import { FilterScopes } from './filters'
import { lookupModule, lookupModules } from './lookup'
import { waitForModules } from './wait'
import type { Metro } from '../types'
@ -28,12 +31,12 @@ export type GetModulesUnsubscribeFunction = () => void
/**
* Get modules matching the filter.
*
* This is a combination of {@link lookupModule} and {@link waitForModules}.
* If the matching modules are already initialized, the callback will be called immediately.
* Otherwise, it will be called when the matching modules are initialized.
*
* @param filter The filter to use to find the module.
* @param options The options to use for the find.
* @returns A promise that resolves to the module's exports or rejects if the find is aborted before a module is found.
* @returns A function to unsubscribe.
*
* @example
* ```ts
@ -69,19 +72,36 @@ export function getModules(
) {
let max = options?.max ?? 1
if (max === 1) {
const [exports, id] = lookupModule(filter, options!)
if (id !== undefined) {
// Only lookup modules that are already initialized
const lookupFilter = filter.scope(FilterScopes.Initialized)
function handleModule(
exports: Metro.ModuleExports | undefined,
id: Metro.ModuleID,
) {
if (isModuleInitialized(id)) {
// Run callback at the end of the event loop. This ensures that the noop is returned first.
// Module is already initialized, there is likely no harm calling the callback late.
asap(() => {
callback(exports, id)
})
} else {
// Module is not initialized, wait for it to be initialized before calling the callback.
onModuleInitialized(id, (_, exports) => {
callback(exports, id)
})
}
}
if (max === 1) {
const [exports, id] = lookupModule(lookupFilter, options!)
if (id !== undefined) {
handleModule(exports, id)
return noop
}
} else
for (const [exports, id] of lookupModules(filter, options!)) {
callback(exports, id)
for (const [exports, id] of lookupModules(lookupFilter, options!)) {
handleModule(exports, id)
if (!--max) return noop
}