2025-04-10 02:03:56 +07:00
|
|
|
import { getInitializedModuleExports, isBlacklisted, onAnyModuleInitialized, onModuleFinishedImporting } from '../metro'
|
2025-04-09 03:42:06 +07:00
|
|
|
import { runFilterReturnExports, type RunFilterReturnExportsOptions } from './_internal'
|
2025-03-30 23:32:17 +07:00
|
|
|
|
|
|
|
|
import type { MaybeDefaultExportMatched } from '.'
|
2025-04-05 23:35:01 +07:00
|
|
|
import type { Metro } from '../../types/metro'
|
2025-03-30 23:32:17 +07:00
|
|
|
import type { Filter, FilterResult } from './filters'
|
|
|
|
|
|
2025-04-09 03:42:06 +07:00
|
|
|
export type WaitForModulesOptions<ReturnNamespace extends boolean = boolean> =
|
|
|
|
|
RunFilterReturnExportsOptions<ReturnNamespace>
|
|
|
|
|
|
|
|
|
|
export type WaitForModulesResult<
|
|
|
|
|
F extends Filter,
|
|
|
|
|
O extends WaitForModulesOptions,
|
|
|
|
|
> = O extends RunFilterReturnExportsOptions<true> ? MaybeDefaultExportMatched<FilterResult<F>> : FilterResult<F>
|
2025-03-30 23:32:17 +07:00
|
|
|
|
|
|
|
|
/**
|
2025-04-09 04:10:41 +07:00
|
|
|
* Wait for modules to initialize. **Callback won't be called if the module is already initialized!**
|
2025-03-30 23:32:17 +07:00
|
|
|
*
|
|
|
|
|
* @param filter The filter to use.
|
|
|
|
|
* @param callback The callback to call when matching modules are initialized.
|
|
|
|
|
* @param options The options to use for the wait.
|
|
|
|
|
* @returns A function to unsubscribe.
|
|
|
|
|
*
|
|
|
|
|
* @example
|
|
|
|
|
* ```ts
|
2025-04-09 04:10:41 +07:00
|
|
|
* const unsub = waitForModules(
|
2025-03-30 23:32:17 +07:00
|
|
|
* byName<typeof import('@shopify/flash-list')>('FlashList'),
|
|
|
|
|
* // (exports: typeof import('@shopify/flash-list'), id: Metro.ModuleID) => any
|
2025-04-09 04:10:41 +07:00
|
|
|
* (id, exports) => {
|
|
|
|
|
* unsub()
|
|
|
|
|
* // Do something with the module...
|
|
|
|
|
* }
|
2025-03-30 23:32:17 +07:00
|
|
|
* )
|
|
|
|
|
* ```
|
|
|
|
|
*/
|
2025-04-05 20:52:09 +07:00
|
|
|
export function waitForModules<F extends Filter>(
|
2025-03-30 23:32:17 +07:00
|
|
|
filter: F,
|
2025-04-05 20:52:09 +07:00
|
|
|
callback: (id: Metro.ModuleID, exports: FilterResult<F>) => any,
|
2025-03-30 23:32:17 +07:00
|
|
|
): () => void
|
2025-04-05 20:52:09 +07:00
|
|
|
|
2025-04-09 03:42:06 +07:00
|
|
|
export function waitForModules<F extends Filter, O extends WaitForModulesOptions>(
|
2025-03-30 23:32:17 +07:00
|
|
|
filter: F,
|
2025-04-09 03:42:06 +07:00
|
|
|
callback: (id: Metro.ModuleID, exports: WaitForModulesResult<F, O>) => any,
|
2025-04-05 20:52:09 +07:00
|
|
|
options: O,
|
|
|
|
|
): () => void
|
|
|
|
|
|
|
|
|
|
export function waitForModules(
|
|
|
|
|
filter: Filter,
|
|
|
|
|
callback: (id: Metro.ModuleID, exports: Metro.ModuleExports) => any,
|
|
|
|
|
options?: WaitForModulesOptions,
|
2025-03-30 23:32:17 +07:00
|
|
|
) {
|
2025-04-05 20:52:09 +07:00
|
|
|
const unsub = onAnyModuleInitialized((id, exports) => {
|
2025-04-10 02:03:56 +07:00
|
|
|
if (isBlacklisted(id)) return
|
2025-04-05 20:52:09 +07:00
|
|
|
const result = runFilterReturnExports(filter, id, exports, options)
|
2025-04-10 02:03:56 +07:00
|
|
|
if (result != null) callback(id, exports)
|
2025-03-30 23:32:17 +07:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return unsub
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-04-09 04:10:41 +07:00
|
|
|
* Wait for a module to initialize by its imported path. Once callback is called, the subscription will be removed automatically.
|
|
|
|
|
*
|
|
|
|
|
* Think of it as if you are doing `import * as exports from path`, and you are also waiting for the app to initialize the module by itself.
|
2025-04-09 03:42:06 +07:00
|
|
|
*
|
2025-03-30 23:32:17 +07:00
|
|
|
* @param path The path to wait for.
|
|
|
|
|
* @param callback The callback to call once the module is initialized.
|
|
|
|
|
* @returns A function to unsubscribe.
|
2025-04-09 04:10:41 +07:00
|
|
|
*
|
|
|
|
|
* @example
|
|
|
|
|
* ```ts
|
|
|
|
|
* waitForModuleByImportedPath(
|
|
|
|
|
* 'utils/PlatformUtils.tsx',
|
|
|
|
|
* (id, exports) => {
|
|
|
|
|
* // Do something with the module...
|
|
|
|
|
* }
|
|
|
|
|
* )
|
|
|
|
|
* ```
|
2025-03-30 23:32:17 +07:00
|
|
|
*/
|
2025-04-05 20:52:09 +07:00
|
|
|
export function waitForModuleByImportedPath<T = any>(path: string, callback: (id: Metro.ModuleID, exports: T) => any) {
|
2025-03-30 23:32:17 +07:00
|
|
|
const unsub = onModuleFinishedImporting((id, cmpPath) => {
|
|
|
|
|
if (path === cmpPath) {
|
|
|
|
|
unsub()
|
2025-04-10 02:03:56 +07:00
|
|
|
callback(id, getInitializedModuleExports(id))
|
2025-03-30 23:32:17 +07:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return unsub
|
|
|
|
|
}
|