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