expo-modules-core 1.2.7 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/CHANGELOG.md +28 -5
  2. package/ExpoModulesCore.podspec +1 -0
  3. package/README.md +1 -1
  4. package/android/ExpoModulesCorePlugin.gradle +16 -0
  5. package/android/build.gradle +3 -2
  6. package/android/src/main/cpp/Exceptions.cpp +8 -0
  7. package/android/src/main/cpp/Exceptions.h +11 -0
  8. package/android/src/main/cpp/ExpoModulesHostObject.cpp +22 -5
  9. package/android/src/main/cpp/ExpoModulesHostObject.h +5 -0
  10. package/android/src/main/cpp/JNIInjector.cpp +2 -0
  11. package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +25 -1
  12. package/android/src/main/cpp/JSIInteropModuleRegistry.h +14 -0
  13. package/android/src/main/cpp/JSIObjectWrapper.h +15 -4
  14. package/android/src/main/cpp/JSITypeConverter.h +3 -2
  15. package/android/src/main/cpp/JavaReferencesCache.cpp +2 -0
  16. package/android/src/main/cpp/JavaScriptFunction.cpp +56 -0
  17. package/android/src/main/cpp/JavaScriptFunction.h +54 -0
  18. package/android/src/main/cpp/JavaScriptModuleObject.cpp +225 -105
  19. package/android/src/main/cpp/JavaScriptModuleObject.h +67 -34
  20. package/android/src/main/cpp/JavaScriptObject.cpp +55 -1
  21. package/android/src/main/cpp/JavaScriptObject.h +17 -13
  22. package/android/src/main/cpp/JavaScriptRuntime.cpp +12 -3
  23. package/android/src/main/cpp/JavaScriptRuntime.h +9 -1
  24. package/android/src/main/cpp/JavaScriptValue.cpp +9 -0
  25. package/android/src/main/cpp/JavaScriptValue.h +4 -0
  26. package/android/src/main/cpp/MethodMetadata.cpp +66 -87
  27. package/android/src/main/cpp/MethodMetadata.h +18 -16
  28. package/android/src/main/cpp/ObjectDeallocator.h +25 -0
  29. package/android/src/main/cpp/WeakRuntimeHolder.cpp +7 -0
  30. package/android/src/main/cpp/WeakRuntimeHolder.h +4 -0
  31. package/android/src/main/cpp/types/CppType.h +4 -1
  32. package/android/src/main/cpp/types/FrontendConverter.cpp +58 -0
  33. package/android/src/main/cpp/types/FrontendConverter.h +45 -0
  34. package/android/src/main/cpp/types/FrontendConverterProvider.cpp +3 -0
  35. package/android/src/main/cpp/types/JNIToJSIConverter.cpp +88 -0
  36. package/android/src/main/cpp/types/JNIToJSIConverter.h +22 -0
  37. package/android/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMapHelper.kt +10 -0
  38. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +8 -25
  39. package/android/src/main/java/expo/modules/kotlin/FilteredIterator.kt +37 -0
  40. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +1 -1
  41. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +30 -23
  42. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +0 -3
  43. package/android/src/main/java/expo/modules/kotlin/Utils.kt +21 -0
  44. package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +21 -1
  45. package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +112 -0
  46. package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassDefinitionData.kt +10 -0
  47. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +21 -0
  48. package/android/src/main/java/expo/modules/kotlin/exception/CommonExceptions.kt +15 -0
  49. package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +17 -3
  50. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +38 -8
  51. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +3 -2
  52. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +3 -2
  53. package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +1 -0
  54. package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +18 -11
  55. package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +4 -1
  56. package/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt +73 -0
  57. package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +28 -2
  58. package/android/src/main/java/expo/modules/kotlin/jni/JavaCallback.kt +8 -1
  59. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptFunction.kt +48 -0
  60. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +40 -3
  61. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +23 -3
  62. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +26 -1
  63. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +0 -11
  64. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +26 -16
  65. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +3 -1
  66. package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObject.kt +12 -0
  67. package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +62 -0
  68. package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectTypeConverter.kt +27 -0
  69. package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +2 -1
  70. package/android/src/main/java/expo/modules/kotlin/types/EitherTypeConverter.kt +7 -6
  71. package/android/src/main/java/expo/modules/kotlin/types/JavaScriptFunctionTypeConverter.kt +22 -0
  72. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +30 -24
  73. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +45 -1
  74. package/android/src/main/java/expo/modules/kotlin/types/TypedArrayTypeConverter.kt +3 -2
  75. package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +3 -1
  76. package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +3 -3
  77. package/android/src/main/java/expo/modules/kotlin/views/FilteredReadableMap.kt +53 -0
  78. package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +25 -5
  79. package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +25 -5
  80. package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +161 -10
  81. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -67
  82. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +6 -7
  83. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +40 -3
  84. package/android/src/main/java/expo/modules/kotlin/views/ViewTypeConverter.kt +44 -0
  85. package/android-annotation/build.gradle +45 -0
  86. package/android-annotation/src/main/java/expo/modules/annotation/Config.kt +7 -0
  87. package/android-annotation/src/main/java/expo/modules/annotation/ConverterBinder.kt +7 -0
  88. package/android-annotation-processor/build.gradle +51 -0
  89. package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessor.kt +175 -0
  90. package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessorProvider.kt +10 -0
  91. package/android-annotation-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +1 -0
  92. package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
  93. package/build/NativeViewManagerAdapter.native.js +36 -23
  94. package/build/NativeViewManagerAdapter.native.js.map +1 -1
  95. package/build/requireNativeModule.js +2 -2
  96. package/build/requireNativeModule.js.map +1 -1
  97. package/common/cpp/fabric/ExpoViewProps.cpp +18 -3
  98. package/common/cpp/fabric/ExpoViewProps.h +4 -1
  99. package/ios/Fabric/ExpoFabricView.swift +10 -10
  100. package/ios/Fabric/ExpoFabricViewObjC.h +2 -0
  101. package/ios/Fabric/ExpoFabricViewObjC.mm +17 -2
  102. package/ios/JSI/EXJSIInstaller.mm +1 -1
  103. package/ios/JSI/EXJSIUtils.h +5 -0
  104. package/ios/JSI/EXJSIUtils.mm +17 -0
  105. package/ios/JSI/EXJavaScriptRuntime.h +5 -0
  106. package/ios/JSI/EXJavaScriptRuntime.mm +6 -0
  107. package/ios/JSI/EXJavaScriptValue.h +2 -0
  108. package/ios/JSI/EXJavaScriptValue.mm +8 -0
  109. package/ios/JSI/EXJavaScriptWeakObject.mm +29 -8
  110. package/ios/JSI/EXRawJavaScriptFunction.h +24 -0
  111. package/ios/JSI/EXRawJavaScriptFunction.mm +52 -0
  112. package/ios/JSI/ExpoModulesHostObject.mm +1 -1
  113. package/ios/JSI/JavaScriptValue.swift +28 -1
  114. package/ios/ModuleRegistry/EXModuleRegistry.h +0 -4
  115. package/ios/ModuleRegistry/EXModuleRegistry.m +0 -23
  116. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -16
  117. package/ios/ModuleRegistryProvider/EXModuleRegistryProvider.m +0 -6
  118. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +1 -31
  119. package/ios/Swift/AppContext.swift +46 -6
  120. package/ios/Swift/Arguments/Convertible.swift +3 -3
  121. package/ios/Swift/Arguments/Convertibles.swift +5 -5
  122. package/ios/Swift/Classes/ClassComponent.swift +18 -12
  123. package/ios/Swift/Classes/ClassRegistry.swift +31 -0
  124. package/ios/Swift/Conversions.swift +19 -3
  125. package/ios/Swift/Convertibles/Convertibles+Color.swift +3 -3
  126. package/ios/Swift/Convertibles/Either.swift +6 -4
  127. package/ios/Swift/DynamicTypes/AnyDynamicType.swift +18 -2
  128. package/ios/Swift/DynamicTypes/DynamicArrayType.swift +3 -3
  129. package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +2 -2
  130. package/ios/Swift/DynamicTypes/DynamicEnumType.swift +1 -1
  131. package/ios/Swift/DynamicTypes/DynamicJavaScriptType.swift +27 -0
  132. package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +9 -2
  133. package/ios/Swift/DynamicTypes/DynamicRawType.swift +1 -1
  134. package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +16 -2
  135. package/ios/Swift/DynamicTypes/DynamicType.swift +6 -0
  136. package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +15 -4
  137. package/ios/Swift/DynamicTypes/DynamicViewType.swift +68 -0
  138. package/ios/Swift/ExpoBridgeModule.swift +1 -1
  139. package/ios/Swift/Functions/AnyFunction.swift +5 -4
  140. package/ios/Swift/Functions/AsyncFunctionComponent.swift +22 -19
  141. package/ios/Swift/Functions/ConcurrentFunctionDefinition.swift +29 -13
  142. package/ios/Swift/Functions/SyncFunctionComponent.swift +26 -15
  143. package/ios/Swift/JavaScriptFunction.swift +68 -0
  144. package/ios/Swift/JavaScriptUtils.swift +57 -18
  145. package/ios/Swift/ModuleHolder.swift +22 -10
  146. package/ios/Swift/Modules/ModuleDefinition.swift +8 -2
  147. package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +8 -8
  148. package/ios/Swift/Objects/ObjectDefinition.swift +17 -15
  149. package/ios/Swift/Objects/PropertyComponent.swift +23 -17
  150. package/ios/Swift/Records/AnyField.swift +1 -1
  151. package/ios/Swift/Records/Field.swift +2 -2
  152. package/ios/Swift/Records/Record.swift +5 -5
  153. package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +4 -0
  154. package/ios/Swift/Views/AnyViewProp.swift +1 -1
  155. package/ios/Swift/Views/ComponentData.swift +37 -2
  156. package/ios/Swift/Views/ConcreteViewProp.swift +2 -2
  157. package/ios/Swift/Views/ViewDefinition.swift +39 -0
  158. package/ios/Swift/Views/ViewModuleWrapper.swift +0 -29
  159. package/ios/Tests/ClassComponentSpec.swift +39 -27
  160. package/ios/Tests/ConvertiblesSpec.swift +75 -49
  161. package/ios/Tests/DynamicTypeSpec.swift +29 -27
  162. package/ios/Tests/EitherSpec.swift +9 -7
  163. package/ios/Tests/ExpoModulesSpec.swift +13 -13
  164. package/ios/Tests/FunctionSpec.swift +38 -22
  165. package/ios/Tests/JavaScriptRuntimeSpec.swift +4 -0
  166. package/ios/Tests/PropertyComponentSpec.swift +33 -30
  167. package/ios/Tests/RecordSpec.swift +7 -5
  168. package/ios/Tests/SharedObjectRegistrySpec.swift +12 -12
  169. package/ios/Tests/TypedArraysSpec.swift +1 -1
  170. package/ios/Tests/ViewDefinitionSpec.swift +4 -2
  171. package/package.json +2 -2
  172. package/src/NativeViewManagerAdapter.native.tsx +33 -29
  173. package/src/requireNativeModule.ts +2 -2
  174. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -132
  175. package/ios/EXViewManager.h +0 -21
  176. package/ios/EXViewManager.m +0 -128
  177. package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.h +0 -17
  178. package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.m +0 -67
  179. package/ios/ViewManagerAdapter/EXViewManagerAdapter.h +0 -17
  180. package/ios/ViewManagerAdapter/EXViewManagerAdapter.m +0 -45
