brick-module
Version:
Better React Native native module development
87 lines (85 loc) • 2.62 kB
JavaScript
import { NativeEventEmitter, TurboModuleRegistry } from "react-native";
//#region src/BrickModule.ts
const moduleCache = /* @__PURE__ */ new Map();
let nativeModule = null;
let eventEmitter = null;
/**
* Gets the native TurboModule instance
* @private
*/
function getNativeModule() {
if (!nativeModule) nativeModule = TurboModuleRegistry.getEnforcing("BrickModule");
return nativeModule;
}
function getEventEmitter() {
if (!eventEmitter) {
const nativeModuleInstance = getNativeModule();
eventEmitter = new NativeEventEmitter(nativeModuleInstance);
console.log("eventEmitter", eventEmitter);
}
return eventEmitter;
}
/**
* Gets a typed module instance by name with explicit type parameter
* @param moduleName - The exact name of the module as defined in its spec
* @returns Typed module interface with all methods, constants, and event listeners
*/
function get(moduleName) {
const cacheKey = moduleName;
if (moduleCache.has(cacheKey)) return moduleCache.get(cacheKey);
const nativeModuleInstance = getNativeModule();
const moduleProxy = new Proxy({}, {
get: (_target, property) => {
if (typeof property !== "string") return void 0;
if (property === "addEventListener") return (eventName, listener) => {
const emitter = getEventEmitter();
const subscription = emitter.addListener(`${moduleName}_${eventName}`, listener);
return () => {
subscription.remove();
};
};
const allConstants = nativeModuleInstance?.getConstants?.() ?? {};
const constantKey = `${moduleName}_${property}`;
if (constantKey in allConstants) return allConstants[constantKey];
return (...args) => {
const methodKey = `${moduleName}_${property}`;
if (typeof nativeModuleInstance[methodKey] === "function") return nativeModuleInstance[methodKey](...args);
throw new Error(`Method ${methodKey} not found`);
};
},
has: (_target, property) => {
return typeof property === "string";
},
ownKeys: (_target) => {
return [];
}
});
moduleCache.set(cacheKey, moduleProxy);
return moduleProxy;
}
/**
* Gets list of all registered modules
* @returns Promise resolving to array of module names
*/
function getRegisteredModules() {
const nativeModuleInstance = getNativeModule();
return nativeModuleInstance?.getRegisteredModules() ?? [];
}
/**
* Clears the module cache (useful for testing or hot reloading)
* @internal
*/
function clearCache() {
moduleCache.clear();
}
/**
* Main Brick Module API object
* Provides type-safe access to native modules
*/
const BrickModule = {
get,
getRegisteredModules,
clearCache
};
//#endregion
export { BrickModule as default };