expo-modules-core 0.6.4 → 0.8.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 (217) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +1 -1
  3. package/android/ExpoModulesCorePlugin.gradle +15 -0
  4. package/android/build.gradle +46 -32
  5. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +5 -5
  6. package/android/src/main/java/expo/modules/adapters/react/services/UIManagerModuleWrapper.java +13 -0
  7. package/android/src/main/java/expo/modules/core/ViewManager.java +9 -0
  8. package/android/src/main/java/expo/modules/core/interfaces/JavaScriptContextProvider.java +4 -0
  9. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +37 -1
  10. package/android/src/main/java/expo/modules/core/interfaces/ReactNativeHostHandler.java +19 -0
  11. package/android/src/main/java/expo/modules/core/interfaces/services/UIManager.java +2 -0
  12. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +23 -5
  13. package/android/src/main/java/expo/modules/kotlin/DynamicExtenstions.kt +5 -3
  14. package/android/src/main/java/expo/modules/kotlin/KPromiseWrapper.kt +3 -8
  15. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +24 -9
  16. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +12 -7
  17. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +23 -1
  18. package/android/src/main/java/expo/modules/kotlin/Promise.kt +1 -1
  19. package/android/src/main/java/expo/modules/kotlin/callbacks/Callback.kt +5 -0
  20. package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallback.kt +39 -0
  21. package/android/src/main/java/expo/modules/kotlin/callbacks/ViewCallbackDelegate.kt +27 -0
  22. package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +25 -0
  23. package/android/src/main/java/expo/modules/kotlin/events/EventEmitter.kt +13 -0
  24. package/android/src/main/java/expo/modules/kotlin/events/KModuleEventEmitterWrapper.kt +102 -0
  25. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +93 -9
  26. package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +11 -0
  27. package/android/src/main/java/expo/modules/kotlin/{methods/AnyMethod.kt → functions/AnyFunction.kt} +18 -18
  28. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +15 -0
  29. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +61 -0
  30. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +15 -0
  31. package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +36 -0
  32. package/android/src/main/java/expo/modules/kotlin/modules/DefinitionMarker.kt +4 -0
  33. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +17 -2
  34. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +219 -30
  35. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +2 -2
  36. package/android/src/main/java/expo/modules/kotlin/records/FieldValidator.kt +139 -0
  37. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +71 -15
  38. package/android/src/main/java/expo/modules/kotlin/records/Required.kt +5 -0
  39. package/android/src/main/java/expo/modules/kotlin/records/ValidationBinder.kt +110 -0
  40. package/android/src/main/java/expo/modules/kotlin/records/Validators.kt +61 -0
  41. package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +11 -5
  42. package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverter.kt +35 -0
  43. package/android/src/main/java/expo/modules/kotlin/types/JSTypeConverterHelper.kt +148 -0
  44. package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +10 -4
  45. package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +12 -6
  46. package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +29 -13
  47. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +2 -1
  48. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +9 -1
  49. package/android/src/main/java/expo/modules/kotlin/views/CallbacksDefinition.kt +3 -0
  50. package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +71 -0
  51. package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +22 -0
  52. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinition.kt +18 -0
  53. package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +64 -0
  54. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +30 -2
  55. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +42 -1
  56. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +62 -2
  57. package/build/EventEmitter.d.ts +1 -0
  58. package/build/EventEmitter.d.ts.map +1 -0
  59. package/build/NativeModulesProxy.d.ts +1 -0
  60. package/build/NativeModulesProxy.d.ts.map +1 -0
  61. package/build/NativeModulesProxy.native.d.ts +1 -4
  62. package/build/NativeModulesProxy.native.d.ts.map +1 -0
  63. package/build/NativeModulesProxy.native.js +1 -14
  64. package/build/NativeModulesProxy.native.js.map +1 -1
  65. package/build/NativeModulesProxy.types.d.ts +1 -3
  66. package/build/NativeModulesProxy.types.d.ts.map +1 -0
  67. package/build/NativeModulesProxy.types.js.map +1 -1
  68. package/build/NativeViewManagerAdapter.d.ts +1 -0
  69. package/build/NativeViewManagerAdapter.d.ts.map +1 -0
  70. package/build/NativeViewManagerAdapter.native.d.ts +1 -0
  71. package/build/NativeViewManagerAdapter.native.d.ts.map +1 -0
  72. package/build/NativeViewManagerAdapter.native.js +9 -33
  73. package/build/NativeViewManagerAdapter.native.js.map +1 -1
  74. package/build/PermissionsHook.d.ts +1 -0
  75. package/build/PermissionsHook.d.ts.map +1 -0
  76. package/build/PermissionsInterface.d.ts +1 -0
  77. package/build/PermissionsInterface.d.ts.map +1 -0
  78. package/build/Platform.d.ts +1 -0
  79. package/build/Platform.d.ts.map +1 -0
  80. package/build/SyntheticPlatformEmitter.d.ts +1 -0
  81. package/build/SyntheticPlatformEmitter.d.ts.map +1 -0
  82. package/build/SyntheticPlatformEmitter.web.d.ts +1 -0
  83. package/build/SyntheticPlatformEmitter.web.d.ts.map +1 -0
  84. package/build/deprecate.d.ts +1 -0
  85. package/build/deprecate.d.ts.map +1 -0
  86. package/build/environment/browser.d.ts +1 -0
  87. package/build/environment/browser.d.ts.map +1 -0
  88. package/build/environment/browser.web.d.ts +1 -0
  89. package/build/environment/browser.web.d.ts.map +1 -0
  90. package/build/errors/CodedError.d.ts +1 -0
  91. package/build/errors/CodedError.d.ts.map +1 -0
  92. package/build/errors/UnavailabilityError.d.ts +1 -0
  93. package/build/errors/UnavailabilityError.d.ts.map +1 -0
  94. package/build/index.d.ts +3 -0
  95. package/build/index.d.ts.map +1 -0
  96. package/build/index.js +2 -0
  97. package/build/index.js.map +1 -1
  98. package/build/requireNativeModule.d.ts +16 -0
  99. package/build/requireNativeModule.d.ts.map +1 -0
  100. package/build/requireNativeModule.js +18 -0
  101. package/build/requireNativeModule.js.map +1 -0
  102. package/build/sweet/NativeErrorManager.d.ts +3 -0
  103. package/build/sweet/NativeErrorManager.d.ts.map +1 -0
  104. package/build/sweet/NativeErrorManager.js +3 -0
  105. package/build/sweet/NativeErrorManager.js.map +1 -0
  106. package/build/sweet/setUpErrorManager.fx.d.ts +2 -0
  107. package/build/sweet/setUpErrorManager.fx.d.ts.map +1 -0
  108. package/build/sweet/setUpErrorManager.fx.js +11 -0
  109. package/build/sweet/setUpErrorManager.fx.js.map +1 -0
  110. package/ios/AppDelegates/EXAppDelegatesLoader.m +4 -8
  111. package/ios/AppDelegates/ExpoAppDelegate.swift +22 -20
  112. package/ios/EXAppDefines.h +1 -0
  113. package/ios/EXAppDefines.m +6 -0
  114. package/ios/EXUtilities.h +2 -0
  115. package/ios/EXUtilities.m +12 -0
  116. package/ios/ExpoModulesCore.h +4 -0
  117. package/ios/ExpoModulesCore.podspec +4 -2
  118. package/ios/Interfaces/FileSystem/EXFileSystemInterface.h +1 -1
  119. package/ios/Interfaces/TaskManager/EXTaskServiceInterface.h +1 -0
  120. package/ios/JSI/{JSIConversions.h → EXJSIConversions.h} +5 -0
  121. package/ios/JSI/{JSIConversions.mm → EXJSIConversions.mm} +21 -1
  122. package/ios/JSI/{JSIInstaller.h → EXJSIInstaller.h} +10 -0
  123. package/ios/JSI/EXJSIInstaller.mm +17 -0
  124. package/ios/JSI/EXJSIUtils.h +19 -0
  125. package/ios/JSI/EXJSIUtils.mm +89 -0
  126. package/ios/JSI/EXJavaScriptObject.h +97 -0
  127. package/ios/JSI/EXJavaScriptObject.mm +121 -0
  128. package/ios/JSI/EXJavaScriptRuntime.h +73 -0
  129. package/ios/JSI/EXJavaScriptRuntime.mm +153 -0
  130. package/ios/JSI/EXJavaScriptValue.h +57 -0
  131. package/ios/JSI/EXJavaScriptValue.mm +166 -0
  132. package/ios/JSI/ExpoModulesHostObject.h +33 -0
  133. package/ios/JSI/ExpoModulesHostObject.mm +41 -0
  134. package/ios/JSI/JavaScriptRuntime.swift +32 -0
  135. package/ios/JSI/JavaScriptValue.swift +94 -0
  136. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +3 -23
  137. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +2 -2
  138. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +101 -75
  139. package/ios/RCTComponentData+Privates.h +12 -0
  140. package/ios/ReactDelegates/EXReactCompatibleHelpers.h +18 -0
  141. package/ios/ReactDelegates/EXReactCompatibleHelpers.m +19 -0
  142. package/ios/ReactDelegates/ExpoReactDelegate.swift +3 -3
  143. package/ios/ReactDelegates/ExpoReactDelegateHandler.swift +4 -4
  144. package/ios/ReactDelegates/ModulePriorities.swift +1 -1
  145. package/ios/Swift/AppContext.swift +64 -4
  146. package/ios/Swift/Arguments/ArgumentType.swift +4 -0
  147. package/ios/Swift/Arguments/Convertibles.swift +13 -13
  148. package/ios/Swift/Arguments/Types/EnumArgumentType.swift +11 -17
  149. package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +1 -1
  150. package/ios/Swift/Arguments/Types/RawArgumentType.swift +2 -2
  151. package/ios/Swift/Conversions.swift +51 -56
  152. package/ios/Swift/EventListener.swift +8 -10
  153. package/ios/Swift/Events/Callback.swift +66 -0
  154. package/ios/Swift/Events/Event.swift +43 -0
  155. package/ios/Swift/Exceptions/ChainableException.swift +51 -0
  156. package/ios/Swift/{CodedError.swift → Exceptions/CodedError.swift} +1 -12
  157. package/ios/Swift/Exceptions/Exception.swift +62 -0
  158. package/ios/Swift/Exceptions/ExceptionOrigin.swift +28 -0
  159. package/ios/Swift/Exceptions/GenericException.swift +20 -0
  160. package/ios/Swift/Exceptions/UnexpectedException.swift +16 -0
  161. package/ios/Swift/Functions/AnyFunction.swift +11 -1
  162. package/ios/Swift/Functions/AsyncFunction.swift +17 -0
  163. package/ios/Swift/Functions/ConcreteFunction.swift +43 -17
  164. package/ios/Swift/JavaScriptUtils.swift +54 -0
  165. package/ios/Swift/ModuleHolder.swift +66 -16
  166. package/ios/Swift/ModuleRegistry.swift +4 -1
  167. package/ios/Swift/Modules/AnyModule.swift +0 -1
  168. package/ios/Swift/Modules/ModuleDefinition.swift +4 -13
  169. package/ios/Swift/Modules/ModuleDefinitionBuilder.swift +0 -1
  170. package/ios/Swift/Modules/ModuleDefinitionComponents.swift +0 -188
  171. package/ios/Swift/ModulesProvider.swift +3 -11
  172. package/ios/Swift/Objects/ObjectDefinition.swift +30 -0
  173. package/ios/Swift/Objects/ObjectDefinitionComponents.swift +384 -0
  174. package/ios/Swift/Promise.swift +8 -3
  175. package/ios/Swift/Records/AnyField.swift +7 -0
  176. package/ios/Swift/Records/Field.swift +24 -19
  177. package/ios/Swift/Records/FieldOption.swift +1 -1
  178. package/ios/Swift/Records/Record.swift +12 -4
  179. package/ios/Swift/SwiftInteropBridge.swift +53 -15
  180. package/ios/Swift/Views/AnyViewProp.swift +1 -1
  181. package/ios/Swift/Views/ComponentData.swift +96 -0
  182. package/ios/Swift/Views/ConcreteViewProp.swift +6 -8
  183. package/ios/Swift/Views/ExpoView.swift +8 -0
  184. package/ios/Swift/Views/ViewFactory.swift +1 -1
  185. package/ios/Swift/Views/ViewManagerDefinition.swift +23 -2
  186. package/ios/Swift/Views/ViewManagerDefinitionBuilder.swift +0 -1
  187. package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +26 -0
  188. package/ios/Swift/Views/ViewModuleWrapper.swift +5 -2
  189. package/ios/Swift.h +5 -0
  190. package/ios/Tests/ArgumentTypeSpec.swift +5 -7
  191. package/ios/Tests/ConstantsSpec.swift +6 -7
  192. package/ios/Tests/ConvertiblesSpec.swift +35 -36
  193. package/ios/Tests/ExceptionsSpec.swift +111 -0
  194. package/ios/Tests/ExpoModulesSpec.swift +76 -0
  195. package/ios/Tests/FunctionSpec.swift +22 -25
  196. package/ios/Tests/FunctionWithConvertiblesSpec.swift +4 -5
  197. package/ios/Tests/JavaScriptObjectSpec.swift +97 -0
  198. package/ios/Tests/JavaScriptRuntimeSpec.swift +94 -0
  199. package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
  200. package/ios/Tests/Mocks/ModulesProviderMock.swift +0 -1
  201. package/ios/Tests/ModuleEventListenersSpec.swift +3 -4
  202. package/ios/Tests/ModuleRegistrySpec.swift +2 -3
  203. package/ios/Tests/RecordSpec.swift +9 -20
  204. package/package.json +3 -3
  205. package/src/NativeModulesProxy.native.ts +2 -22
  206. package/src/NativeModulesProxy.types.ts +0 -8
  207. package/src/NativeViewManagerAdapter.native.tsx +12 -28
  208. package/src/index.ts +4 -0
  209. package/src/requireNativeModule.ts +29 -0
  210. package/src/sweet/NativeErrorManager.ts +2 -0
  211. package/src/sweet/setUpErrorManager.fx.ts +12 -0
  212. package/android/src/main/java/expo/modules/kotlin/events/KEventEmitterWrapper.kt +0 -26
  213. package/android/src/main/java/expo/modules/kotlin/methods/Method.kt +0 -14
  214. package/android/src/main/java/expo/modules/kotlin/methods/PromiseMethod.kt +0 -15
  215. package/ios/JSI/ExpoModulesProxySpec.h +0 -24
  216. package/ios/JSI/ExpoModulesProxySpec.mm +0 -135
  217. package/ios/JSI/JSIInstaller.mm +0 -22
