fix(lib): migrate to new withDependencies APIs
This commit is contained in:
parent
d3fb84b76d
commit
ecb2cf810b
3 changed files with 71 additions and 88 deletions
|
|
@ -1,6 +1,5 @@
|
|||
import { lookupModule, lookupModules } from '@revenge-mod/modules/finders'
|
||||
import { withDependencies } from '@revenge-mod/modules/finders/filters'
|
||||
import { getModuleDependencies } from '@revenge-mod/modules/metro/utils'
|
||||
import {
|
||||
ReactJSXRuntimeModuleId,
|
||||
ReactModuleId,
|
||||
|
|
@ -10,7 +9,7 @@ import { proxify } from '@revenge-mod/utils/proxy'
|
|||
import { ImportTrackerModuleId } from './common/import-tracker'
|
||||
import type { DiscordModules } from './types'
|
||||
|
||||
const { loose } = withDependencies
|
||||
const { atLeast, last, loose, relative } = withDependencies
|
||||
|
||||
/**
|
||||
* The lowest amount of dependencies `design/native.tsx` is expected to have.
|
||||
|
|
@ -29,13 +28,12 @@ export let Design: Design = proxify(
|
|||
// [3909, 4608, 5182, 13172, 2, ...] (141 dependencies)
|
||||
const [, id] = lookupModule(
|
||||
withDependencies<Design>(
|
||||
loose([
|
||||
atLeast(DesignMinimumDependencies, [
|
||||
[ImportTrackerModuleId],
|
||||
[ImportTrackerModuleId],
|
||||
[ReactNativeModuleId, ImportTrackerModuleId],
|
||||
[ImportTrackerModuleId],
|
||||
ImportTrackerModuleId,
|
||||
...Array<null>(DesignMinimumDependencies - 5).fill(null),
|
||||
]),
|
||||
).keyAs('revenge.discord.design.Design'),
|
||||
{
|
||||
|
|
@ -55,9 +53,6 @@ export let Design: Design = proxify(
|
|||
|
||||
// design/components/Forms/native/FormSwitch.native.tsx
|
||||
export let FormSwitch: DiscordModules.Components.FormSwitch = proxify(() => {
|
||||
// TODO: Possibly come up with a better dependency fingerprinting API
|
||||
// to not have to deal with this bullshit
|
||||
|
||||
for (const [, id] of lookupModules(
|
||||
withDependencies(
|
||||
loose([
|
||||
|
|
@ -66,17 +61,25 @@ export let FormSwitch: DiscordModules.Components.FormSwitch = proxify(() => {
|
|||
ReactNativeModuleId,
|
||||
ReactJSXRuntimeModuleId,
|
||||
]),
|
||||
).keyAs('revenge.discord.design.FormSwitch'),
|
||||
)
|
||||
.and(
|
||||
withDependencies(
|
||||
last([
|
||||
relative(1),
|
||||
relative(2),
|
||||
null,
|
||||
null,
|
||||
ImportTrackerModuleId,
|
||||
]),
|
||||
),
|
||||
)
|
||||
.keyAs('revenge.discord.design.FormSwitch'),
|
||||
{
|
||||
initialize: false,
|
||||
},
|
||||
)) {
|
||||
const deps = getModuleDependencies(id)!
|
||||
if (deps.at(-1) !== ImportTrackerModuleId) continue
|
||||
if (deps.at(-4) === id + 2 && deps.at(-5) === id + 1) {
|
||||
const FormSwitch_ = __r(id)!.FormSwitch
|
||||
if (FormSwitch_) return (FormSwitch = FormSwitch_)
|
||||
}
|
||||
const FormSwitch_ = __r(id)!.FormSwitch
|
||||
if (FormSwitch_) return (FormSwitch = FormSwitch_)
|
||||
}
|
||||
})!
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import {
|
|||
withDependencies,
|
||||
withName,
|
||||
} from '@revenge-mod/modules/finders/filters'
|
||||
import { getModuleDependencies } from '@revenge-mod/modules/metro/utils'
|
||||
import { asap, noop } from '@revenge-mod/utils/callback'
|
||||
import {
|
||||
cache,
|
||||
|
|
@ -75,14 +74,19 @@ export function getStore<T>(
|
|||
]
|
||||
*/
|
||||
|
||||
const withLeadingFluxStoreDeps = withDependencies(
|
||||
withDependencies.loose([
|
||||
withName('_classCallCheck'),
|
||||
withName('_createClass'),
|
||||
withName('_possibleConstructorReturn'),
|
||||
withName('bound getPrototypeOf'),
|
||||
withName('_inherits'),
|
||||
]),
|
||||
const { last, loose } = withDependencies
|
||||
|
||||
// The import tracker is checked first, as it is far cheaper than resolving the leading dependencies' exports
|
||||
const withFluxStoreDeps = withDependencies(last([ImportTrackerModuleId])).and(
|
||||
withDependencies(
|
||||
loose([
|
||||
withName('_classCallCheck'),
|
||||
withName('_createClass'),
|
||||
withName('_possibleConstructorReturn'),
|
||||
withName('bound getPrototypeOf'),
|
||||
withName('_inherits'),
|
||||
]),
|
||||
),
|
||||
)
|
||||
|
||||
export type WithStore = FilterGenerator<
|
||||
|
|
@ -102,9 +106,7 @@ export const withStore = createFilterGenerator(
|
|||
(_, id, exports, initialized) => {
|
||||
if (initialized) return Boolean(exports?._dispatchToken)
|
||||
|
||||
if (!withLeadingFluxStoreDeps(id)) return false
|
||||
const deps = getModuleDependencies(id)!
|
||||
return deps[deps.length - 1] === ImportTrackerModuleId
|
||||
return withFluxStoreDeps(id, undefined, false)
|
||||
},
|
||||
() => 'revenge.discord.store',
|
||||
FilterScopes.Uninitialized | FilterScopes.Initialized,
|
||||
|
|
|
|||
|
|
@ -7,39 +7,50 @@ import {
|
|||
withDependencies,
|
||||
} from '@revenge-mod/modules/finders/filters'
|
||||
import { isModuleExportBad } from '@revenge-mod/modules/metro/utils'
|
||||
import {
|
||||
ReactJSXRuntimeModuleId,
|
||||
ReactModuleId,
|
||||
ReactNativeModuleId,
|
||||
} from '@revenge-mod/react'
|
||||
import { FilterScopes } from '../../modules/src/finders/filters/constants'
|
||||
import type {
|
||||
Filter,
|
||||
FilterGenerator,
|
||||
} from '@revenge-mod/modules/finders/filters'
|
||||
import type { Metro } from '@revenge-mod/modules/types'
|
||||
import type { FC } from 'react'
|
||||
|
||||
// [React, ReactJsxRuntime, (Tokens), (BaseIconImage), (Asset), ImportTracker]
|
||||
// Asset = relativeDep(1)
|
||||
const IconComponentFilter = [
|
||||
ReactModuleId,
|
||||
ReactJSXRuntimeModuleId,
|
||||
TokensModuleId,
|
||||
null,
|
||||
null,
|
||||
ImportTrackerModuleId,
|
||||
]
|
||||
const { last } = withDependencies
|
||||
|
||||
// Generated IconComponents that have multiple assets, there is no specific length, so the filter has to be generated on-the-fly.
|
||||
// [React, ReactNative, ReactJsxRuntime, (Tokens), (BaseIconImage), (...Assets), ImportTracker]
|
||||
// ...Assets = relativeDep(1..n)
|
||||
const MultiIconComponentFilterBase = [
|
||||
ReactModuleId,
|
||||
ReactNativeModuleId,
|
||||
ReactJSXRuntimeModuleId,
|
||||
TokensModuleId,
|
||||
null,
|
||||
]
|
||||
const depsFilters: Record<string, Filter> = {}
|
||||
|
||||
/**
|
||||
* Builds a dependency filter for an icon component.
|
||||
*
|
||||
* `[React, (ReactNative), ReactJsxRuntime, Tokens, (BaseIconImage), (...Assets), ImportTracker]`
|
||||
*
|
||||
* `ReactNative` is only present on components with multiple assets, and it sits right after `React`,
|
||||
* so everything from `ReactJsxRuntime` onwards is at a fixed distance from the end on both shapes.
|
||||
*
|
||||
* @param names The component name, then the asset names if the component has multiple assets.
|
||||
* @returns The filter, or `undefined` if any of the assets aren't registered yet.
|
||||
*/
|
||||
function depsFilterFor(names: string[]) {
|
||||
const key = names.join(',')
|
||||
const cached = depsFilters[key]
|
||||
if (cached) return cached
|
||||
|
||||
// Components with multiple assets are named separately from their assets
|
||||
const assets = names.length > 1 ? names.slice(1) : names
|
||||
const mids: Metro.ModuleID[] = []
|
||||
|
||||
for (const name of assets) {
|
||||
const mid = getAssetByName(name)?.moduleId
|
||||
// Module ID can never be zero, so if it's falsy, it means the asset was not found.
|
||||
if (!mid) return
|
||||
|
||||
mids.push(mid)
|
||||
}
|
||||
|
||||
return (depsFilters[key] = withDependencies(
|
||||
last([TokensModuleId, null, ...mids, ImportTrackerModuleId]),
|
||||
))
|
||||
}
|
||||
|
||||
export type WithGeneratedIconComponent = FilterGenerator<
|
||||
<N extends string>(
|
||||
|
|
@ -82,44 +93,11 @@ export type WithGeneratedIconComponent = FilterGenerator<
|
|||
export const withGeneratedIconComponent = createFilterGenerator<
|
||||
Parameters<WithGeneratedIconComponent>
|
||||
>(
|
||||
(names, id, exports) => {
|
||||
if (typeof exports === 'object' && isModuleExportBad(exports)) {
|
||||
if (typeof exports[names[0]] === 'function')
|
||||
return Object.keys(exports).length === 1
|
||||
} else {
|
||||
let filter = IconComponentFilter
|
||||
(names, id, exports, initialized) => {
|
||||
// Icon components always export their component, so unusable exports can never match
|
||||
if (initialized && isModuleExportBad(exports)) return false
|
||||
|
||||
if (names.length > 1) {
|
||||
const mids = []
|
||||
|
||||
for (let i = 1; i < names.length; i++) {
|
||||
const name = names[i]
|
||||
const mid = getAssetByName(name)?.moduleId
|
||||
// Module ID can never be zero, so if it's falsy, it means the asset was not found.
|
||||
if (!mid) return false
|
||||
|
||||
mids.push(mid)
|
||||
}
|
||||
|
||||
filter = [
|
||||
...MultiIconComponentFilterBase,
|
||||
...mids,
|
||||
ImportTrackerModuleId,
|
||||
]
|
||||
} else {
|
||||
const [name] = names
|
||||
|
||||
const mid = getAssetByName(name)?.moduleId
|
||||
// Module ID can never be zero, so if it's falsy, it means the asset was not found.
|
||||
if (!mid) return false
|
||||
|
||||
IconComponentFilter[4] = mid
|
||||
}
|
||||
|
||||
return withDependencies(filter)(id, exports)
|
||||
}
|
||||
|
||||
return false
|
||||
return depsFilterFor(names)?.(id, exports, initialized) ?? false
|
||||
},
|
||||
names => `revenge.utils.discord.generatedIconComponent(${names.join(',')})`,
|
||||
FilterScopes.Uninitialized | FilterScopes.Initialized,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue