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 { lookupModule, lookupModules } from '@revenge-mod/modules/finders'
|
||||||
import { withDependencies } from '@revenge-mod/modules/finders/filters'
|
import { withDependencies } from '@revenge-mod/modules/finders/filters'
|
||||||
import { getModuleDependencies } from '@revenge-mod/modules/metro/utils'
|
|
||||||
import {
|
import {
|
||||||
ReactJSXRuntimeModuleId,
|
ReactJSXRuntimeModuleId,
|
||||||
ReactModuleId,
|
ReactModuleId,
|
||||||
|
|
@ -10,7 +9,7 @@ import { proxify } from '@revenge-mod/utils/proxy'
|
||||||
import { ImportTrackerModuleId } from './common/import-tracker'
|
import { ImportTrackerModuleId } from './common/import-tracker'
|
||||||
import type { DiscordModules } from './types'
|
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.
|
* 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)
|
// [3909, 4608, 5182, 13172, 2, ...] (141 dependencies)
|
||||||
const [, id] = lookupModule(
|
const [, id] = lookupModule(
|
||||||
withDependencies<Design>(
|
withDependencies<Design>(
|
||||||
loose([
|
atLeast(DesignMinimumDependencies, [
|
||||||
[ImportTrackerModuleId],
|
[ImportTrackerModuleId],
|
||||||
[ImportTrackerModuleId],
|
[ImportTrackerModuleId],
|
||||||
[ReactNativeModuleId, ImportTrackerModuleId],
|
[ReactNativeModuleId, ImportTrackerModuleId],
|
||||||
[ImportTrackerModuleId],
|
[ImportTrackerModuleId],
|
||||||
ImportTrackerModuleId,
|
ImportTrackerModuleId,
|
||||||
...Array<null>(DesignMinimumDependencies - 5).fill(null),
|
|
||||||
]),
|
]),
|
||||||
).keyAs('revenge.discord.design.Design'),
|
).keyAs('revenge.discord.design.Design'),
|
||||||
{
|
{
|
||||||
|
|
@ -55,9 +53,6 @@ export let Design: Design = proxify(
|
||||||
|
|
||||||
// design/components/Forms/native/FormSwitch.native.tsx
|
// design/components/Forms/native/FormSwitch.native.tsx
|
||||||
export let FormSwitch: DiscordModules.Components.FormSwitch = proxify(() => {
|
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(
|
for (const [, id] of lookupModules(
|
||||||
withDependencies(
|
withDependencies(
|
||||||
loose([
|
loose([
|
||||||
|
|
@ -66,17 +61,25 @@ export let FormSwitch: DiscordModules.Components.FormSwitch = proxify(() => {
|
||||||
ReactNativeModuleId,
|
ReactNativeModuleId,
|
||||||
ReactJSXRuntimeModuleId,
|
ReactJSXRuntimeModuleId,
|
||||||
]),
|
]),
|
||||||
).keyAs('revenge.discord.design.FormSwitch'),
|
)
|
||||||
|
.and(
|
||||||
|
withDependencies(
|
||||||
|
last([
|
||||||
|
relative(1),
|
||||||
|
relative(2),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
ImportTrackerModuleId,
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.keyAs('revenge.discord.design.FormSwitch'),
|
||||||
{
|
{
|
||||||
initialize: false,
|
initialize: false,
|
||||||
},
|
},
|
||||||
)) {
|
)) {
|
||||||
const deps = getModuleDependencies(id)!
|
const FormSwitch_ = __r(id)!.FormSwitch
|
||||||
if (deps.at(-1) !== ImportTrackerModuleId) continue
|
if (FormSwitch_) return (FormSwitch = FormSwitch_)
|
||||||
if (deps.at(-4) === id + 2 && deps.at(-5) === id + 1) {
|
|
||||||
const FormSwitch_ = __r(id)!.FormSwitch
|
|
||||||
if (FormSwitch_) return (FormSwitch = FormSwitch_)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})!
|
})!
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import {
|
||||||
withDependencies,
|
withDependencies,
|
||||||
withName,
|
withName,
|
||||||
} from '@revenge-mod/modules/finders/filters'
|
} from '@revenge-mod/modules/finders/filters'
|
||||||
import { getModuleDependencies } from '@revenge-mod/modules/metro/utils'
|
|
||||||
import { asap, noop } from '@revenge-mod/utils/callback'
|
import { asap, noop } from '@revenge-mod/utils/callback'
|
||||||
import {
|
import {
|
||||||
cache,
|
cache,
|
||||||
|
|
@ -75,14 +74,19 @@ export function getStore<T>(
|
||||||
]
|
]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const withLeadingFluxStoreDeps = withDependencies(
|
const { last, loose } = withDependencies
|
||||||
withDependencies.loose([
|
|
||||||
withName('_classCallCheck'),
|
// The import tracker is checked first, as it is far cheaper than resolving the leading dependencies' exports
|
||||||
withName('_createClass'),
|
const withFluxStoreDeps = withDependencies(last([ImportTrackerModuleId])).and(
|
||||||
withName('_possibleConstructorReturn'),
|
withDependencies(
|
||||||
withName('bound getPrototypeOf'),
|
loose([
|
||||||
withName('_inherits'),
|
withName('_classCallCheck'),
|
||||||
]),
|
withName('_createClass'),
|
||||||
|
withName('_possibleConstructorReturn'),
|
||||||
|
withName('bound getPrototypeOf'),
|
||||||
|
withName('_inherits'),
|
||||||
|
]),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
export type WithStore = FilterGenerator<
|
export type WithStore = FilterGenerator<
|
||||||
|
|
@ -102,9 +106,7 @@ export const withStore = createFilterGenerator(
|
||||||
(_, id, exports, initialized) => {
|
(_, id, exports, initialized) => {
|
||||||
if (initialized) return Boolean(exports?._dispatchToken)
|
if (initialized) return Boolean(exports?._dispatchToken)
|
||||||
|
|
||||||
if (!withLeadingFluxStoreDeps(id)) return false
|
return withFluxStoreDeps(id, undefined, false)
|
||||||
const deps = getModuleDependencies(id)!
|
|
||||||
return deps[deps.length - 1] === ImportTrackerModuleId
|
|
||||||
},
|
},
|
||||||
() => 'revenge.discord.store',
|
() => 'revenge.discord.store',
|
||||||
FilterScopes.Uninitialized | FilterScopes.Initialized,
|
FilterScopes.Uninitialized | FilterScopes.Initialized,
|
||||||
|
|
|
||||||
|
|
@ -7,39 +7,50 @@ import {
|
||||||
withDependencies,
|
withDependencies,
|
||||||
} from '@revenge-mod/modules/finders/filters'
|
} from '@revenge-mod/modules/finders/filters'
|
||||||
import { isModuleExportBad } from '@revenge-mod/modules/metro/utils'
|
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 { FilterScopes } from '../../modules/src/finders/filters/constants'
|
||||||
import type {
|
import type {
|
||||||
Filter,
|
Filter,
|
||||||
FilterGenerator,
|
FilterGenerator,
|
||||||
} from '@revenge-mod/modules/finders/filters'
|
} from '@revenge-mod/modules/finders/filters'
|
||||||
|
import type { Metro } from '@revenge-mod/modules/types'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
|
|
||||||
// [React, ReactJsxRuntime, (Tokens), (BaseIconImage), (Asset), ImportTracker]
|
const { last } = withDependencies
|
||||||
// Asset = relativeDep(1)
|
|
||||||
const IconComponentFilter = [
|
|
||||||
ReactModuleId,
|
|
||||||
ReactJSXRuntimeModuleId,
|
|
||||||
TokensModuleId,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
ImportTrackerModuleId,
|
|
||||||
]
|
|
||||||
|
|
||||||
// Generated IconComponents that have multiple assets, there is no specific length, so the filter has to be generated on-the-fly.
|
const depsFilters: Record<string, Filter> = {}
|
||||||
// [React, ReactNative, ReactJsxRuntime, (Tokens), (BaseIconImage), (...Assets), ImportTracker]
|
|
||||||
// ...Assets = relativeDep(1..n)
|
/**
|
||||||
const MultiIconComponentFilterBase = [
|
* Builds a dependency filter for an icon component.
|
||||||
ReactModuleId,
|
*
|
||||||
ReactNativeModuleId,
|
* `[React, (ReactNative), ReactJsxRuntime, Tokens, (BaseIconImage), (...Assets), ImportTracker]`
|
||||||
ReactJSXRuntimeModuleId,
|
*
|
||||||
TokensModuleId,
|
* `ReactNative` is only present on components with multiple assets, and it sits right after `React`,
|
||||||
null,
|
* 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<
|
export type WithGeneratedIconComponent = FilterGenerator<
|
||||||
<N extends string>(
|
<N extends string>(
|
||||||
|
|
@ -82,44 +93,11 @@ export type WithGeneratedIconComponent = FilterGenerator<
|
||||||
export const withGeneratedIconComponent = createFilterGenerator<
|
export const withGeneratedIconComponent = createFilterGenerator<
|
||||||
Parameters<WithGeneratedIconComponent>
|
Parameters<WithGeneratedIconComponent>
|
||||||
>(
|
>(
|
||||||
(names, id, exports) => {
|
(names, id, exports, initialized) => {
|
||||||
if (typeof exports === 'object' && isModuleExportBad(exports)) {
|
// Icon components always export their component, so unusable exports can never match
|
||||||
if (typeof exports[names[0]] === 'function')
|
if (initialized && isModuleExportBad(exports)) return false
|
||||||
return Object.keys(exports).length === 1
|
|
||||||
} else {
|
|
||||||
let filter = IconComponentFilter
|
|
||||||
|
|
||||||
if (names.length > 1) {
|
return depsFilterFor(names)?.(id, exports, initialized) ?? false
|
||||||
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
|
|
||||||
},
|
},
|
||||||
names => `revenge.utils.discord.generatedIconComponent(${names.join(',')})`,
|
names => `revenge.utils.discord.generatedIconComponent(${names.join(',')})`,
|
||||||
FilterScopes.Uninitialized | FilterScopes.Initialized,
|
FilterScopes.Uninitialized | FilterScopes.Initialized,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue