feat(lib/modules/finders/waits): cached-only waits
This commit is contained in:
parent
00e9794baf
commit
578b78dd7e
9 changed files with 112 additions and 38 deletions
|
|
@ -35,6 +35,8 @@ const byAssetSourceResolver = byDependencies([
|
|||
invariantId,
|
||||
])
|
||||
|
||||
const cachedOnly = { cached: true }
|
||||
|
||||
// Tracking/caching assets
|
||||
const unsubAR = waitForModules(
|
||||
byProps<ReactNative.AssetsRegistry>('registerAsset'),
|
||||
|
|
@ -82,6 +84,7 @@ const unsubAR = waitForModules(
|
|||
return (asset.id = result)
|
||||
}
|
||||
},
|
||||
cachedOnly,
|
||||
)
|
||||
|
||||
/**
|
||||
|
|
@ -138,4 +141,5 @@ const unsubRAS = waitForModules(
|
|||
// @ts-expect-error
|
||||
rAS.addCustomSourceTransformer(({ asset }) => aOverrides.get(asset))
|
||||
},
|
||||
cachedOnly,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ export function getStore<T>(
|
|||
return noop
|
||||
}
|
||||
|
||||
return waitForModules(byStoreName<T>(name), callback)
|
||||
return waitForModules(byStoreName<T>(name), callback, { cached: true })
|
||||
}
|
||||
|
||||
/// FILTERING
|
||||
|
|
|
|||
|
|
@ -37,4 +37,7 @@ const unsubSRC = waitForModules(
|
|||
},
|
||||
)
|
||||
},
|
||||
{
|
||||
cached: true,
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { noop } from '@revenge-mod/utils/callback'
|
||||
import { getCachedFilterRegistry } from '../caches'
|
||||
import { mInitialized } from '../metro/patches'
|
||||
import {
|
||||
onAnyModuleInitialized,
|
||||
|
|
@ -34,7 +36,18 @@ export type WaitForModulesOptions<
|
|||
ReturnNamespace extends boolean = boolean,
|
||||
All extends boolean = boolean,
|
||||
> = RunFilterReturnExportsOptions<ReturnNamespace> &
|
||||
BaseWaitForModulesOptions<All>
|
||||
BaseWaitForModulesOptions<All> & {
|
||||
/**
|
||||
* Use cached results **only** (if possible).
|
||||
* If there is no cache result, this works as if you did not pass this option at all.
|
||||
*
|
||||
* By default, waits cache results but does not use them, because new modules may still be found.
|
||||
* Use this option as an optimization if you are sure that you don't need to find new modules once results are cached.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
cached?: boolean
|
||||
}
|
||||
|
||||
export type WaitForModulesResult<
|
||||
F extends Filter,
|
||||
|
|
@ -84,6 +97,46 @@ export function waitForModules(
|
|||
callback: WaitForModulesCallback<any>,
|
||||
options?: WaitForModulesOptions,
|
||||
): WaitForModulesUnsubscribeFunction {
|
||||
if (options?.cached) {
|
||||
const reg = getCachedFilterRegistry(filter.key)
|
||||
if (reg === null) return noop
|
||||
|
||||
if (reg) {
|
||||
if (__BUILD_FLAG_DEBUG_MODULE_WAITS__)
|
||||
nativeLoggingHook(
|
||||
`\u001b[32mUsing cached results for wait \u001b[33m${filter.key}\u001b[0m`,
|
||||
1,
|
||||
)
|
||||
|
||||
const runCachedCallback = (id: Metro.ModuleID) => {
|
||||
const flag = reg[id]
|
||||
|
||||
DEBUG_logWaitMatched(filter.key, id, flag, true)
|
||||
callback(
|
||||
exportsFromFilterResultFlag(
|
||||
flag,
|
||||
getInitializedModuleExports(id),
|
||||
options,
|
||||
),
|
||||
id,
|
||||
)
|
||||
}
|
||||
|
||||
const cleanups: Array<() => void> = []
|
||||
|
||||
for (const sId of Object.keys(reg)) {
|
||||
const id = Number(sId)
|
||||
if (mInitialized.has(id)) continue
|
||||
|
||||
cleanups.push(onModuleInitialized(id, runCachedCallback))
|
||||
}
|
||||
|
||||
return () => {
|
||||
for (const cleanup of cleanups) cleanup()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (__BUILD_FLAG_DEBUG_MODULE_WAITS__)
|
||||
nativeLoggingHook(
|
||||
`\u001b[94mWaiting for module matching: \u001b[93m${filter.key}\u001b[0m`,
|
||||
|
|
@ -173,9 +226,10 @@ function DEBUG_logWaitMatched(
|
|||
key: string,
|
||||
id: Metro.ModuleID,
|
||||
flag: FilterResultFlag,
|
||||
cached?: boolean,
|
||||
) {
|
||||
nativeLoggingHook(
|
||||
`\u001b[32mWait matched: \u001b[33m${key}\u001b[0m (matched ${id}, ${FilterResultFlagToHumanReadable[flag]})`,
|
||||
`\u001b[32mWait matched: \u001b[33m${key}\u001b[0m (matched ${id}, ${FilterResultFlagToHumanReadable[flag]}${cached ? ', \u001b[92mcached\u001b[0m' : ''})`,
|
||||
1,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ const unsubRN = waitForModules(
|
|||
|
||||
ReactNativeModuleId = id
|
||||
ReactNative = exports
|
||||
|
||||
require('./native/patches')
|
||||
},
|
||||
{
|
||||
cached: true,
|
||||
},
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import { byProps } from '@revenge-mod/modules/finders/filters'
|
||||
import { waitForModules } from '@revenge-mod/modules/finders/wait'
|
||||
import { after, before } from '@revenge-mod/patcher'
|
||||
import { ReactNative } from '..'
|
||||
import type { RunApplicationCallback } from '../types'
|
||||
|
|
@ -7,22 +5,18 @@ import type { RunApplicationCallback } from '../types'
|
|||
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 sBeforeRunApplication)
|
||||
try {
|
||||
cb()
|
||||
} catch {}
|
||||
return args
|
||||
})
|
||||
|
||||
after(ReactNative.AppRegistry, 'runApplication', res => {
|
||||
for (const cb of sAfterRunApplication)
|
||||
try {
|
||||
cb()
|
||||
} catch {}
|
||||
return res
|
||||
})
|
||||
before(ReactNative.AppRegistry, 'runApplication', args => {
|
||||
for (const cb of sBeforeRunApplication)
|
||||
try {
|
||||
cb()
|
||||
} catch {}
|
||||
return args
|
||||
})
|
||||
|
||||
after(ReactNative.AppRegistry, 'runApplication', res => {
|
||||
for (const cb of sAfterRunApplication)
|
||||
try {
|
||||
cb()
|
||||
} catch {}
|
||||
return res
|
||||
})
|
||||
|
|
|
|||
|
|
@ -7,6 +7,10 @@ import { PluginFlags } from '@revenge-mod/plugins/constants'
|
|||
import { noop } from '@revenge-mod/utils/callback'
|
||||
import { getCurrentStack } from '@revenge-mod/utils/error'
|
||||
|
||||
const cachedOnly = {
|
||||
cached: true,
|
||||
}
|
||||
|
||||
// TODO(plugins/no-track): Block Sentry native-side
|
||||
registerPlugin(
|
||||
{
|
||||
|
|
@ -42,6 +46,7 @@ registerPlugin(
|
|||
instead(SentryUtils, 'setTags', noop)
|
||||
instead(SentryUtils, 'setUser', noop)
|
||||
},
|
||||
cachedOnly,
|
||||
)
|
||||
|
||||
// modules/errors/native/SentryInitUtils.tsx
|
||||
|
|
@ -52,6 +57,7 @@ registerPlugin(
|
|||
|
||||
instead(SentryInitUtils, 'initSentry', noop)
|
||||
},
|
||||
cachedOnly,
|
||||
)
|
||||
|
||||
// Discord uses ReactNavigationInstrumentation to track navigation
|
||||
|
|
@ -71,6 +77,7 @@ registerPlugin(
|
|||
},
|
||||
)
|
||||
},
|
||||
cachedOnly,
|
||||
)
|
||||
|
||||
if (__DEV__)
|
||||
|
|
@ -86,17 +93,7 @@ registerPlugin(
|
|||
|
||||
cleanup(unsubSU, unsubSIU, unsubSentryInst)
|
||||
},
|
||||
start({
|
||||
cleanup,
|
||||
logger,
|
||||
unscoped: {
|
||||
discord: {
|
||||
common: {
|
||||
flux: { DispatcherModuleId },
|
||||
},
|
||||
},
|
||||
},
|
||||
}) {
|
||||
init({ cleanup }) {
|
||||
// utils/AnalyticsUtils.tsx
|
||||
const unsubAU = waitForModules(
|
||||
byProps<{
|
||||
|
|
@ -109,7 +106,6 @@ registerPlugin(
|
|||
AnalyticsUtils => {
|
||||
unsubAU()
|
||||
|
||||
logger.info('Patching AnalyticsUtils...')
|
||||
instead(AnalyticsUtils.default, 'track', noop)
|
||||
instead(AnalyticsUtils, 'trackNetworkAction', noop)
|
||||
|
||||
|
|
@ -119,8 +115,22 @@ registerPlugin(
|
|||
for (const key of Object.keys(handlers))
|
||||
instead(handlers, key, noop)
|
||||
},
|
||||
cachedOnly,
|
||||
)
|
||||
|
||||
cleanup(unsubAU)
|
||||
},
|
||||
start({
|
||||
cleanup,
|
||||
logger,
|
||||
unscoped: {
|
||||
discord: {
|
||||
common: {
|
||||
flux: { DispatcherModuleId },
|
||||
},
|
||||
},
|
||||
},
|
||||
}) {
|
||||
// modules/app_analytics/useTrackImpression.tsx
|
||||
const unsubTI = waitForModules(
|
||||
byProps<{
|
||||
|
|
@ -130,11 +140,10 @@ registerPlugin(
|
|||
useTrackImpression => {
|
||||
unsubTI()
|
||||
|
||||
logger.info('Patching useTrackImpression...')
|
||||
|
||||
instead(useTrackImpression, 'trackImpression', noop)
|
||||
instead(useTrackImpression, 'default', noop)
|
||||
},
|
||||
cachedOnly,
|
||||
)
|
||||
|
||||
// actions/AnalyticsTrackActionCreators.tsx
|
||||
|
|
@ -148,9 +157,10 @@ registerPlugin(
|
|||
instead(AnalyticsTrackActionCreators, 'track', noop)
|
||||
}
|
||||
},
|
||||
cachedOnly,
|
||||
)
|
||||
|
||||
cleanup(unsubAU, unsubTI, unsubATAC)
|
||||
cleanup(unsubTI, unsubATAC)
|
||||
},
|
||||
stop({ plugin }) {
|
||||
plugin.flags |= PluginFlags.ReloadRequired
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@ registerPlugin(
|
|||
},
|
||||
)
|
||||
},
|
||||
{
|
||||
cached: true,
|
||||
},
|
||||
)
|
||||
|
||||
cleanup(unsubEB)
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ const pluginSettings = registerPlugin(
|
|||
patchSettingsOverviewScreen(exports)
|
||||
},
|
||||
{
|
||||
cached: true,
|
||||
returnNamespace: true,
|
||||
},
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue