diff --git a/lib/assets/src/_internal.ts b/lib/assets/src/_internal.ts index a5aa416..3b8c694 100644 --- a/lib/assets/src/_internal.ts +++ b/lib/assets/src/_internal.ts @@ -1,4 +1,9 @@ -import type { Asset, CustomAsset } from './types' +import type { + Asset, + CustomAsset, + OnAssetsRegistryInitializedCallback, +} from './types' export const aCustoms = new Set() export const aOverrides = new WeakMap() +export const aCallbacks = new Set() diff --git a/lib/assets/src/index.ts b/lib/assets/src/index.ts index 5a53c7d..bbd165a 100644 --- a/lib/assets/src/index.ts +++ b/lib/assets/src/index.ts @@ -1,11 +1,13 @@ +import { noop } from '@revenge-mod/utils/callback' import { Platform } from 'react-native' -import { aCustoms, aOverrides } from './_internal' +import { aCallbacks, aCustoms, aOverrides } from './_internal' import { cache } from './caches' -import { AssetsRegistry } from './preinit' +import { AssetsRegistry, AssetsRegistryModuleId } from './preinit' import type { Asset, AssetId, CustomAsset, + OnAssetsRegistryInitializedCallback, PackagerAsset, RegisterableAsset, } from './types' @@ -18,6 +20,35 @@ export { // iOS cannot display SVGs let _preferredType: Asset['type'] = Platform.OS === 'ios' ? 'png' : 'svg' +/** + * Returns whether assets-registry is initialized. + */ +export function isAssetsRegistryInitialized() { + return AssetsRegistryModuleId >= 0 +} + +/** + * Registers a callback to be called when the assets registry is initialized. + * + * If the assets registry is already initialized, the callback will be called immediately. + * + * @param callback The callback to be called when the assets registry is initialized. + * @returns A function to remove the callback. + */ +export function onAssetsRegistryInitialized( + callback: OnAssetsRegistryInitializedCallback, +) { + if (isAssetsRegistryInitialized()) { + callback() + return noop + } + + aCallbacks.add(callback) + return () => { + aCallbacks.delete(callback) + } +} + /** * Set the preferred asset type. This is used to determine which asset to use when multiple types are available. * diff --git a/lib/assets/src/preinit.ts b/lib/assets/src/preinit.ts index 94b3b51..c8b5b3b 100644 --- a/lib/assets/src/preinit.ts +++ b/lib/assets/src/preinit.ts @@ -2,7 +2,7 @@ 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 { aOverrides } from './_internal' +import { aCallbacks, aOverrides } from './_internal' import { cacheAsset, cached } from './caches' import type { ReactNative } from '@revenge-mod/react/types' import type { Asset, PackagerAsset } from './types' @@ -17,6 +17,13 @@ const unsubAR = waitForModules( AssetsRegistryModuleId = id AssetsRegistry = exports as ReactNative.AssetsRegistry + for (const cb of aCallbacks) + try { + cb() + } catch {} + + aCallbacks.clear() + // There are two matching exports. One is the original, and one is a re-export. // The original asset-registry is simply required by the re-exported one with no changes. diff --git a/lib/assets/src/types.ts b/lib/assets/src/types.ts index 12c2b74..4d01ce3 100644 --- a/lib/assets/src/types.ts +++ b/lib/assets/src/types.ts @@ -13,6 +13,8 @@ export interface CustomAsset export type RegisterableAsset = Omit +export type OnAssetsRegistryInitializedCallback = () => void + declare module '@revenge-mod/react/types' { export namespace ReactNative { export namespace AssetsRegistry {