package/CHANGELOG.md CHANGED
@@ -10,6 +10,59 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 0.8.0 — 2022-04-18
14
+
15
+ ### 🛠 Breaking changes
16
+
17
+ - Remove backward compatible workaround and drop react-native 0.64 support. ([#16446](https://github.com/expo/expo/pull/16446) by [@kudo](https://github.com/kudo))
18
+
19
+ ### ⚠️ Notices
20
+
21
+ - Deprecated current behavior of `function` module definition component in favor of `asyncFunction` to emphasize that it's being executed asynchronously in JavaScript. In the future release `function` will become synchronous. ([#16630](https://github.com/expo/expo/pull/16630) by [@tsapeta](https://github.com/tsapeta), [#16656](https://github.com/expo/expo/pull/16656) by [@lukmccall](https://github.com/lukmccall))
22
+ - On Android bump `compileSdkVersion` to `31`, `targetSdkVersion` to `31` and `Java` version to `11`. ([#16941](https://github.com/expo/expo/pull/16941) by [@bbarthec](https://github.com/bbarthec))
23
+
24
+ ### 🎉 New features
25
+
26
+ - Add `getDevSupportManagerFactory` support to `ReactNativeHostHandler`. ([#16434](https://github.com/expo/expo/pull/16434) by [@lukmccall](https://github.com/lukmccall))
27
+ - Add support for automatic setup of `expo-dev-client` on Android. ([#16441](https://github.com/expo/expo/pull/16441) by [@esamelson](https://github.com/esamelson))
28
+ - Stopped relying on deprecated `ViewPropTypes` from React Native. ([#16207](https://github.com/expo/expo/pull/16207) by [@tsapeta](https://github.com/tsapeta))
29
+ - Added Android `ReactNativeHostHandler.getJavaScriptExecutorFactory()` for a module to override the `JavaScriptExecutorFactory`. ([#17005](https://github.com/expo/expo/pull/17005) by [@kudo](https://github.com/kudo))
30
+
31
+ ### 🐛 Bug fixes
32
+
33
+ - Fix the `Fatal error: Expo modules provider must implement "ModulesProviderProtocol"` runtime error in XCTest targets and SwiftUI Preview. ([#16733](https://github.com/expo/expo/pull/16733) by [@kudo](https://github.com/kudo))
34
+
35
+ ### 💡 Others
36
+
37
+ - Removed the opt-in feature to use the turbo module implementation of `NativeModulesProxy` in favor of another solution introduced in [#15847](https://github.com/expo/expo/pull/15847). ([#16825](https://github.com/expo/expo/pull/16825) by [@tsapeta](https://github.com/tsapeta))
38
+
39
+ ## 0.7.0 — 2022-01-26
40
+
41
+ ### 🎉 New features
42
+
43
+ - Allow accessing `RCTBridge` from the modules on iOS. ([#15816](https://github.com/expo/expo/pull/15816) by [@tsapeta](https://github.com/tsapeta))
44
+ - Added support for native callbacks through the view props in Sweet API on iOS. ([#15731](https://github.com/expo/expo/pull/15731) by [@tsapeta](https://github.com/tsapeta))
45
+ - Added support for native callbacks through the view props in Sweet API on Android. ([#15743](https://github.com/expo/expo/pull/15743) by [@lukmccall](https://github.com/lukmccall))
46
+ - The `ModuleDefinition` will use class name if the `name` component wasn't provided in Sweet API on Android. ([#15738](https://github.com/expo/expo/pull/15738) by [@lukmccall](https://github.com/lukmccall))
47
+ - Added `onViewDestroys` component to the `ViewManager` in Sweet API on Android. ([#15740](https://github.com/expo/expo/pull/15740) by [@lukmccall](https://github.com/lukmccall))
48
+ - Added shortened `constants` component that takes `vargs Pair<String, Any?>` as an argument in Sweet API on Android. ([#15742](https://github.com/expo/expo/pull/15742) by [@lukmccall](https://github.com/lukmccall))
49
+ - Introduced the concept of chainable exceptions in Sweet API on iOS. ([#15813](https://github.com/expo/expo/pull/15813) by [@tsapeta](https://github.com/tsapeta))
50
+ - Sweet function closures can throw errors on iOS. ([#15849](https://github.com/expo/expo/pull/15849) by [@tsapeta](https://github.com/tsapeta))
51
+ - Add `requireNativeModule` function to replace accessing native modules from `NativeModulesProxy`. ([#15848](https://github.com/expo/expo/pull/15848) by [@tsapeta](https://github.com/tsapeta))
52
+ - Implemented basic functionality of JSI host object to replace `NativeModulesProxy` on iOS. ([#15847](https://github.com/expo/expo/pull/15847) by [@tsapeta](https://github.com/tsapeta))
53
+
54
+ ### 🐛 Bug fixes
55
+
56
+ - It's no longer possible to directly call methods from the `ModuleDefinition` in the `ViewManagers` on Android. ([#15741](https://github.com/expo/expo/pull/15741) by [@lukmccall](https://github.com/lukmccall))
57
+ - Fix compatibility with react-native 0.66. ([#15914](https://github.com/expo/expo/pull/15914) by [@kudo](https://github.com/kudo))
58
+ - Fix `Plugin with id 'maven' not found` build error from Android Gradle 7. ([#16080](https://github.com/expo/expo/pull/16080) by [@kudo](https://github.com/kudo))
59
+
60
+ ## 0.6.5 — 2022-02-01
61
+
62
+ ### 🐛 Bug fixes
63
+
64
+ - Fix `Plugin with id 'maven' not found` build error from Android Gradle 7. ([#16080](https://github.com/expo/expo/pull/16080) by [@kudo](https://github.com/kudo))
65
+
13
66
  ## 0.6.4 — 2022-01-05
14
67
 
15
68
  ### 🐛 Bug fixes
package/README.md CHANGED
@@ -4,7 +4,7 @@ The core of Expo Modules architecture.
4
4
 
5
5
  # Installation in managed Expo projects
6
6
 
7
- For managed [managed](https://docs.expo.io/versions/latest/introduction/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](#api-documentation). If you follow the link and there is no documentation available then this library is not yet usable within managed projects &mdash; it is likely to be included in an upcoming Expo SDK release.
7
+ For [managed](https://docs.expo.dev/versions/latest/introduction/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](#api-documentation). If you follow the link and there is no documentation available then this library is not yet usable within managed projects &mdash; it is likely to be included in an upcoming Expo SDK release.
8
8
 
9
9
  # Installation in bare React Native projects
10
10
 
@@ -0,0 +1,15 @@
1
+ class KotlinExpoModulesCorePlugin implements Plugin<Project> {
2
+ void apply(Project project) {
3
+ project.buildscript {
4
+ project.ext.kotlinVersion = {
5
+ project.rootProject.ext.has("kotlinVersion")
6
+ ? project.rootProject.ext.get("kotlinVersion")
7
+ : "1.6.10"
8
+ }
9
+ }
10
+ }
11
+ }
12
+
13
+ ext.applyKotlinExpoModulesCorePlugin = {
14
+ apply plugin: KotlinExpoModulesCorePlugin
15
+ }
@@ -1,71 +1,85 @@
1
1
  apply plugin: 'com.android.library'
2
2
  apply plugin: 'kotlin-android'
3
- apply plugin: 'maven'
3
+ apply plugin: 'maven-publish'
4
4
 
5
5
  group = 'host.exp.exponent'
6
- version = '0.6.4'
6
+ version = '0.8.0'
7
7
 
8
8
  buildscript {
9
+ def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
10
+ if (expoModulesCorePlugin.exists()) {
11
+ apply from: expoModulesCorePlugin
12
+ applyKotlinExpoModulesCorePlugin()
13
+ }
14
+
9
15
  // Simple helper that allows the root project to override versions declared by this library.
10
16
  ext.safeExtGet = { prop, fallback ->
11
17
  rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
12
18
  }
13
19
 
20
+ // Ensures backward compatibility
21
+ ext.getKotlinVersion = {
22
+ if (ext.has("kotlinVersion")) {
23
+ ext.kotlinVersion()
24
+ } else {
25
+ ext.safeExtGet("kotlinVersion", "1.6.10")
26
+ }
27
+ }
28
+
14
29
  repositories {
15
30
  mavenCentral()
16
31
  }
17
32
 
18
33
  dependencies {
19
- classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet('kotlinVersion', '1.4.21')}")
34
+ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
20
35
  }
21
36
  }
22
37
 
23
- //Upload android library to maven with javadoc and android sources
24
- configurations {
25
- deployerJars
26
- }
27
-
28
- //Creating sources with comments
38
+ // Creating sources with comments
29
39
  task androidSourcesJar(type: Jar) {
30
40
  classifier = 'sources'
31
41
  from android.sourceSets.main.java.srcDirs
32
42
  }
33
43
 
34
- //Put the androidSources and javadoc to the artifacts
35
- artifacts {
36
- archives androidSourcesJar
37
- }
38
-
39
- uploadArchives {
40
- repositories {
41
- mavenDeployer {
42
- configuration = configurations.deployerJars
43
- repository(url: mavenLocal().url)
44
+ afterEvaluate {
45
+ publishing {
46
+ publications {
47
+ release(MavenPublication) {
48
+ from components.release
49
+ // Add additional sourcesJar to artifacts
50
+ artifact(androidSourcesJar)
51
+ }
52
+ }
53
+ repositories {
54
+ maven {
55
+ url = mavenLocal().url
56
+ }
44
57
  }
45
58
  }
46
59
  }
47
60
 
48
61
  android {
49
- compileSdkVersion safeExtGet("compileSdkVersion", 30)
62
+ compileSdkVersion safeExtGet("compileSdkVersion", 31)
50
63
 
51
64
  compileOptions {
52
- sourceCompatibility JavaVersion.VERSION_1_8
53
- targetCompatibility JavaVersion.VERSION_1_8
65
+ sourceCompatibility JavaVersion.VERSION_11
66
+ targetCompatibility JavaVersion.VERSION_11
67
+ }
68
+
69
+ kotlinOptions {
70
+ jvmTarget = JavaVersion.VERSION_11.majorVersion
54
71
  }
55
72
 
56
73
  defaultConfig {
57
74
  minSdkVersion safeExtGet("minSdkVersion", 21)
58
- targetSdkVersion safeExtGet("targetSdkVersion", 30)
75
+ targetSdkVersion safeExtGet("targetSdkVersion", 31)
59
76
  consumerProguardFiles 'proguard-rules.pro'
60
77
  versionCode 1
61
- versionName "0.6.4"
78
+ versionName "0.8.0"
62
79
  }
63
80
  lintOptions {
64
81
  abortOnError false
65
82
  }
66
- kotlinOptions {
67
- jvmTarget = JavaVersion.VERSION_1_8
68
- }
69
83
 
70
84
  testOptions {
71
85
  unitTests.all {
@@ -81,12 +95,10 @@ android {
81
95
  }
82
96
 
83
97
  dependencies {
84
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${safeExtGet('kotlinVersion', '1.4.21')}"
85
- implementation "org.jetbrains.kotlin:kotlin-reflect:${safeExtGet('kotlinVersion', '1.4.21')}"
98
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
99
+ implementation "org.jetbrains.kotlin:kotlin-reflect:${getKotlinVersion()}"
86
100
  implementation 'androidx.annotation:annotation:1.2.0'
87
-
88
- // used only in `expo.modules.core.errors.ModuleDestroyedException` for API export
89
- compileOnly("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3")
101
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0"
90
102
 
91
103
  //noinspection GradleDynamicVersion
92
104
  implementation 'com.facebook.react:react-native:+'
@@ -95,6 +107,8 @@ dependencies {
95
107
  testImplementation 'junit:junit:4.13.1'
96
108
  testImplementation 'io.mockk:mockk:1.10.6'
97
109
  testImplementation "com.google.truth:truth:1.1.2"
110
+ testImplementation "org.robolectric:robolectric:4.5.1"
111
+ testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0"
98
112
  }
99
113
 
100
114
  /**
@@ -36,7 +36,7 @@ import javax.annotation.Nullable;
36
36
  */
37
37
  public class NativeModulesProxy extends ReactContextBaseJavaModule {
38
38
  private final static String NAME = "NativeUnimoduleProxy";
39
- private final static String VIEW_MANAGERS_NAMES_KEY = "viewManagersNames";
39
+ private final static String VIEW_MANAGERS_METADATA_KEY = "viewManagersMetadata";
40
40
  private final static String MODULES_CONSTANTS_KEY = "modulesConstants";
41
41
  private final static String EXPORTED_METHODS_KEY = "exportedMethods";
42
42
 
@@ -97,7 +97,7 @@ public class NativeModulesProxy extends ReactContextBaseJavaModule {
97
97
 
98
98
  Map<String, Object> modulesConstants = new HashMap<>(exportedModules.size());
99
99
  Map<String, Object> exportedMethodsMap = new HashMap<>(exportedModules.size());
100
- List<String> viewManagersNames = new ArrayList<>(viewManagers.size());
100
+ Map<String, Object> viewManagersMetadata = new HashMap<>(viewManagers.size());
101
101
 
102
102
  for (ExportedModule exportedModule : exportedModules) {
103
103
  String moduleName = exportedModule.getName();
@@ -116,15 +116,15 @@ public class NativeModulesProxy extends ReactContextBaseJavaModule {
116
116
  }));
117
117
 
118
118
  for (ViewManager viewManager : viewManagers) {
119
- viewManagersNames.add(viewManager.getName());
119
+ viewManagersMetadata.put(viewManager.getName(), viewManager.getMetadata());
120
120
  }
121
121
 
122
- viewManagersNames.addAll(mKotlinInteropModuleRegistry.exportedViewManagersNames());
122
+ viewManagersMetadata.putAll(mKotlinInteropModuleRegistry.viewManagersMetadata());
123
123
 
124
124
  Map<String, Object> constants = new HashMap<>(3);
125
125
  constants.put(MODULES_CONSTANTS_KEY, modulesConstants);
126
126
  constants.put(EXPORTED_METHODS_KEY, exportedMethodsMap);
127
- constants.put(VIEW_MANAGERS_NAMES_KEY, viewManagersNames);
127
+ constants.put(VIEW_MANAGERS_METADATA_KEY, viewManagersMetadata);
128
128
  return constants;
129
129
  }
130
130
 
@@ -6,6 +6,7 @@ import android.util.Log;
6
6
  import android.view.View;
7
7
 
8
8
  import com.facebook.react.bridge.ReactContext;
9
+ import com.facebook.react.turbomodule.core.CallInvokerHolderImpl;
9
10
  import com.facebook.react.uimanager.IllegalViewOperationException;
10
11
  import com.facebook.react.uimanager.NativeViewHierarchyManager;
11
12
  import com.facebook.react.uimanager.UIManagerModule;
@@ -115,6 +116,14 @@ public class UIManagerModuleWrapper implements
115
116
  }
116
117
  }
117
118
 
119
+ public void runOnNativeModulesQueueThread(Runnable runnable) {
120
+ if (mReactContext.isOnNativeModulesQueueThread()) {
121
+ runnable.run();
122
+ } else {
123
+ mReactContext.runOnNativeModulesQueueThread(runnable);
124
+ }
125
+ }
126
+
118
127
 
119
128
  @Override
120
129
  public void registerLifecycleEventListener(final LifecycleEventListener listener) {
@@ -188,6 +197,10 @@ public class UIManagerModuleWrapper implements
188
197
  return mReactContext.getJavaScriptContextHolder().get();
189
198
  }
190
199
 
200
+ public CallInvokerHolderImpl getJSCallInvokerHolder() {
201
+ return (CallInvokerHolderImpl) mReactContext.getCatalystInstance().getJSCallInvokerHolder();
202
+ }
203
+
191
204
  @Override
192
205
  public Activity getCurrentActivity() {
193
206
  return getContext().getCurrentActivity();
@@ -50,6 +50,15 @@ public abstract class ViewManager<V extends View> implements RegistryLifecycleLi
50
50
  // by default do nothing
51
51
  }
52
52
 
53
+ /**
54
+ * Returns a map of view manager's metadata that will be exposed to JavaScript.
55
+ */
56
+ public Map<String, Object> getMetadata() {
57
+ Map<String, Object> metadata = new HashMap<>();
58
+ metadata.put("propsNames", getPropSetters().keySet().toArray());
59
+ return metadata;
60
+ }
61
+
53
62
  /**
54
63
  * Returns a map of { propName => propInfo } so that platform adapter knows value of what class
55
64
  * does the propsetter expect.
@@ -1,5 +1,9 @@
1
1
  package expo.modules.core.interfaces;
2
2
 
3
+ import com.facebook.react.turbomodule.core.CallInvokerHolderImpl;
4
+
3
5
  public interface JavaScriptContextProvider {
4
6
  long getJavaScriptContextRef();
7
+
8
+ CallInvokerHolderImpl getJSCallInvokerHolder();
5
9
  }
@@ -1,12 +1,17 @@
1
1
  package expo.modules.core.interfaces;
2
2
 
3
3
  import android.app.Activity;
4
+ import android.view.KeyEvent;
5
+ import android.view.ViewGroup;
6
+
7
+ import com.facebook.react.ReactActivity;
8
+ import com.facebook.react.ReactActivityDelegate;
4
9
  import com.facebook.react.ReactRootView;
5
10
 
6
11
  import androidx.annotation.Nullable;
7
12
 
8
13
  /**
9
- * A handler API for modules to override default ReactActivity behaviors.
14
+ * A handler API for modules to override default ReactActivityDelegate behaviors.
10
15
  * Used by {@link ReactActivityDelegateWrapper}
11
16
  */
12
17
  public interface ReactActivityHandler {
@@ -18,4 +23,35 @@ public interface ReactActivityHandler {
18
23
  default ReactRootView createReactRootView(Activity activity) {
19
24
  return null;
20
25
  }
26
+
27
+ /**
28
+ * Gives modules a chance to create a ViewGroup that is used as a container for the ReactRootView,
29
+ * which is added as a child to the container if non-null.
30
+ * @return a ViewGroup to be used as a container, or null if no container is needed
31
+ */
32
+ @Nullable
33
+ default ViewGroup createReactRootViewContainer(Activity activity) {
34
+ return null;
35
+ }
36
+
37
+ /**
38
+ * Gives modules a chance to respond to `onKeyUp` events. Every listener will receive this
39
+ * callback, but the delegate will not receive the event unless if any of the listeners consume it
40
+ * (i.e. return `true` from this method).
41
+ * `ReactActivityDelegateWrapper.onKeyUp` will return `true` if any module returns `true`.
42
+ *
43
+ * @return true if this module wants to return `true` from `ReactActivityDelegateWrapper.onKeyUp`
44
+ */
45
+ default boolean onKeyUp(int keyCode, KeyEvent event) {
46
+ return false;
47
+ }
48
+
49
+ /**
50
+ * Gives modules a chance to override the wrapped ReactActivityDelegate instance.
51
+ * @return a new ReactActivityDelegate instance, or null if not to override
52
+ */
53
+ @Nullable
54
+ default ReactActivityDelegate onDidCreateReactActivityDelegate(ReactActivity activity, ReactActivityDelegate delegate) {
55
+ return null;
56
+ }
21
57
  }
@@ -2,6 +2,7 @@ package expo.modules.core.interfaces;
2
2
 
3
3
  import com.facebook.react.ReactInstanceManager;
4
4
  import com.facebook.react.bridge.JavaScriptContextHolder;
5
+ import com.facebook.react.bridge.JavaScriptExecutorFactory;
5
6
  import com.facebook.react.bridge.ReactApplicationContext;
6
7
 
7
8
  import androidx.annotation.Nullable;
@@ -42,6 +43,24 @@ public interface ReactNativeHostHandler {
42
43
  return null;
43
44
  }
44
45
 
46
+ /**
47
+ * Given chance for modules to override react dev support manager factory.
48
+ * e.g. for expo-dev-client
49
+ *
50
+ * Note: we can't specify the type here, because the `DevSupportManagerFactory`
51
+ * doesn't exist in the React Native 0.66 or below.
52
+ *
53
+ * @return custom DevSupportManagerFactory, or null if not to override
54
+ */
55
+ @Nullable
56
+ default Object getDevSupportManagerFactory() { return null; }
57
+
58
+ /**
59
+ * Given chance for modules to override the javascript executor factory.
60
+ */
61
+ @Nullable
62
+ default JavaScriptExecutorFactory getJavaScriptExecutorFactory() { return null; }
63
+
45
64
  //region event listeners
46
65
 
47
66
  /**
@@ -28,6 +28,8 @@ public interface UIManager {
28
28
 
29
29
  void runOnClientCodeQueueThread(Runnable runnable);
30
30
 
31
+ void runOnNativeModulesQueueThread(Runnable runnable);
32
+
31
33
  void registerLifecycleEventListener(LifecycleEventListener listener);
32
34
 
33
35
  void unregisterLifecycleEventListener(LifecycleEventListener listener);
@@ -5,7 +5,6 @@ import android.content.Context
5
5
  import android.content.Intent
6
6
  import com.facebook.react.bridge.ReactApplicationContext
7
7
  import expo.modules.core.interfaces.ActivityProvider
8
- import expo.modules.core.interfaces.services.EventEmitter
9
8
  import expo.modules.interfaces.barcodescanner.BarCodeScannerInterface
10
9
  import expo.modules.interfaces.camera.CameraViewInterface
11
10
  import expo.modules.interfaces.constants.ConstantsInterface
@@ -15,8 +14,11 @@ import expo.modules.interfaces.imageloader.ImageLoaderInterface
15
14
  import expo.modules.interfaces.permissions.Permissions
16
15
  import expo.modules.interfaces.sensors.SensorServiceInterface
17
16
  import expo.modules.interfaces.taskManager.TaskManagerInterface
17
+ import expo.modules.kotlin.defaultmodules.ErrorManagerModule
18
+ import expo.modules.kotlin.events.EventEmitter
18
19
  import expo.modules.kotlin.events.EventName
19
20
  import expo.modules.kotlin.events.KEventEmitterWrapper
21
+ import expo.modules.kotlin.events.KModuleEventEmitterWrapper
20
22
  import expo.modules.kotlin.events.OnActivityResultPayload
21
23
  import expo.modules.kotlin.modules.Module
22
24
  import java.lang.ref.WeakReference
@@ -26,7 +28,10 @@ class AppContext(
26
28
  val legacyModuleRegistry: expo.modules.core.ModuleRegistry,
27
29
  private val reactContextHolder: WeakReference<ReactApplicationContext>
28
30
  ) {
29
- val registry = ModuleRegistry(WeakReference(this)).register(modulesProvider)
31
+ val registry = ModuleRegistry(WeakReference(this)).apply {
32
+ register(ErrorManagerModule())
33
+ register(modulesProvider)
34
+ }
30
35
  private val reactLifecycleDelegate = ReactLifecycleDelegate(this)
31
36
 
32
37
  init {
@@ -119,18 +124,31 @@ class AppContext(
119
124
  * Provides access to the event emitter
120
125
  */
121
126
  fun eventEmitter(module: Module): EventEmitter? {
122
- val legacyEventEmitter = legacyModule<EventEmitter>() ?: return null
123
- return KEventEmitterWrapper(
127
+ val legacyEventEmitter = legacyModule<expo.modules.core.interfaces.services.EventEmitter>()
128
+ ?: return null
129
+ return KModuleEventEmitterWrapper(
124
130
  requireNotNull(registry.getModuleHolder(module)) {
125
131
  "Cannot create an event emitter for the module that isn't present in the module registry."
126
132
  },
127
- legacyEventEmitter
133
+ legacyEventEmitter,
134
+ reactContextHolder
128
135
  )
129
136
  }
130
137
 
138
+ internal val callbackInvoker: EventEmitter?
139
+ get() {
140
+ val legacyEventEmitter = legacyModule<expo.modules.core.interfaces.services.EventEmitter>()
141
+ ?: return null
142
+ return KEventEmitterWrapper(legacyEventEmitter, reactContextHolder)
143
+ }
144
+
145
+ internal val errorManager: ErrorManagerModule?
146
+ get() = registry.getModule()
147
+
131
148
  fun onDestroy() {
132
149
  reactContextHolder.get()?.removeLifecycleEventListener(reactLifecycleDelegate)
133
150
  registry.post(EventName.MODULE_DESTROY)
151
+ registry.cleanUp()
134
152
  }
135
153
 
136
154
  fun onHostResume() {
@@ -3,7 +3,9 @@ package expo.modules.kotlin
3
3
  import com.facebook.react.bridge.Dynamic
4
4
 
5
5
  inline fun <T> Dynamic.recycle(block: Dynamic.() -> T): T {
6
- val result = block(this)
7
- this.recycle()
8
- return result
6
+ try {
7
+ return block(this)
8
+ } finally {
9
+ this.recycle()
10
+ }
9
11
  }
@@ -1,20 +1,15 @@
1
1
  package expo.modules.kotlin
2
2
 
3
- import android.os.Bundle
4
- import com.facebook.react.bridge.Arguments
3
+ import expo.modules.kotlin.types.JSTypeConverter
5
4
 
6
5
  class KPromiseWrapper(
7
6
  private val bridgePromise: com.facebook.react.bridge.Promise
8
7
  ) : Promise {
9
8
 
9
+ @Suppress("UNCHECKED_CAST")
10
10
  override fun resolve(value: Any?) {
11
11
  bridgePromise.resolve(
12
- when (value) {
13
- is Unit -> null
14
- is Bundle -> Arguments.fromBundle(value as Bundle?)
15
- is List<*> -> Arguments.fromList(value as List<*>?)
16
- else -> value
17
- }
12
+ JSTypeConverter.convertToJSValue(value)
18
13
  )
19
14
  }
20
15
 
@@ -3,6 +3,8 @@ package expo.modules.kotlin
3
3
  import com.facebook.react.bridge.ReactApplicationContext
4
4
  import com.facebook.react.bridge.ReadableArray
5
5
  import com.facebook.react.uimanager.ViewManager
6
+ import expo.modules.kotlin.exception.CodedException
7
+ import expo.modules.kotlin.exception.UnexpectedException
6
8
  import expo.modules.kotlin.views.GroupViewManagerWrapper
7
9
  import expo.modules.kotlin.views.SimpleViewManagerWrapper
8
10
  import expo.modules.kotlin.views.ViewManagerWrapperDelegate
@@ -18,7 +20,7 @@ class KotlinInteropModuleRegistry(
18
20
  legacyModuleRegistry: expo.modules.core.ModuleRegistry,
19
21
  reactContext: WeakReference<ReactApplicationContext>
20
22
  ) {
21
- private val appContext = AppContext(modulesProvider, legacyModuleRegistry, reactContext)
23
+ internal val appContext = AppContext(modulesProvider, legacyModuleRegistry, reactContext)
22
24
 
23
25
  private val registry: ModuleRegistry
24
26
  get() = appContext.registry
@@ -26,9 +28,16 @@ class KotlinInteropModuleRegistry(
26
28
  fun hasModule(name: String): Boolean = registry.hasModule(name)
27
29
 
28
30
  fun callMethod(moduleName: String, method: String, arguments: ReadableArray, promise: Promise) {
29
- registry
30
- .getModuleHolder(moduleName)
31
- ?.call(method, arguments, promise)
31
+ try {
32
+ requireNotNull(
33
+ registry.getModuleHolder(moduleName)
34
+ ) { "Trying to call '$method' on the non-existing module '$moduleName'" }
35
+ .call(method, arguments, promise)
36
+ } catch (e: CodedException) {
37
+ promise.reject(e)
38
+ } catch (e: Throwable) {
39
+ promise.reject(UnexpectedException(e))
40
+ }
32
41
  }
33
42
 
34
43
  fun exportedModulesConstants(): Map<ModuleName, ModuleConstants> {
@@ -66,6 +75,17 @@ class KotlinInteropModuleRegistry(
66
75
  }
67
76
  }
68
77
 
78
+ fun viewManagersMetadata(): Map<String, Map<String, Any>> {
79
+ return registry
80
+ .filter { it.definition.viewManagerDefinition != null }
81
+ .map { holder ->
82
+ holder.name to mapOf(
83
+ "propsNames" to (holder.definition.viewManagerDefinition?.propsNames ?: emptyList())
84
+ )
85
+ }
86
+ .toMap()
87
+ }
88
+
69
89
  fun extractViewManagersDelegateHolders(viewManagers: List<ViewManager<*, *>>): List<ViewWrapperDelegateHolder> =
70
90
  viewManagers.filterIsInstance<ViewWrapperDelegateHolder>()
71
91
 
@@ -87,11 +107,6 @@ class KotlinInteropModuleRegistry(
87
107
  }
88
108
  }
89
109
 
90
- fun exportedViewManagersNames(): List<String> =
91
- registry
92
- .filter { it.definition.viewManagerDefinition != null }
93
- .map { it.definition.name }
94
-
95
110
  fun onDestroy() {
96
111
  appContext.onDestroy()
97
112
  }
@@ -1,25 +1,26 @@
1
1
  package expo.modules.kotlin
2
2
 
3
3
  import com.facebook.react.bridge.ReadableArray
4
- import expo.modules.core.utilities.ifNull
5
4
  import expo.modules.kotlin.events.BasicEventListener
6
5
  import expo.modules.kotlin.events.EventListenerWithPayload
7
6
  import expo.modules.kotlin.events.EventListenerWithSenderAndPayload
8
7
  import expo.modules.kotlin.events.EventName
8
+ import expo.modules.kotlin.exception.FunctionCallException
9
9
  import expo.modules.kotlin.exception.MethodNotFoundException
10
+ import expo.modules.kotlin.exception.exceptionDecorator
10
11
  import expo.modules.kotlin.modules.Module
11
12
 
12
13
  class ModuleHolder(val module: Module) {
13
14
  val definition = module.definition()
14
15
  val name get() = definition.name
15
16
 
16
- fun call(methodName: String, args: ReadableArray, promise: Promise) {
17
- val method = definition.methods[methodName].ifNull {
18
- promise.reject(MethodNotFoundException(methodName, definition.name))
19
- return
20
- }
17
+ fun call(methodName: String, args: ReadableArray, promise: Promise) = exceptionDecorator({
18
+ FunctionCallException(methodName, definition.name, it)
19
+ }) {
20
+ val method = definition.methods[methodName]
21
+ ?: throw MethodNotFoundException()
21
22
 
22
- method.call(args, promise)
23
+ method.call(this, args, promise)
23
24
  }
24
25
 
25
26
  fun post(eventName: EventName) {
@@ -38,4 +39,8 @@ class ModuleHolder(val module: Module) {
38
39
  val listener = definition.eventListeners[eventName] ?: return
39
40
  (listener as? EventListenerWithSenderAndPayload<Sender, Payload>)?.call(sender, payload)
40
41
  }
42
+
43
+ fun cleanUp() {
44
+ module.cleanUp()
45
+ }
41
46
  }