revenge-bundle-next/lib/modules/src/metro/subscriptions/index.ts

95 lines
3.3 KiB
TypeScript

import { _init, _initAll, _path, _req, _reqAll } from './_internal'
import type { Metro } from '../../types'
import type { initializedModuleHasBadExports } from '../utils'
export type ModuleFirstRequiredCallback = (id: Metro.ModuleID) => void
export type ModuleInitializedCallback = (id: Metro.ModuleID, exports: Metro.ModuleExports) => void
export type ModuleWithImportedPathInitializedCallback = (id: Metro.ModuleID, path: string) => void
/**
* Registers a callback to be called when any module is initialized.
* During this time, the module factory is not yet executed.
*
* @see {@link initializedModuleHasBadExports} to avoid bad module exports.
*
* @param callback The callback to be called.
* @returns A function that unregisters the callback.
*/
export function onAnyModuleInitialized(callback: ModuleInitializedCallback) {
_initAll.add(callback)
return () => _initAll.delete(callback)
}
/**
* Registers a callback to be called when a specific module is initialized.
*
* This runs after the module factory has been executed, but before the module is considered initialized by Metro.
* However, Revenge APIs will consider the module initialized at this poi
*
* @see {@link initializedModuleHasBadExports} to avoid bad module exports.
*
* @param id The ID of the module.
* @param callback The callback to be called.
* @returns A function that unregisters the callback.
*/
export function onModuleInitialized(id: Metro.ModuleID, callback: ModuleInitializedCallback) {
let set = _init.get(id)
if (!set) {
set = new Set()
_init.set(id, set)
}
set.add(callback)
return () => set.delete(callback)
}
/**
* Registers a callback to be called when a module with a specific import path is initialized.
*
* @see {@link initializedModuleHasBadExports} to avoid bad module exports.
*
* @param callback The callback to be called.
* @returns A function that unregisters the callback.
*/
export function onModuleFinishedImporting(callback: ModuleWithImportedPathInitializedCallback) {
_path.add(callback)
return () => _path.delete(callback)
}
/**
* Registers a callback to be called when any module is required the first time.
*
* This runs after the module factory has been executed, but before the module is considered initialized by Metro.
* However, Revenge APIs will consider the module initialized at this point.
*
* @see {@link initializedModuleHasBadExports} to avoid bad module exports.
*
* @param callback The callback to be called.
* @returns A function that unregisters the callback.
*/
export function onAnyModuleFirstRequired(callback: ModuleFirstRequiredCallback) {
_reqAll.add(callback)
return () => _reqAll.delete(callback)
}
/**
* Registers a callback to be called when a specific module is required the first time.
* During this time, the module factory is not yet executed.
*
* @see {@link initializedModuleHasBadExports} to avoid bad module exports.
*
* @param id The ID of the module.
* @param callback The callback to be called.
* @returns A function that unregisters the callback.
*/
export function onModuleFirstRequired(id: Metro.ModuleID, callback: ModuleFirstRequiredCallback) {
let set = _req.get(id)
if (!set) {
set = new Set()
_req.set(id, set)
}
set.add(callback)
return () => set.delete(callback)
}