1d46e3a1aSTomasz Sapetaimport NativeModulesProxy from './NativeModulesProxy';
2d46e3a1aSTomasz Sapeta
31bed2683STomasz Sapetatype ExpoObject = {
41bed2683STomasz Sapeta  modules:
51bed2683STomasz Sapeta    | undefined
61bed2683STomasz Sapeta    | {
71bed2683STomasz Sapeta        [key: string]: any;
81bed2683STomasz Sapeta      };
9*6e021b28SWojciech Dróżdż  uuidv4: () => string;
101bed2683STomasz Sapeta};
111bed2683STomasz Sapeta
12d46e3a1aSTomasz Sapetadeclare global {
13d46e3a1aSTomasz Sapeta  // eslint-disable-next-line no-var
141bed2683STomasz Sapeta  var expo: ExpoObject | undefined;
151bed2683STomasz Sapeta
161bed2683STomasz Sapeta  /**
171bed2683STomasz Sapeta   * @deprecated `global.ExpoModules` is deprecated, use `global.expo.modules` instead.
181bed2683STomasz Sapeta   */
191bed2683STomasz Sapeta  // eslint-disable-next-line no-var
20d46e3a1aSTomasz Sapeta  var ExpoModules:
21d46e3a1aSTomasz Sapeta    | undefined
22d46e3a1aSTomasz Sapeta    | {
23d46e3a1aSTomasz Sapeta        [key: string]: any;
24d46e3a1aSTomasz Sapeta      };
25d46e3a1aSTomasz Sapeta}
26d46e3a1aSTomasz Sapeta
27d46e3a1aSTomasz Sapeta/**
28d46e3a1aSTomasz Sapeta * Imports the native module registered with given name. In the first place it tries to load
29d46e3a1aSTomasz Sapeta * the module installed through the JSI host object and then falls back to the bridge proxy module.
30d46e3a1aSTomasz Sapeta * Notice that the modules loaded from the proxy may not support some features like synchronous functions.
31d46e3a1aSTomasz Sapeta *
32d46e3a1aSTomasz Sapeta * @param moduleName Name of the requested native module.
33d46e3a1aSTomasz Sapeta * @returns Object representing the native module.
34d46e3a1aSTomasz Sapeta * @throws Error when there is no native module with given name.
35d46e3a1aSTomasz Sapeta */
36d46e3a1aSTomasz Sapetaexport function requireNativeModule<ModuleType = any>(moduleName: string): ModuleType {
375585864bSTomasz Sapeta  const nativeModule = requireOptionalNativeModule<ModuleType>(moduleName);
38d46e3a1aSTomasz Sapeta
39d46e3a1aSTomasz Sapeta  if (!nativeModule) {
40d46e3a1aSTomasz Sapeta    throw new Error(`Cannot find native module '${moduleName}'`);
41d46e3a1aSTomasz Sapeta  }
42d46e3a1aSTomasz Sapeta  return nativeModule;
43d46e3a1aSTomasz Sapeta}
445585864bSTomasz Sapeta
455585864bSTomasz Sapeta/**
465585864bSTomasz Sapeta * Imports the native module registered with the given name. The same as `requireNativeModule`,
475585864bSTomasz Sapeta * but returns `null` when the module cannot be found instead of throwing an error.
485585864bSTomasz Sapeta *
495585864bSTomasz Sapeta * @param moduleName Name of the requested native module.
505585864bSTomasz Sapeta * @returns Object representing the native module or `null` when it cannot be found.
515585864bSTomasz Sapeta */
525585864bSTomasz Sapetaexport function requireOptionalNativeModule<ModuleType = any>(
535585864bSTomasz Sapeta  moduleName: string
545585864bSTomasz Sapeta): ModuleType | null {
555585864bSTomasz Sapeta  return (
565585864bSTomasz Sapeta    globalThis.expo?.modules?.[moduleName] ??
575585864bSTomasz Sapeta    globalThis.ExpoModules?.[moduleName] ??
585585864bSTomasz Sapeta    NativeModulesProxy[moduleName] ??
595585864bSTomasz Sapeta    null
605585864bSTomasz Sapeta  );
615585864bSTomasz Sapeta}
62