@@ -7,7 +7,7 @@ import ExpoModulesTestCore
7
7
  final class SharedObjectRegistrySpec: ExpoSpec {
8
8
  override func spec() {
9
9
  let appContext = AppContext.create()
10
- let runtime = appContext.runtime
10
+ let runtime = try! appContext.runtime
11
11
 
12
12
  describe("pullNextId") {
13
13
  it("returns nextId") {
@@ -29,28 +29,28 @@ final class SharedObjectRegistrySpec: ExpoSpec {
29
29
  describe("add") {
30
30
  it("adds using nextId") {
31
31
  let nextId = SharedObjectRegistry.nextId
32
- let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime!.createObject())
32
+ let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime.createObject())
33
33
  expect(nextId) == id
34
34
  }
35
35
  it("is increasing size") {
36
36
  let size = SharedObjectRegistry.size
37
- SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime!.createObject())
37
+ SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime.createObject())
38
38
  expect(SharedObjectRegistry.size) == size + 1
39
39
  }
40
40
  it("assigns id on native object") {
41
41
  let nativeObject = TestSharedObject()
42
- let id = SharedObjectRegistry.add(native: nativeObject, javaScript: runtime!.createObject())
42
+ let id = SharedObjectRegistry.add(native: nativeObject, javaScript: runtime.createObject())
43
43
  expect(nativeObject.sharedObjectId) == id
44
44
  }
45
45
  it("assigns id on JS object") {
46
- let jsObject = runtime!.createObject()
46
+ let jsObject = runtime.createObject()
47
47
  let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: jsObject)
48
48
  expect(jsObject.hasProperty(sharedObjectIdPropertyName)) == true
49
49
  expect(try! jsObject.getProperty(sharedObjectIdPropertyName).asInt()) == id
50
50
  }
51
51
  it("saves objects pair") {
52
52
  let nativeObject = TestSharedObject()
53
- let jsObject = runtime!.createObject()
53
+ let jsObject = runtime.createObject()
54
54
  let id = SharedObjectRegistry.add(native: nativeObject, javaScript: jsObject)
55
55
  let pair = SharedObjectRegistry.get(id)
56
56
  expect(pair?.native) === nativeObject
@@ -60,18 +60,18 @@ final class SharedObjectRegistrySpec: ExpoSpec {
60
60
 
61
61
  describe("delete") {
62
62
  it("deletes objects pair") {
63
- let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime!.createObject())
63
+ let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: runtime.createObject())
64
64
  SharedObjectRegistry.delete(id)
65
65
  expect(SharedObjectRegistry.get(id)).to(beNil())
66
66
  }
67
67
  it("resets id on native object") {
68
68
  let nativeObject = TestSharedObject()
69
- let id = SharedObjectRegistry.add(native: nativeObject, javaScript: runtime!.createObject())
69
+ let id = SharedObjectRegistry.add(native: nativeObject, javaScript: runtime.createObject())
70
70
  SharedObjectRegistry.delete(id)
71
71
  expect(nativeObject.sharedObjectId) == 0
72
72
  }
73
73
  it("resets id on JS object") {
74
- let jsObject = runtime!.createObject()
74
+ let jsObject = runtime.createObject()
75
75
  let id = SharedObjectRegistry.add(native: TestSharedObject(), javaScript: jsObject)
76
76
  SharedObjectRegistry.delete(id)
77
77
  expect(try! jsObject.getProperty(sharedObjectIdPropertyName).asInt()) == 0
@@ -81,12 +81,12 @@ final class SharedObjectRegistrySpec: ExpoSpec {
81
81
  describe("toNativeObject") {
82
82
  it("returns native object") {
83
83
  let nativeObject = TestSharedObject()
84
- let jsObject = runtime!.createObject()
84
+ let jsObject = runtime.createObject()
85
85
  SharedObjectRegistry.add(native: nativeObject, javaScript: jsObject)
86
86
  expect(SharedObjectRegistry.toNativeObject(jsObject)) === nativeObject
87
87
  }
88
88
  it("returns nil") {
89
- let jsObject = runtime!.createObject()
89
+ let jsObject = runtime.createObject()
90
90
  expect(SharedObjectRegistry.toNativeObject(jsObject)).to(beNil())
91
91
  }
92
92
  }
@@ -94,7 +94,7 @@ final class SharedObjectRegistrySpec: ExpoSpec {
94
94
  describe("toJavaScriptObject") {
95
95
  it("returns JS object") {
96
96
  let nativeObject = TestSharedObject()
97
- let jsObject = runtime!.createObject()
97
+ let jsObject = runtime.createObject()
98
98
  SharedObjectRegistry.add(native: nativeObject, javaScript: jsObject)
99
99
  expect(SharedObjectRegistry.toJavaScriptObject(nativeObject)) == jsObject
100
100
  }
@@ -8,7 +8,7 @@ final class TypedArraysSpec: ExpoSpec {
8
8
  override func spec() {
9
9
  describe("module") {
10
10
  let appContext = AppContext.create()
11
- let runtime = appContext.runtime!
11
+ let runtime = try! appContext.runtime
12
12
 
13
13
  beforeSuite {
14
14
  appContext.moduleRegistry.register(moduleType: TypedArraysModule.self)
@@ -15,6 +15,8 @@ final class ViewDefinitionSpec: ExpoSpec {
15
15
  }
16
16
 
17
17
  describe("Prop") {
18
+ let appContext = AppContext.create()
19
+
18
20
  it("sets the prop") {
19
21
  let textView = UITextView()
20
22
  let content = "hello"
@@ -23,7 +25,7 @@ final class ViewDefinitionSpec: ExpoSpec {
23
25
  view.text = value
24
26
  }
25
27
  }
26
- try definition.propsDict()["content"]?.set(value: content, onView: textView)
28
+ try definition.propsDict()["content"]?.set(value: content, onView: textView, appContext: appContext)
27
29
  expect(textView.text) == content
28
30
  }
29
31
 
@@ -36,7 +38,7 @@ final class ViewDefinitionSpec: ExpoSpec {
36
38
  expect(view).to(beAKindOf(UITextView.self))
37
39
  }
38
40
  }
39
- try definition.propsDict()["content"]?.set(value: content, onView: textView)
41
+ try definition.propsDict()["content"]?.set(value: content, onView: textView, appContext: appContext)
40
42
  }
41
43
  }
42
44
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-core",
3
- "version": "1.2.7",
3
+ "version": "1.3.0",
4
4
  "description": "The core of Expo Modules architecture",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -42,5 +42,5 @@
42
42
  "@testing-library/react-hooks": "^7.0.1",
43
43
  "expo-module-scripts": "^3.0.0"
44
44
  },
45
- "gitHead": "f5076c4ff6cf352b5fd8e528533a377167fa4edb"
45
+ "gitHead": "4ba50c428c8369bb6b3a51a860d4898ad4ccbe78"
46
46
  }
@@ -1,5 +1,7 @@
1
1
  import React from 'react';
2
- import { NativeModules, requireNativeComponent, HostComponent } from 'react-native';
2
+ import { findNodeHandle, NativeModules, requireNativeComponent, HostComponent } from 'react-native';
3
+
4
+ import { requireNativeModule } from './requireNativeModule';
3
5
 
4
6
  // To make the transition from React Native's `requireNativeComponent` to Expo's
5
7
  // `requireNativeViewManager` as easy as possible, `requireNativeViewManager` is a drop-in
@@ -10,10 +12,6 @@ import { NativeModules, requireNativeComponent, HostComponent } from 'react-nati
10
12
  // passed to React Native's View (ex: style, testID) and custom view props, which are passed to the
11
13
  // adapter view component in a prop called `proxiedProperties`.
12
14
 
13
- type NativeExpoComponentProps = {
14
- proxiedProperties: object;
15
- };
16
-
17
15
  /**
18
16
  * A map that caches registered native components.
19
17
  */
@@ -52,33 +50,39 @@ export function requireNativeViewManager<P>(viewName: string): React.ComponentTy
52
50
  // Set up the React Native native component, which is an adapter to the universal module's view
53
51
  // manager
54
52
  const reactNativeViewName = `ViewManagerAdapter_${viewName}`;
55
- const ReactNativeComponent =
56
- requireCachedNativeComponent<NativeExpoComponentProps>(reactNativeViewName);
57
- const proxiedPropsNames = viewManagerConfig?.propsNames ?? [];
53
+ const ReactNativeComponent = requireCachedNativeComponent(reactNativeViewName);
58
54
 
59
- // Define a component for universal-module authors to access their native view manager
60
- const NativeComponentAdapter = React.forwardRef<any>((props, ref) => {
61
- const nativeProps = omit(props, proxiedPropsNames);
62
- const proxiedProps = pick(props, proxiedPropsNames);
63
- return <ReactNativeComponent {...nativeProps} proxiedProperties={proxiedProps} ref={ref} />;
64
- }) as React.ComponentType<P>;
65
- NativeComponentAdapter.displayName = `Adapter<${viewName}>`;
66
- return NativeComponentAdapter;
67
- }
55
+ class NativeComponent extends React.PureComponent<P> {
56
+ static displayName = viewName;
57
+
58
+ // This will be accessed from native when the prototype functions are called,
59
+ // in order to find the associated native view.
60
+ nativeTag: number | null = null;
61
+
62
+ componentDidMount(): void {
63
+ this.nativeTag = findNodeHandle(this);
64
+ }
68
65
 
69
- function omit(props: Record<string, any>, propNames: string[]) {
70
- const copied = { ...props };
71
- for (const propName of propNames) {
72
- delete copied[propName];
66
+ render(): React.ReactNode {
67
+ return <ReactNativeComponent {...this.props} />;
68
+ }
73
69
  }
74
- return copied;
75
- }
76
70
 
77
- function pick(props: Record<string, any>, propNames: string[]) {
78
- return propNames.reduce((prev, curr) => {
79
- if (curr in props) {
80
- prev[curr] = props[curr];
71
+ try {
72
+ const nativeModule = requireNativeModule(viewName);
73
+ const nativeViewPrototype = nativeModule.ViewPrototype;
74
+
75
+ if (nativeViewPrototype) {
76
+ // Assign native view functions to the component prototype so they can be accessed from the ref.
77
+ Object.assign(NativeComponent.prototype, nativeViewPrototype);
81
78
  }
82
- return prev;
83
- }, {});
79
+ } catch {
80
+ // `requireNativeModule` may throw an error when the native module cannot be found.
81
+ // In some tests we don't mock the entire modules, but we do want to mock native views. For now,
82
+ // until we still have to support the legacy modules proxy and don't have better ways to mock,
83
+ // let's just gracefully skip assigning the prototype functions.
84
+ // See: https://github.com/expo/expo/blob/main/packages/expo-modules-core/src/__tests__/NativeViewManagerAdapter-test.native.tsx
85
+ }
86
+
87
+ return NativeComponent;
84
88
  }
@@ -34,8 +34,8 @@ declare global {
34
34
  */
35
35
  export function requireNativeModule<ModuleType = any>(moduleName: string): ModuleType {
36
36
  const nativeModule: ModuleType =
37
- global.expo?.modules?.[moduleName] ??
38
- global.ExpoModules?.[moduleName] ??
37
+ globalThis.expo?.modules?.[moduleName] ??
38
+ globalThis.ExpoModules?.[moduleName] ??
39
39
  NativeModulesProxy[moduleName];
40
40
 
41
41
  if (!nativeModule) {
@@ -1,132 +0,0 @@
1
- @file:OptIn(ExperimentalStdlibApi::class)
2
- @file:Suppress("FunctionName")
3
-
4
- package expo.modules.kotlin.views
5
-
6
- import android.content.Context
7
- import android.view.View
8
- import expo.modules.kotlin.modules.DefinitionMarker
9
- import expo.modules.kotlin.types.toAnyType
10
- import kotlin.reflect.typeOf
11
-
12
- @DefinitionMarker
13
- class ViewManagerDefinitionBuilder {
14
- @PublishedApi
15
- internal var viewFactory: ((Context) -> View)? = null
16
-
17
- @PublishedApi
18
- internal var viewType: Class<out View>? = null
19
-
20
- @PublishedApi
21
- internal var props = mutableMapOf<String, AnyViewProp>()
22
-
23
- @PublishedApi
24
- internal var onViewDestroys: ((View) -> Unit)? = null
25
-
26
- @PublishedApi
27
- internal var viewGroupDefinition: ViewGroupDefinition? = null
28
- private var callbacksDefinition: CallbacksDefinition? = null
29
-
30
- fun build(): ViewManagerDefinition =
31
- ViewManagerDefinition(
32
- { context, _ -> requireNotNull(viewFactory)(context) },
33
- requireNotNull(viewType),
34
- props,
35
- onViewDestroys,
36
- callbacksDefinition,
37
- viewGroupDefinition
38
- )
39
-
40
- /**
41
- * Defines the factory creating a native view when the module is used as a view.
42
- */
43
- inline fun <reified ViewType : View> View(noinline body: (Context) -> ViewType) {
44
- viewType = ViewType::class.java
45
- viewFactory = body
46
- }
47
-
48
- /**
49
- * Creates view's lifecycle listener that is called right after the view isn't longer used by React Native.
50
- */
51
- inline fun <reified ViewType : View> OnViewDestroys(noinline body: (view: ViewType) -> Unit) {
52
- onViewDestroys = { body(it as ViewType) }
53
- }
54
-
55
- /**
56
- * Creates a view prop that defines its name and setter.
57
- */
58
- inline fun <reified ViewType : View, reified PropType> Prop(
59
- name: String,
60
- noinline body: (view: ViewType, prop: PropType) -> Unit
61
- ) {
62
- props[name] = ConcreteViewProp(
63
- name,
64
- typeOf<PropType>().toAnyType(),
65
- body
66
- )
67
- }
68
-
69
- /**
70
- * Creates a view prop group that defines its name and setter.
71
- */
72
- inline fun <reified ViewType : View, reified PropType> PropGroup(
73
- vararg names: String,
74
- noinline body: (view: ViewType, name: String, prop: PropType) -> Unit
75
- ) {
76
- for (name in names) {
77
- props[name] = ConcreteViewProp<ViewType, PropType>(
78
- name,
79
- typeOf<PropType>().toAnyType()
80
- ) { view, prop -> body(view, name, prop) }
81
- }
82
- }
83
-
84
- /**
85
- * Creates a view prop group that defines its name and setter with the custom mapping.
86
- */
87
- inline fun <reified ViewType : View, reified PropType, reified CustomValue> PropGroup(
88
- vararg propInfo: Pair<String, CustomValue>,
89
- noinline body: (view: ViewType, value: CustomValue, prop: PropType) -> Unit
90
- ) {
91
- for ((name, value) in propInfo) {
92
- props[name] = ConcreteViewProp<ViewType, PropType>(
93
- name,
94
- typeOf<PropType>().toAnyType()
95
- ) { view, prop -> body(view, value, prop) }
96
- }
97
- }
98
-
99
- /**
100
- * Creates a view prop group that defines its name and setter with the index mapping.
101
- */
102
- @JvmName("PropGroupIndexed")
103
- inline fun <reified ViewType : View, reified PropType> PropGroup(
104
- vararg names: String,
105
- noinline body: (view: ViewType, value: Int, prop: PropType) -> Unit
106
- ) {
107
- names.forEachIndexed { index, name ->
108
- props[name] = ConcreteViewProp<ViewType, PropType>(
109
- name,
110
- typeOf<PropType>().toAnyType()
111
- ) { view, prop -> body(view, index, prop) }
112
- }
113
- }
114
-
115
- /**
116
- * Defines prop names that should be treated as callbacks.
117
- */
118
- fun Events(vararg callbacks: String) {
119
- callbacksDefinition = CallbacksDefinition(callbacks)
120
- }
121
-
122
- /**
123
- * Creates the group view definition that scopes group view-related definitions.
124
- */
125
- inline fun GroupView(body: ViewGroupDefinitionLegacyBuilder.() -> Unit) {
126
- require(viewGroupDefinition == null) { "The viewManager definition may have exported only one groupView definition." }
127
-
128
- val groupViewDefinitionBuilder = ViewGroupDefinitionLegacyBuilder()
129
- body.invoke(groupViewDefinitionBuilder)
130
- viewGroupDefinition = groupViewDefinitionBuilder.build()
131
- }
132
- }
@@ -1,21 +0,0 @@
1
- // Copyright © 2018 650 Industries. All rights reserved.
2
-
3
- #import <Foundation/Foundation.h>
4
- #import <UIKit/UIKit.h>
5
-
6
- #import <ExpoModulesCore/EXExportedModule.h>
7
-
8
- NS_ASSUME_NONNULL_BEGIN
9
-
10
- @interface EXViewManager : EXExportedModule
11
-
12
- - (UIView *)view;
13
- - (NSString *)viewName;
14
- - (NSArray<NSString *> *)supportedEvents;
15
-
16
- - (NSDictionary<NSString *, NSString *> *)getPropsNames;
17
- - (void)updateProp:(NSString *)propName withValue:(id)value onView:(UIView *)view;
18
-
19
- @end
20
-
21
- NS_ASSUME_NONNULL_END
@@ -1,128 +0,0 @@
1
- // Copyright © 2018 650 Industries. All rights reserved.
2
-
3
- #import <objc/runtime.h>
4
-
5
- #import <ExpoModulesCore/EXViewManager.h>
6
-
7
- #define QUOTE(str) #str
8
- #define EXPAND_AND_QUOTE(str) QUOTE(str)
9
-
10
- #define EX_IS_METHOD_PROPSETTER(methodName) \
11
- [methodName hasPrefix:@EXPAND_AND_QUOTE(EX_PROPSETTERS_PREFIX)]
12
-
13
- #define EX_PROPSETTER_FOR_PROP(propName)\
14
- QUOTE(EX_PROPSETTERS_PREFIX)propName
15
-
16
- static const NSString *noViewExceptionName = @"No custom -(UIView *)view implementation.";
17
- static const NSString *noViewExceptionReason = @"You've subclassed an EXViewManager, but didn't override the -(UIView *)view method. Override this method and return a new view instance.";
18
-
19
- static const NSString *noViewNameExceptionName = @"No custom -(NSString *)viewName implementation.";
20
- static const NSString *noViewNameExceptionReasonFormat = @"You've subclassed an EXViewManager in %@, but didn't override the -(NSString *)viewName method. Override this method and return a name of the view component.";
21
-
22
- @interface EXViewManager ()
23
-
24
- @property NSDictionary<NSString *, NSString *> *propsNamesSelectors;
25
-
26
- @end
27
-
28
- @implementation EXViewManager
29
-
30
- - (instancetype)init
31
- {
32
- if (self = [super init]) {
33
- _propsNamesSelectors = [self getPropsNames];
34
- }
35
- return self;
36
- }
37
-
38
- - (UIView *)view
39
- {
40
- @throw [NSException exceptionWithName:(NSString *)noViewExceptionName
41
- reason:(NSString *)noViewExceptionReason
42
- userInfo:nil];
43
- }
44
-
45
- - (NSString *)viewName
46
- {
47
- @throw [NSException exceptionWithName:(NSString *)noViewNameExceptionName
48
- reason:(NSString *)[NSString stringWithFormat:(NSString *)noViewNameExceptionReasonFormat, NSStringFromClass([self class])]
49
- userInfo:nil];
50
- }
51
-
52
- - (NSArray<NSString *> *)supportedEvents
53
- {
54
- return @[];
55
- }
56
-
57
- // Scans the class methods for methods with a certain prefix (see macro EX_PROPSETTERS_PREFIX),
58
- // and returns dictionary which has props names as keys and selector strings as values.
59
- // Example: @{ @"type": @"__ex_set__type" }
60
-
61
- - (NSDictionary<NSString *, NSString *> *)getPropsNames
62
- {
63
- NSMutableDictionary<NSString *, NSString *> *propsNames = [NSMutableDictionary dictionary];
64
-
65
- unsigned int methodsCount;
66
- Method *methodsDescriptions = class_copyMethodList([self class], &methodsCount);
67
-
68
- @try {
69
- for(int i = 0; i < methodsCount; i++) {
70
- Method method = methodsDescriptions[i];
71
- SEL methodSelector = method_getName(method);
72
- NSString *methodName = NSStringFromSelector(methodSelector);
73
- if (EX_IS_METHOD_PROPSETTER(methodName)) {
74
- NSString *propNameWithArguments = [methodName substringFromIndex:[@EXPAND_AND_QUOTE(EX_PROPSETTERS_PREFIX) length]];
75
- NSString *propName = [[propNameWithArguments componentsSeparatedByString:@":"] firstObject];
76
- propsNames[propName] = methodName;
77
- }
78
- }
79
- }
80
- @finally {
81
- free(methodsDescriptions);
82
- }
83
-
84
- return propsNames;
85
- }
86
-
87
- - (void)updateProp:(NSString *)propName withValue:(id)value onView:(UIView *)view
88
- {
89
- if (_propsNamesSelectors[propName]) {
90
- NSString *selectorString = _propsNamesSelectors[propName];
91
- SEL selector = NSSelectorFromString(selectorString);
92
- NSMethodSignature *methodSignature = [self methodSignatureForSelector:selector];
93
- if (methodSignature == nil) {
94
- // This in fact should never happen -- if we have a selector for this prop
95
- // (which we have if we're here), view manager should return method signature
96
- // for the cached selector.
97
- EXLogError(@"View manager of view '%@' does not implement method for selector '%@'.", [self viewName], NSStringFromSelector(selector));
98
- return;
99
- }
100
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
101
- [invocation setTarget:self];
102
- [invocation setSelector:selector];
103
- [invocation setArgument:&value atIndex:2];
104
-
105
- // According to objc.h, the BOOL type can be represented by `bool` or `signed char` so
106
- // getArgumentTypeAtIndex can return _C_BOOL (when `bool`) or _C_CHR (when `signed char`)
107
- #if OBJC_BOOL_IS_BOOL
108
- if ([methodSignature getArgumentTypeAtIndex:2][0] == _C_BOOL) {
109
- // We need this intermediary variable, see
110
- // https://stackoverflow.com/questions/11061166/pointer-to-bool-in-objective-c
111
- BOOL retainedValue = [value boolValue];
112
- [invocation setArgument:&retainedValue atIndex:2];
113
- }
114
- #else // BOOL is represented by `signed char`
115
- if ([methodSignature getArgumentTypeAtIndex:2][0] == _C_CHR) {
116
- BOOL retainedValue = [value charValue];
117
- [invocation setArgument:&retainedValue atIndex:2];
118
- }
119
- #endif
120
- [invocation setArgument:(void *)&view atIndex:3];
121
- [invocation retainArguments];
122
- [invocation invoke];
123
- } else {
124
- EXLogWarn(@"Tried to set property `%@` on view manager of view `%@` when the view manager does not export such prop.", propName, [self viewName]);
125
- }
126
- }
127
-
128
- @end
@@ -1,17 +0,0 @@
1
- // Copyright 2018-present 650 Industries. All rights reserved.
2
-
3
- #import <React/RCTViewManager.h>
4
-
5
- #import <ExpoModulesCore/EXViewManager.h>
6
-
7
- // A registry for view manager adapter classes.
8
- // As we have to create subclasses of EXViewManagerAdapters
9
- // at runtime to be able to respond with proper + (NSString *)moduleName
10
- // to React, let's cache these classes and not create them twice.
11
-
12
- @interface EXViewManagerAdapterClassesRegistry : NSObject
13
-
14
- - (Class)viewManagerAdapterClassForViewManager:(EXViewManager *)viewManager;
15
- + (Class)createViewManagerAdapterClassForViewManager:(EXViewManager *)viewManager;
16
-
17
- @end
@@ -1,67 +0,0 @@
1
- // Copyright 2018-present 650 Industries. All rights reserved.
2
-
3
- #import <objc/runtime.h>
4
-
5
- #import <ExpoModulesCore/EXViewManagerAdapterClassesRegistry.h>
6
- #import <ExpoModulesCore/EXViewManagerAdapter.h>
7
-
8
- static const NSString *viewManagerAdapterModuleNamePrefix = @"ViewManagerAdapter_";
9
-
10
- static IMP directEventBlockImplementation = nil;
11
- static dispatch_once_t directEventBlockImplementationOnceToken;
12
-
13
- @interface EXViewManagerAdapterClassesRegistry ()
14
-
15
- @property (nonatomic, strong) NSMutableDictionary<Class, Class> *viewManagerAdaptersClasses;
16
-
17
- @end
18
-
19
- @implementation EXViewManagerAdapterClassesRegistry
20
-
21
- - (instancetype)init
22
- {
23
- if (self = [super init]) {
24
- _viewManagerAdaptersClasses = [NSMutableDictionary dictionary];
25
- }
26
- return self;
27
- }
28
-
29
- - (Class)viewManagerAdapterClassForViewManager:(EXViewManager *)viewManager
30
- {
31
- Class viewManagerClass = [viewManager class];
32
- if (_viewManagerAdaptersClasses[viewManagerClass] == nil) {
33
- _viewManagerAdaptersClasses[(id <NSCopying>)viewManagerClass] = [self.class createViewManagerAdapterClassForViewManager:viewManager];
34
- }
35
- return _viewManagerAdaptersClasses[viewManagerClass];
36
- }
37
-
38
- + (Class)createViewManagerAdapterClassForViewManager:(EXViewManager *)viewManager
39
- {
40
- const char *viewManagerClassName = [[viewManagerAdapterModuleNamePrefix stringByAppendingString:[viewManager viewName]] UTF8String];
41
- Class viewManagerAdapterClass = objc_allocateClassPair([EXViewManagerAdapter class], viewManagerClassName, 0);
42
- Class metaClass = object_getClass(viewManagerAdapterClass);
43
-
44
- [self _ensureDirectEventBlockImplementationIsPresent];
45
-
46
- for (NSString *eventName in [viewManager supportedEvents]) {
47
- class_addMethod(metaClass, NSSelectorFromString([@"propConfig_" stringByAppendingString:eventName]), directEventBlockImplementation, "@@:");
48
- }
49
-
50
- IMP viewManagerImp = imp_implementationWithBlock(^{
51
- return viewManager;
52
- });
53
- class_addMethod(viewManagerAdapterClass, NSSelectorFromString(@"viewManager"), viewManagerImp, "@@:");
54
-
55
- return viewManagerAdapterClass;
56
- }
57
-
58
- + (void)_ensureDirectEventBlockImplementationIsPresent
59
- {
60
- dispatch_once(&directEventBlockImplementationOnceToken, ^{
61
- directEventBlockImplementation = imp_implementationWithBlock(^{
62
- return @[@"RCTDirectEventBlock"];
63
- });
64
- });
65
- }
66
-
67
- @end
@@ -1,17 +0,0 @@
1
- // Copyright 2018-present 650 Industries. All rights reserved.
2
-
3
- #import <React/RCTViewManager.h>
4
-
5
- #import <ExpoModulesCore/EXViewManager.h>
6
-
7
- // EXViewManagerAdapter is an RN wrapper around ExpoModulesCore's EXViewManager.
8
- // For each exported view manager is it subclassed so that React Native
9
- // can get proper module name (which is returned by a class method).
10
- //
11
- // Instead of instantiating the subclass by yourself,
12
- // use EXViewManagerAdapterClassesRegistry's
13
- // viewManagerAdapterClassForViewManager:.
14
-
15
- @interface EXViewManagerAdapter : RCTViewManager
16
-
17
- @end
@@ -1,45 +0,0 @@
1
- // Copyright 2018-present 650 Industries. All rights reserved.
2
-
3
- #import <ExpoModulesCore/EXViewManagerAdapter.h>
4
-
5
- @interface EXViewManagerAdapter ()
6
-
7
- - (EXViewManager *)viewManager;
8
-
9
- @end
10
-
11
- @implementation EXViewManagerAdapter
12
-
13
- - (NSArray<NSString *> *)supportedEvents
14
- {
15
- return [[self viewManager] supportedEvents];
16
- }
17
-
18
- // This class is not used directly --- usually it's subclassed
19
- // in runtime by EXNativeModulesProxy for each exported view manager.
20
- // Each created class has different class name, conforming to convention.
21
- // This way we can provide React Native with different RCTViewManagers
22
- // returning different modules names.
23
-
24
- + (NSString *)moduleName
25
- {
26
- return NSStringFromClass(self);
27
- }
28
-
29
- - (UIView *)view
30
- {
31
- return [[self viewManager] view];
32
- }
33
-
34
- // The adapter multiplexes custom view properties in one "big object prop" that is passed here.
35
-
36
- RCT_CUSTOM_VIEW_PROPERTY(proxiedProperties, NSDictionary, UIView)
37
- {
38
- __weak EXViewManagerAdapter *weakSelf = self;
39
- [json enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
40
- __strong EXViewManagerAdapter *strongSelf = weakSelf;
41
- [strongSelf.viewManager updateProp:key withValue:obj onView:view];
42
- }];
43
- }
44
-
45
- @end