1import React from 'react';
2import { findNodeHandle, NativeModules, requireNativeComponent } from 'react-native';
3import { requireNativeModule } from './requireNativeModule';
4// To make the transition from React Native's `requireNativeComponent` to Expo's
5// `requireNativeViewManager` as easy as possible, `requireNativeViewManager` is a drop-in
6// replacement for `requireNativeComponent`.
7//
8// For each view manager, we create a wrapper component that accepts all of the props available to
9// the author of the universal module. This wrapper component splits the props into two sets: props
10// passed to React Native's View (ex: style, testID) and custom view props, which are passed to the
11// adapter view component in a prop called `proxiedProperties`.
12/**
13 * A map that caches registered native components.
14 */
15const nativeComponentsCache = new Map();
16/**
17 * Requires a React Native component from cache if possible. This prevents
18 * "Tried to register two views with the same name" errors on fast refresh, but
19 * also when there are multiple versions of the same package with native component.
20 */
21function requireCachedNativeComponent(viewName) {
22    const cachedNativeComponent = nativeComponentsCache.get(viewName);
23    if (!cachedNativeComponent) {
24        const nativeComponent = requireNativeComponent(viewName);
25        nativeComponentsCache.set(viewName, nativeComponent);
26        return nativeComponent;
27    }
28    return cachedNativeComponent;
29}
30/**
31 * A drop-in replacement for `requireNativeComponent`.
32 */
33export function requireNativeViewManager(viewName) {
34    const { viewManagersMetadata } = NativeModules.NativeUnimoduleProxy;
35    const viewManagerConfig = viewManagersMetadata?.[viewName];
36    if (__DEV__ && !viewManagerConfig) {
37        const exportedViewManagerNames = Object.keys(viewManagersMetadata).join(', ');
38        console.warn(`The native view manager required by name (${viewName}) from NativeViewManagerAdapter isn't exported by expo-modules-core. Views of this type may not render correctly. Exported view managers: [${exportedViewManagerNames}].`);
39    }
40    // Set up the React Native native component, which is an adapter to the universal module's view
41    // manager
42    const reactNativeViewName = `ViewManagerAdapter_${viewName}`;
43    const ReactNativeComponent = requireCachedNativeComponent(reactNativeViewName);
44    class NativeComponent extends React.PureComponent {
45        static displayName = viewName;
46        // This will be accessed from native when the prototype functions are called,
47        // in order to find the associated native view.
48        nativeTag = null;
49        componentDidMount() {
50            this.nativeTag = findNodeHandle(this);
51        }
52        render() {
53            return React.createElement(ReactNativeComponent, { ...this.props });
54        }
55    }
56    try {
57        const nativeModule = requireNativeModule(viewName);
58        const nativeViewPrototype = nativeModule.ViewPrototype;
59        if (nativeViewPrototype) {
60            // Assign native view functions to the component prototype so they can be accessed from the ref.
61            Object.assign(NativeComponent.prototype, nativeViewPrototype);
62        }
63    }
64    catch {
65        // `requireNativeModule` may throw an error when the native module cannot be found.
66        // In some tests we don't mock the entire modules, but we do want to mock native views. For now,
67        // until we still have to support the legacy modules proxy and don't have better ways to mock,
68        // let's just gracefully skip assigning the prototype functions.
69        // See: https://github.com/expo/expo/blob/main/packages/expo-modules-core/src/__tests__/NativeViewManagerAdapter-test.native.tsx
70    }
71    return NativeComponent;
72}
73//# sourceMappingURL=NativeViewManagerAdapter.native.js.map