expo-modules-core 0.9.2 → 0.10.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 (167) hide show
  1. package/CHANGELOG.md +18 -5
  2. package/android/CMakeLists.txt +154 -0
  3. package/android/build.gradle +293 -5
  4. package/android/src/main/cpp/Exceptions.cpp +22 -0
  5. package/android/src/main/cpp/Exceptions.h +38 -0
  6. package/android/src/main/cpp/ExpoModulesHostObject.cpp +47 -0
  7. package/android/src/main/cpp/ExpoModulesHostObject.h +32 -0
  8. package/android/src/main/cpp/JNIFunctionBody.cpp +29 -0
  9. package/android/src/main/cpp/JNIFunctionBody.h +50 -0
  10. package/android/src/main/cpp/JNIInjector.cpp +19 -0
  11. package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +122 -0
  12. package/android/src/main/cpp/JSIInteropModuleRegistry.h +96 -0
  13. package/android/src/main/cpp/JSIObjectWrapper.h +33 -0
  14. package/android/src/main/cpp/JSITypeConverter.h +84 -0
  15. package/android/src/main/cpp/JavaScriptModuleObject.cpp +138 -0
  16. package/android/src/main/cpp/JavaScriptModuleObject.h +122 -0
  17. package/android/src/main/cpp/JavaScriptObject.cpp +125 -0
  18. package/android/src/main/cpp/JavaScriptObject.h +131 -0
  19. package/android/src/main/cpp/JavaScriptRuntime.cpp +127 -0
  20. package/android/src/main/cpp/JavaScriptRuntime.h +87 -0
  21. package/android/src/main/cpp/JavaScriptValue.cpp +172 -0
  22. package/android/src/main/cpp/JavaScriptValue.h +78 -0
  23. package/android/src/main/cpp/MethodMetadata.cpp +230 -0
  24. package/android/src/main/cpp/MethodMetadata.h +92 -0
  25. package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +2 -0
  26. package/android/src/main/java/expo/modules/core/errors/ContextDestroyedException.kt +7 -0
  27. package/android/src/main/java/expo/modules/interfaces/permissions/Permissions.java +30 -0
  28. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +49 -1
  29. package/android/src/main/java/expo/modules/kotlin/ConcatIterator.kt +18 -0
  30. package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +15 -12
  31. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +39 -3
  32. package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +2 -2
  33. package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +13 -0
  34. package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +2 -0
  35. package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +19 -14
  36. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +29 -7
  37. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +13 -13
  38. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +18 -0
  39. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +18 -0
  40. package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +56 -0
  41. package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +28 -0
  42. package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +18 -0
  43. package/android/src/main/java/expo/modules/kotlin/jni/JNIFunctionBody.kt +39 -0
  44. package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +89 -0
  45. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +44 -0
  46. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +113 -0
  47. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +35 -0
  48. package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +15 -5
  49. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +65 -111
  50. package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +35 -2
  51. package/android/src/main/java/expo/modules/kotlin/providers/AppContextProvider.kt +14 -0
  52. package/android/src/main/java/expo/modules/kotlin/providers/CurrentActivityProvider.kt +22 -0
  53. package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +19 -2
  54. package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +3 -2
  55. package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +7 -2
  56. package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +68 -20
  57. package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +50 -22
  58. package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +18 -2
  59. package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +18 -2
  60. package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +17 -2
  61. package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +43 -3
  62. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +5 -0
  63. package/build/NativeModulesProxy.native.d.ts.map +1 -1
  64. package/build/NativeModulesProxy.native.js +9 -3
  65. package/build/NativeModulesProxy.native.js.map +1 -1
  66. package/ios/AppDelegates/EXAppDelegatesLoader.m +1 -2
  67. package/ios/ExpoModulesCore.podspec +1 -1
  68. package/ios/JSI/EXJSIConversions.mm +6 -0
  69. package/ios/JSI/EXJSIInstaller.h +15 -21
  70. package/ios/JSI/EXJSIInstaller.mm +39 -3
  71. package/ios/JSI/EXJSIUtils.h +47 -3
  72. package/ios/JSI/EXJSIUtils.mm +88 -4
  73. package/ios/JSI/EXJavaScriptObject.h +11 -18
  74. package/ios/JSI/EXJavaScriptObject.mm +37 -18
  75. package/ios/JSI/EXJavaScriptRuntime.h +43 -9
  76. package/ios/JSI/EXJavaScriptRuntime.mm +70 -27
  77. package/ios/JSI/EXJavaScriptTypedArray.h +30 -0
  78. package/ios/JSI/EXJavaScriptTypedArray.mm +29 -0
  79. package/ios/JSI/EXJavaScriptValue.h +3 -2
  80. package/ios/JSI/EXJavaScriptValue.mm +17 -20
  81. package/ios/JSI/EXJavaScriptWeakObject.h +23 -0
  82. package/ios/JSI/EXJavaScriptWeakObject.mm +53 -0
  83. package/ios/JSI/EXObjectDeallocator.h +27 -0
  84. package/ios/JSI/ExpoModulesHostObject.h +3 -3
  85. package/ios/JSI/ExpoModulesHostObject.mm +4 -4
  86. package/ios/JSI/JavaScriptRuntime.swift +38 -1
  87. package/ios/JSI/JavaScriptValue.swift +7 -0
  88. package/ios/JSI/TypedArray.cpp +67 -0
  89. package/ios/JSI/TypedArray.h +46 -0
  90. package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -11
  91. package/ios/NativeModulesProxy/EXNativeModulesProxy.h +17 -10
  92. package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +85 -77
  93. package/ios/NativeModulesProxy/NativeModulesProxyModule.swift +17 -0
  94. package/ios/Services/EXReactNativeEventEmitter.h +2 -2
  95. package/ios/Services/EXReactNativeEventEmitter.m +11 -6
  96. package/ios/Swift/AppContext.swift +208 -28
  97. package/ios/Swift/Arguments/AnyArgument.swift +18 -0
  98. package/ios/Swift/Arguments/{Types/EnumArgumentType.swift → EnumArgument.swift} +2 -17
  99. package/ios/Swift/Classes/ClassComponent.swift +95 -0
  100. package/ios/Swift/Classes/ClassComponentElement.swift +33 -0
  101. package/ios/Swift/Classes/ClassComponentElementsBuilder.swift +34 -0
  102. package/ios/Swift/Classes/ClassComponentFactories.swift +96 -0
  103. package/ios/Swift/DynamicTypes/AnyDynamicType.swift +44 -0
  104. package/ios/Swift/DynamicTypes/DynamicArrayType.swift +56 -0
  105. package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +27 -0
  106. package/ios/Swift/DynamicTypes/DynamicEnumType.swift +27 -0
  107. package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +63 -0
  108. package/ios/Swift/DynamicTypes/DynamicRawType.swift +33 -0
  109. package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +37 -0
  110. package/ios/Swift/DynamicTypes/DynamicType.swift +39 -0
  111. package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +46 -0
  112. package/ios/Swift/Exceptions/CodedError.swift +1 -1
  113. package/ios/Swift/Exceptions/Exception.swift +8 -6
  114. package/ios/Swift/Exceptions/UnexpectedException.swift +2 -1
  115. package/ios/Swift/ExpoBridgeModule.m +5 -0
  116. package/ios/Swift/ExpoBridgeModule.swift +65 -0
  117. package/ios/Swift/Functions/AnyFunction.swift +33 -31
  118. package/ios/Swift/Functions/AsyncFunctionComponent.swift +196 -59
  119. package/ios/Swift/Functions/SyncFunctionComponent.swift +142 -58
  120. package/ios/Swift/JavaScriptUtils.swift +32 -57
  121. package/ios/Swift/Logging/LogHandlers.swift +39 -0
  122. package/ios/Swift/Logging/LogType.swift +62 -0
  123. package/ios/Swift/Logging/Logger.swift +198 -0
  124. package/ios/Swift/ModuleHolder.swift +19 -54
  125. package/ios/Swift/ModuleRegistry.swift +7 -1
  126. package/ios/Swift/Modules/AnyModule.swift +3 -3
  127. package/ios/Swift/ModulesProvider.swift +2 -0
  128. package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +37 -0
  129. package/ios/Swift/Objects/ObjectDefinition.swift +74 -1
  130. package/ios/Swift/Objects/ObjectDefinitionComponents.swift +77 -68
  131. package/ios/Swift/Objects/PropertyComponent.swift +147 -0
  132. package/ios/Swift/Promise.swift +12 -3
  133. package/ios/Swift/Records/Field.swift +2 -2
  134. package/ios/Swift/SharedObjects/SharedObject.swift +20 -0
  135. package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +129 -0
  136. package/ios/Swift/TypedArrays/AnyTypedArray.swift +11 -0
  137. package/ios/Swift/TypedArrays/ConcreteTypedArrays.swift +56 -0
  138. package/ios/Swift/TypedArrays/GenericTypedArray.swift +49 -0
  139. package/ios/Swift/TypedArrays/TypedArray.swift +80 -0
  140. package/ios/Swift/Utilities.swift +28 -0
  141. package/ios/Swift/Views/ConcreteViewProp.swift +3 -3
  142. package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +2 -2
  143. package/ios/Tests/ClassComponentSpec.swift +210 -0
  144. package/ios/Tests/DynamicTypeSpec.swift +336 -0
  145. package/ios/Tests/EnumArgumentSpec.swift +48 -0
  146. package/ios/Tests/ExpoModulesSpec.swift +17 -3
  147. package/ios/Tests/FunctionSpec.swift +167 -118
  148. package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
  149. package/ios/Tests/PropertyComponentSpec.swift +95 -0
  150. package/ios/Tests/SharedObjectRegistrySpec.swift +109 -0
  151. package/ios/Tests/TypedArraysSpec.swift +136 -0
  152. package/package.json +2 -2
  153. package/src/NativeModulesProxy.native.ts +13 -3
  154. package/src/ts-declarations/ExpoModules.d.ts +7 -0
  155. package/tsconfig.json +1 -1
  156. package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +0 -15
  157. package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +0 -36
  158. package/ios/Swift/Arguments/AnyArgumentType.swift +0 -13
  159. package/ios/Swift/Arguments/ArgumentType.swift +0 -28
  160. package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +0 -42
  161. package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +0 -16
  162. package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +0 -49
  163. package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +0 -15
  164. package/ios/Swift/Arguments/Types/RawArgumentType.swift +0 -25
  165. package/ios/Swift/Functions/ConcreteFunction.swift +0 -103
  166. package/ios/Swift/SwiftInteropBridge.swift +0 -155
  167. package/ios/Tests/ArgumentTypeSpec.swift +0 -143
package/CHANGELOG.md CHANGED
@@ -10,17 +10,30 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
- ## 0.9.2 — 2022-05-09
13
+ ## 0.10.0 — 2022-06-23
14
14
 
15
- ### 🐛 Bug fixes
16
-
17
- - Fix view props weren't recognized in the bare workflow on iOS. ([#17411](https://github.com/expo/expo/pull/17411) by [@lukmccall](https://github.com/lukmccall))
15
+ ### 🎉 New features
18
16
 
19
- ## 0.9.1 2022-05-05
17
+ - Add proxy methods for `Permissions` module accepting `expo.modules.kotlin.Promise` on Android. ([#17668](https://github.com/expo/expo/pull/17668) by [@bbarthec](https://github.com/bbarthec))
18
+ - Create `CurrentActivityProvider` on Android. ([#17571](https://github.com/expo/expo/pull/17571) by [@bbarthec](https://github.com/bbarthec))
19
+ - Create `AppContextProvider` on Android. ([#17546](https://github.com/expo/expo/pull/17546) by [@bbarthec](https://github.com/bbarthec))
20
+ - Introduce dynamic properties in the Sweet API on iOS. ([#17318](https://github.com/expo/expo/pull/17318) by [@tsapeta](https://github.com/tsapeta))
21
+ - Implemented classes in the Sweet API on iOS. ([#17514](https://github.com/expo/expo/pull/17514), [#17525](https://github.com/expo/expo/pull/17525) by [@tsapeta](https://github.com/tsapeta))
22
+ - Add basic support for sync functions in the Sweet API on Android. ([#16977](https://github.com/expo/expo/pull/16977) by [@lukmccall](https://github.com/lukmccall))
23
+ - Better error handling in the synchronous functions on iOS. ([#17628](https://github.com/expo/expo/pull/17628) by [@tsapeta](https://github.com/tsapeta))
24
+ - Experimental support for typed arrays on iOS. ([#17667](https://github.com/expo/expo/pull/17667) by [@tsapeta](https://github.com/tsapeta))
20
25
 
21
26
  ### 🐛 Bug fixes
22
27
 
23
28
  - Fix modules have not been deallocated during the application reload on iOS. ([#17285](https://github.com/expo/expo/pull/17285) by [@lukmccall](https://github.com/lukmccall))
29
+ - Fix view props weren't recognized in the bare workflow on iOS. ([#17411](https://github.com/expo/expo/pull/17411) by [@lukmccall](https://github.com/lukmccall))
30
+ - Fix support for optional function arguments on iOS. ([#17950](https://github.com/expo/expo/pull/17950) by [@barthap](https://github.com/barthap))
31
+
32
+ ### 💡 Others
33
+
34
+ - Migrated Expo modules definitions to the new naming convention. ([#17193](https://github.com/expo/expo/pull/17193) by [@tsapeta](https://github.com/tsapeta))
35
+ - Refactored Expo modules registration and the `AppContext` on iOS. ([#17225](https://github.com/expo/expo/pull/17225) by [@tsapeta](https://github.com/tsapeta))
36
+ - Split the implementation of async and sync functions on iOS. ([#17188](https://github.com/expo/expo/pull/17188) by [@tsapeta](https://github.com/tsapeta))
24
37
 
25
38
  ## 0.9.0 — 2022-04-21
26
39
 
@@ -0,0 +1,154 @@
1
+ cmake_minimum_required(VERSION 3.4.1)
2
+
3
+ set(CMAKE_VERBOSE_MAKEFILE ON)
4
+ set(CMAKE_ANDROID_STL_TYPE c++_shared)
5
+ set(CMAKE_CXX_STANDARD 17)
6
+ set(PACKAGE_NAME "expo-modules-core")
7
+ set(BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
8
+
9
+ if (${NATIVE_DEBUG})
10
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g")
11
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g")
12
+ endif ()
13
+
14
+ set(SRC_DIR ${CMAKE_SOURCE_DIR}/src)
15
+ file(GLOB sources_android "${SRC_DIR}/main/cpp/*.cpp")
16
+
17
+ # shared
18
+
19
+ add_library(
20
+ ${PACKAGE_NAME}
21
+ SHARED
22
+ ${sources_android}
23
+ )
24
+
25
+ # Extracted AAR: ${BUILD_DIR}/react-native-0*/jni/${ANDROID_ABI}
26
+ file(GLOB LIBRN_DIR "${REACT_NATIVE_SO_DIR}/${ANDROID_ABI}")
27
+ if (NOT LIBRN_DIR)
28
+ # If /${ANDROID_ABI} dir not found, then ${REACT_NATIVE_SO_DIR} is probably:
29
+ # ReactAndroid/build/react-ndk/exported
30
+ file(GLOB LIBRN_DIR "${REACT_NATIVE_SO_DIR}")
31
+ endif ()
32
+
33
+ file(GLOB libfbjni_include_DIRS "${BUILD_DIR}/fbjni-*-headers.jar/")
34
+ file(GLOB HERMES_SO_DIR "${BUILD_DIR}/third-party-ndk/hermes/jni/${ANDROID_ABI}")
35
+
36
+ # includes
37
+
38
+ target_include_directories(
39
+ ${PACKAGE_NAME}
40
+ PRIVATE
41
+ "${REACT_NATIVE_DIR}/React"
42
+ "${REACT_NATIVE_DIR}/React/Base"
43
+ "${REACT_NATIVE_DIR}/ReactAndroid/src/main/jni"
44
+ "${REACT_NATIVE_DIR}/ReactAndroid/src/main/jni/react"
45
+ "${REACT_NATIVE_DIR}/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni"
46
+ "${REACT_NATIVE_DIR}/ReactCommon"
47
+ "${REACT_NATIVE_DIR}/ReactCommon/react/nativemodule/core"
48
+ "${REACT_NATIVE_DIR}/ReactCommon/callinvoker"
49
+ "${REACT_NATIVE_DIR}/ReactCommon/jsi"
50
+ "${HERMES_DIR}/android/include"
51
+ "${BUILD_DIR}/third-party-ndk/boost/boost_${BOOST_VERSION}"
52
+ "${BUILD_DIR}/third-party-ndk/double-conversion"
53
+ "${BUILD_DIR}/third-party-ndk/folly"
54
+ ${libfbjni_include_DIRS}
55
+ )
56
+
57
+ # find libraries
58
+
59
+ find_library(LOG_LIB log)
60
+
61
+ find_library(
62
+ FOLLY_JSON_LIB
63
+ folly_json
64
+ PATHS ${LIBRN_DIR}
65
+ NO_CMAKE_FIND_ROOT_PATH
66
+ )
67
+
68
+ find_library(
69
+ FBJNI_LIB
70
+ fbjni
71
+ PATHS ${LIBRN_DIR}
72
+ NO_CMAKE_FIND_ROOT_PATH
73
+ )
74
+
75
+ find_library(
76
+ JSI_LIB
77
+ jsi
78
+ PATHS ${LIBRN_DIR}
79
+ NO_CMAKE_FIND_ROOT_PATH
80
+ )
81
+
82
+ find_library(
83
+ REACT_NATIVE_JNI_LIB
84
+ reactnativejni
85
+ PATHS ${LIBRN_DIR}
86
+ NO_CMAKE_FIND_ROOT_PATH
87
+ )
88
+
89
+ find_library(
90
+ REACT_NATIVE_MODULES_CORE
91
+ react_nativemodule_core
92
+ PATHS ${LIBRN_DIR}
93
+ NO_CMAKE_FIND_ROOT_PATH
94
+ )
95
+
96
+ find_library(
97
+ HERMES_LIB
98
+ hermes
99
+ PATHS ${HERMES_SO_DIR}
100
+ NO_CMAKE_FIND_ROOT_PATH
101
+ )
102
+
103
+ find_library(
104
+ JSEXECUTOR_LIB
105
+ jscexecutor
106
+ PATHS ${LIBRN_DIR}
107
+ NO_CMAKE_FIND_ROOT_PATH
108
+ )
109
+
110
+ #reactnativejni
111
+
112
+ # linking
113
+
114
+ target_compile_options(
115
+ ${PACKAGE_NAME}
116
+ PRIVATE -DFOLLY_NO_CONFIG=1
117
+ -DFOLLY_HAVE_CLOCK_GETTIME=1
118
+ -DFOLLY_HAVE_MEMRCHR=1
119
+ -DFOLLY_USE_LIBCPP=1
120
+ -DFOLLY_MOBILE=1
121
+ -DFOR_HERMES=${FOR_HERMES}
122
+ -O2
123
+ -frtti
124
+ -fexceptions
125
+ -Wall
126
+ -fstack-protector-all
127
+ )
128
+
129
+ if (${FOR_HERMES})
130
+ target_link_libraries(
131
+ ${PACKAGE_NAME}
132
+ ${LOG_LIB}
133
+ ${FBJNI_LIB}
134
+ ${JSI_LIB}
135
+ ${HERMES_LIB}
136
+ ${REACT_NATIVE_JNI_LIB}
137
+ ${FOLLY_JSON_LIB}
138
+ ${REACT_NATIVE_MODULES_CORE}
139
+ android
140
+ )
141
+ else ()
142
+ target_link_libraries(
143
+ ${PACKAGE_NAME}
144
+ ${LOG_LIB}
145
+ ${FBJNI_LIB}
146
+ ${JSI_LIB}
147
+ ${JSEXECUTOR_LIB}
148
+ ${REACT_NATIVE_JNI_LIB}
149
+ ${FOLLY_JSON_LIB}
150
+ ${REACT_NATIVE_MODULES_CORE}
151
+ android
152
+ )
153
+ endif ()
154
+
@@ -1,9 +1,12 @@
1
+ import java.nio.file.Paths
2
+
1
3
  apply plugin: 'com.android.library'
2
4
  apply plugin: 'kotlin-android'
3
5
  apply plugin: 'maven-publish'
6
+ apply plugin: "de.undercouch.download"
4
7
 
5
8
  group = 'host.exp.exponent'
6
- version = '0.9.2'
9
+ version = '0.10.0'
7
10
 
8
11
  buildscript {
9
12
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
@@ -32,7 +35,50 @@ buildscript {
32
35
 
33
36
  dependencies {
34
37
  classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
38
+ classpath "de.undercouch:gradle-download-task:4.1.2"
39
+ }
40
+ }
41
+
42
+ def isAndroidTest() {
43
+ Gradle gradle = getGradle()
44
+ String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()
45
+ return tskReqStr.contains("AndroidTest")
46
+ }
47
+
48
+ def downloadsDir = new File("$buildDir/downloads")
49
+ def thirdPartyNdkDir = new File("$buildDir/third-party-ndk")
50
+
51
+ def REACT_NATIVE_DIR = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).parent
52
+ def REACT_NATIVE_BUILD_FROM_SOURCE = findProject(":ReactAndroid") != null
53
+ def REACT_NATIVE_SO_DIR = findProject(":ReactAndroid")
54
+ ? Paths.get(findProject(":ReactAndroid").getProjectDir().toString(), "build", "intermediates", "library_*", "*", "jni")
55
+ : "${buildDir}/react-native-0*/jni"
56
+
57
+ def reactProperties = new Properties()
58
+ file("$REACT_NATIVE_DIR/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
59
+
60
+ def FOLLY_VERSION = reactProperties.getProperty("FOLLY_VERSION")
61
+ def BOOST_VERSION = reactProperties.getProperty("BOOST_VERSION")
62
+ def DOUBLE_CONVERSION_VERSION = reactProperties.getProperty("DOUBLE_CONVERSION_VERSION")
63
+
64
+ def reactNativeThirdParty = new File("$REACT_NATIVE_DIR/ReactAndroid/src/main/jni/third-party")
65
+
66
+ def reactNativeArchitectures() {
67
+ def value = project.getProperties().get("reactNativeArchitectures")
68
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
69
+ }
70
+
71
+ def FOR_HERMES = false
72
+ def HERMES_DIR = new File(["node", "--print", "require.resolve('hermes-engine/package.json')"].execute(null, rootDir).text.trim()).parent
73
+ if (findProject(":app")) {
74
+ def appProjectExt = project(":app").ext
75
+ if (appProjectExt.has("react")) {
76
+ FOR_HERMES = project(":app").ext.react.enableHermes
77
+ } else {
78
+ FOR_HERMES = (findProperty('expo.jsEngine') ?: "jsc") == "hermes"
35
79
  }
80
+ } else {
81
+ FOR_HERMES = (findProperty('expo.jsEngine') ?: "jsc") == "hermes"
36
82
  }
37
83
 
38
84
  // Creating sources with comments
@@ -75,14 +121,74 @@ android {
75
121
  targetSdkVersion safeExtGet("targetSdkVersion", 31)
76
122
  consumerProguardFiles 'proguard-rules.pro'
77
123
  versionCode 1
78
- versionName "0.9.2"
124
+ versionName "0.10.0"
125
+
126
+ testInstrumentationRunner "expo.modules.TestRunner"
127
+
128
+ externalNativeBuild {
129
+ cmake {
130
+ abiFilters (*reactNativeArchitectures())
131
+ arguments "-DREACT_NATIVE_DIR=${REACT_NATIVE_DIR}",
132
+ "-DREACT_NATIVE_SO_DIR=${REACT_NATIVE_SO_DIR}",
133
+ "-DBOOST_VERSION=${BOOST_VERSION}",
134
+ "-DFOR_HERMES=${FOR_HERMES}",
135
+ "-DHERMES_DIR=${HERMES_DIR}"
136
+ }
137
+ }
138
+ }
139
+
140
+ externalNativeBuild {
141
+ cmake {
142
+ path "CMakeLists.txt"
143
+ }
79
144
  }
145
+
146
+ buildFeatures {
147
+ prefab true
148
+ }
149
+
150
+ packagingOptions {
151
+ // Gradle will add cmake target dependencies into packaging.
152
+ // Theses files are intermediated linking files to build modules-core and should not be in final package.
153
+ def sharedLibraries = [
154
+ "**/libc++_shared.so",
155
+ "**/libreactnativejni.so",
156
+ "**/libreact_nativemodule_core.so",
157
+ "**/libglog.so",
158
+ "**/libjscexecutor.so",
159
+ "**/libfbjni.so",
160
+ "**/libfolly_json.so",
161
+ "**/libhermes.so",
162
+ "**/libjsi.so",
163
+ ]
164
+
165
+ // In android (instrumental) tests, we want to package all so files to enable our JSI functionality.
166
+ // Otherwise, those files should be excluded, because will be loaded by the application.
167
+ if (isAndroidTest()) {
168
+ excludes = [
169
+ "META-INF/MANIFEST.MF",
170
+ "META-INF/com.android.tools/proguard/coroutines.pro",
171
+ "META-INF/proguard/coroutines.pro"
172
+ ]
173
+ pickFirsts = sharedLibraries
174
+ } else {
175
+ excludes = sharedLibraries
176
+ }
177
+ }
178
+
179
+ configurations {
180
+ extractHeaders
181
+ extractJNI
182
+ }
183
+
80
184
  lintOptions {
81
185
  abortOnError false
82
186
  }
83
187
 
84
188
  testOptions {
85
- unitTests.all {
189
+ unitTests.includeAndroidResources = true
190
+
191
+ unitTests.all { test ->
86
192
  testLogging {
87
193
  outputs.upToDateWhen { false }
88
194
  events "passed", "failed", "skipped", "standardError"
@@ -94,21 +200,62 @@ android {
94
200
  }
95
201
  }
96
202
 
203
+
97
204
  dependencies {
98
205
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
99
206
  implementation "org.jetbrains.kotlin:kotlin-reflect:${getKotlinVersion()}"
100
- implementation 'androidx.annotation:annotation:1.2.0'
207
+ implementation 'androidx.annotation:annotation:1.3.0'
101
208
  implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0"
209
+ /**
210
+ * ReactActivity (the base activity for every React Native application) is subclassing AndroidX classes.
211
+ * Unfortunately until https://github.com/facebook/react-native/pull/33072 is released React Native uses "androidx.appcompat:appcompat:1.0.2".
212
+ * Gradle is picking the highest version of the dependency so we enforce higher version here.
213
+ * see https://docs.gradle.org/current/userguide/dependency_resolution.html#sec:version-conflict
214
+ * We're enforcing the most up-to-date versions of the dependencies here that are used in subclassing chain for ReactActivity.
215
+ */
216
+ implementation "androidx.appcompat:appcompat:1.4.1"
217
+ implementation "androidx.activity:activity-ktx:1.4.0" // androidx.appcompat:appcompat:1.4.1 depends on version 1.2.3, so we enforce higher one here
218
+ implementation "androidx.fragment:fragment-ktx:1.4.1" // androidx.appcomapt:appcompat:1.4.1 depends on version 1.3.4, so we enforce higher one here
102
219
 
103
220
  //noinspection GradleDynamicVersion
104
221
  implementation 'com.facebook.react:react-native:+'
105
222
 
223
+ compileOnly 'com.facebook.fbjni:fbjni:0.2.2'
224
+ extractHeaders 'com.facebook.fbjni:fbjni:0.2.2:headers'
225
+ extractJNI 'com.facebook.fbjni:fbjni:0.2.2'
226
+ def rnAARs = fileTree("${REACT_NATIVE_DIR}/android").matching { include "**/*.aar" }
227
+ if (rnAARs.any()) {
228
+ // node_modules/react-native has a .aar, extract headers
229
+ if (rnAARs.size() > 1) {
230
+ logger.error("More than one React Native AAR file has been found:")
231
+ rnAARs.each { println(it) }
232
+ throw new GradleException("Multiple React Native AARs found:\n${rnAARs.join("\n")}" +
233
+ "\nRemove the old ones and try again")
234
+ }
235
+ def rnAAR = rnAARs.singleFile
236
+ extractJNI(files(rnAAR))
237
+ }
238
+ // else - there is no prebuilt react-native.aar, this is most likely Expo Go
239
+
106
240
  testImplementation 'androidx.test:core:1.4.0'
107
241
  testImplementation 'junit:junit:4.13.1'
108
- testImplementation 'io.mockk:mockk:1.10.6'
242
+ testImplementation 'io.mockk:mockk:1.12.3'
109
243
  testImplementation "com.google.truth:truth:1.1.2"
110
244
  testImplementation "org.robolectric:robolectric:4.5.1"
111
245
  testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0"
246
+
247
+ androidTestImplementation 'androidx.test:runner:1.4.0'
248
+ androidTestImplementation 'androidx.test:core:1.4.0'
249
+ androidTestImplementation 'androidx.test:rules:1.4.0'
250
+ androidTestImplementation "io.mockk:mockk-android:1.12.3"
251
+ androidTestImplementation "com.google.truth:truth:1.1.2"
252
+ androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0"
253
+
254
+ if (FOR_HERMES) {
255
+ androidTestImplementation files(new File(HERMES_DIR, "android/hermes-debug.aar"))
256
+ } else {
257
+ androidTestImplementation "org.webkit:android-jsc:+"
258
+ }
112
259
  }
113
260
 
114
261
  /**
@@ -120,3 +267,144 @@ dependencies {
120
267
  tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
121
268
  kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
122
269
  }
270
+
271
+ // UTILS
272
+ task createNativeDepsDirectories() {
273
+ downloadsDir.mkdirs()
274
+ thirdPartyNdkDir.mkdirs()
275
+ }
276
+ // END UTILS
277
+
278
+ // JNI
279
+ task extractAARHeaders {
280
+ doLast {
281
+ configurations.extractHeaders.files.each {
282
+ def file = it.absoluteFile
283
+ copy {
284
+ from zipTree(file)
285
+ into "$buildDir/$file.name"
286
+ include "**/*.h"
287
+ }
288
+ }
289
+ }
290
+ }
291
+
292
+ task extractJNIFiles {
293
+ doLast {
294
+ configurations.extractJNI.files.each {
295
+ def file = it.absoluteFile
296
+ copy {
297
+ from zipTree(file)
298
+ into "$buildDir/$file.name"
299
+ include "jni/**/*"
300
+ }
301
+ }
302
+ }
303
+ }
304
+ // END JNI
305
+
306
+ // BOOST
307
+ task downloadBoost(dependsOn: createNativeDepsDirectories, type: Download) {
308
+ src("https://github.com/react-native-community/boost-for-react-native/releases/download/v${BOOST_VERSION.replace("_", ".")}-0/boost_${BOOST_VERSION}.tar.gz")
309
+ onlyIfNewer(true)
310
+ overwrite(false)
311
+ dest(new File(downloadsDir, "boost_${BOOST_VERSION}.tar.gz"))
312
+ }
313
+
314
+ task prepareBoost(dependsOn: [downloadBoost], type: Copy) {
315
+ from(tarTree(resources.gzip(downloadBoost.dest)))
316
+ from("$reactNativeThirdParty/boost/Android.mk")
317
+ include("Android.mk", "boost_${BOOST_VERSION}/boost/**/*.hpp", "boost/boost/**/*.hpp")
318
+ includeEmptyDirs = false
319
+ into("$thirdPartyNdkDir/boost")
320
+ doLast {
321
+ file("$thirdPartyNdkDir/boost/boost").renameTo("$thirdPartyNdkDir/boost/boost_${BOOST_VERSION}")
322
+ }
323
+ }
324
+ // END BOOST
325
+
326
+ // DOUBLE CONVERSION
327
+ task downloadDoubleConversion(dependsOn: createNativeDepsDirectories, type: Download) {
328
+ src("https://github.com/google/double-conversion/archive/v${DOUBLE_CONVERSION_VERSION}.tar.gz")
329
+ onlyIfNewer(true)
330
+ overwrite(false)
331
+ dest(new File(downloadsDir, "double-conversion-${DOUBLE_CONVERSION_VERSION}.tar.gz"))
332
+ }
333
+
334
+ task prepareDoubleConversion(dependsOn: [downloadDoubleConversion], type: Copy) {
335
+ from(tarTree(downloadDoubleConversion.dest))
336
+ from("$reactNativeThirdParty/double-conversion/Android.mk")
337
+ include("double-conversion-${DOUBLE_CONVERSION_VERSION}/src/**/*", "Android.mk")
338
+ filesMatching("*/src/**/*", { fname -> fname.path = "double-conversion/${fname.name}" })
339
+ includeEmptyDirs = false
340
+ into("$thirdPartyNdkDir/double-conversion")
341
+ }
342
+ // END DOUBLE CONVERSION
343
+
344
+ // FOLLY
345
+ task downloadFolly(dependsOn: createNativeDepsDirectories, type: Download) {
346
+ src("https://github.com/facebook/folly/archive/v${FOLLY_VERSION}.tar.gz")
347
+ onlyIfNewer(true)
348
+ overwrite(false)
349
+ dest(new File(downloadsDir, "folly-${FOLLY_VERSION}.tar.gz"))
350
+ }
351
+
352
+ task prepareFolly(dependsOn: [downloadFolly], type: Copy) {
353
+ from(tarTree(downloadFolly.dest))
354
+ from("$reactNativeThirdParty/folly/Android.mk")
355
+ include("folly-${FOLLY_VERSION}/folly/**/*", "Android.mk")
356
+ eachFile { fname -> fname.path = (fname.path - "folly-${FOLLY_VERSION}/") }
357
+ // Fixes problem with Folly failing to build on certain systems. See
358
+ // https://github.com/software-mansion/react-native-reanimated/issues/1024
359
+ def follyReplaceContent = '''
360
+ ssize_t r;
361
+ do {
362
+ r = open(name, flags, mode);
363
+ } while (r == -1 && errno == EINTR);
364
+ return r;
365
+ '''
366
+ filter { line -> line.replaceAll("return int\\(wrapNoInt\\(open, name, flags, mode\\)\\);", follyReplaceContent) }
367
+ includeEmptyDirs = false
368
+ into("$thirdPartyNdkDir/folly")
369
+ }
370
+ // END FOLLy
371
+
372
+ task prepareHermes() {
373
+ if (!FOR_HERMES) {
374
+ return
375
+ }
376
+
377
+ def hermesAAR = file("$HERMES_DIR/android/hermes-debug.aar")
378
+ if (!hermesAAR.exists()) {
379
+ throw new GradleScriptException("The hermes-engine npm package is missing \"android/hermes-debug.aar\"", null)
380
+ }
381
+
382
+ def soFiles = zipTree(hermesAAR).matching({ it.include "**/*.so" })
383
+
384
+ copy {
385
+ from soFiles
386
+ from "$REACT_NATIVE_DIR/ReactAndroid/src/main/jni/first-party/hermes/Android.mk"
387
+ into "$thirdPartyNdkDir/hermes"
388
+ }
389
+ }
390
+
391
+ task prepareThirdPartyNdkHeaders(dependsOn: [prepareBoost, prepareDoubleConversion, prepareFolly, prepareHermes]) {}
392
+
393
+ afterEvaluate {
394
+ extractAARHeaders.dependsOn(prepareThirdPartyNdkHeaders)
395
+ extractJNIFiles.dependsOn(prepareThirdPartyNdkHeaders)
396
+ }
397
+
398
+ tasks.whenTaskAdded { task ->
399
+ if (!task.name.contains("Clean") && (task.name.contains('externalNativeBuild') || task.name.startsWith('configureCMake'))) {
400
+ task.dependsOn(extractAARHeaders)
401
+ task.dependsOn(extractJNIFiles)
402
+ if (REACT_NATIVE_BUILD_FROM_SOURCE) {
403
+ def buildType = task.name.endsWith('Debug') ? 'Debug' : 'Release'
404
+ task.dependsOn(":ReactAndroid:copy${buildType}JniLibsProjectOnly")
405
+ }
406
+ } else if (task.name.startsWith('generateJsonModel') && REACT_NATIVE_BUILD_FROM_SOURCE) {
407
+ def buildType = task.name.endsWith('Debug') ? 'Debug' : 'Release'
408
+ task.dependsOn(":ReactAndroid:copy${buildType}JniLibsProjectOnly")
409
+ }
410
+ }
@@ -0,0 +1,22 @@
1
+ // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2
+
3
+ #include "Exceptions.h"
4
+
5
+ namespace jni = facebook::jni;
6
+
7
+ namespace expo {
8
+
9
+ jni::local_ref<CodedException> CodedException::create(const std::string &message) {
10
+ return CodedException::newInstance(jni::make_jstring(message));
11
+ }
12
+
13
+ jni::local_ref<JavaScriptEvaluateException> JavaScriptEvaluateException::create(
14
+ const std::string &message,
15
+ const std::string &jsStack
16
+ ) {
17
+ return JavaScriptEvaluateException::newInstance(
18
+ jni::make_jstring(message),
19
+ jni::make_jstring(jsStack)
20
+ );
21
+ }
22
+ } // namespace expo
@@ -0,0 +1,38 @@
1
+ // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2
+
3
+ #pragma once
4
+
5
+ #include <fbjni/fbjni.h>
6
+
7
+ namespace jni = facebook::jni;
8
+
9
+ namespace expo {
10
+ /**
11
+ * A convenient wrapper for the Kotlin CodedException.
12
+ * It can be used with the `jni::throwNewJavaException` function to throw a cpp exception that
13
+ * will be automatically changed to the corresponding Java/Kotlin exception.
14
+ * `jni::throwNewJavaException` creates and throws a C++ exception which wraps a Java exception,
15
+ * so the C++ flow is interrupted. Then, when translatePendingCppExceptionToJavaException
16
+ * is called at the topmost level of the native stack, the wrapped Java exception is thrown to the java caller.
17
+ */
18
+ class CodedException : public jni::JavaClass<CodedException, jni::JThrowable> {
19
+ public:
20
+ static auto constexpr kJavaDescriptor = "Lexpo/modules/kotlin/exception/CodedException;";
21
+
22
+ static jni::local_ref<CodedException> create(const std::string &message);
23
+ };
24
+
25
+ /**
26
+ * A convenient wrapper for the Kotlin JavaScriptEvaluateException.
27
+ */
28
+ class JavaScriptEvaluateException
29
+ : public jni::JavaClass<JavaScriptEvaluateException, CodedException> {
30
+ public:
31
+ static auto constexpr kJavaDescriptor = "Lexpo/modules/kotlin/exception/JavaScriptEvaluateException;";
32
+
33
+ static jni::local_ref<JavaScriptEvaluateException> create(
34
+ const std::string &message,
35
+ const std::string &jsStack
36
+ );
37
+ };
38
+ } // namespace expo
@@ -0,0 +1,47 @@
1
+ // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2
+
3
+ #include "ExpoModulesHostObject.h"
4
+
5
+ #include <folly/dynamic.h>
6
+ #include <jsi/JSIDynamic.h>
7
+
8
+ namespace jsi = facebook::jsi;
9
+
10
+ namespace expo {
11
+
12
+ ExpoModulesHostObject::ExpoModulesHostObject(JSIInteropModuleRegistry *installer)
13
+ : installer(installer) {}
14
+
15
+ jsi::Value ExpoModulesHostObject::get(jsi::Runtime &runtime, const jsi::PropNameID &name) {
16
+ auto cName = name.utf8(runtime);
17
+ auto module = installer->getModule(cName);
18
+ if (module == nullptr) {
19
+ return jsi::Value::undefined();
20
+ }
21
+
22
+ module->cthis()->jsiInteropModuleRegistry = installer;
23
+ auto jsiObject = module->cthis()->getJSIObject(runtime);
24
+ return jsi::Value(runtime, *jsiObject);
25
+ }
26
+
27
+ void ExpoModulesHostObject::set(jsi::Runtime &runtime, const jsi::PropNameID &name,
28
+ const jsi::Value &value) {
29
+ throw jsi::JSError(
30
+ runtime,
31
+ "RuntimeError: Cannot override the host object for expo module '" + name.utf8(runtime) + "'"
32
+ );
33
+ }
34
+
35
+ std::vector<jsi::PropNameID> ExpoModulesHostObject::getPropertyNames(jsi::Runtime &rt) {
36
+ auto names = installer->getModulesName();
37
+ size_t size = names->size();
38
+ std::vector<jsi::PropNameID> result;
39
+ result.reserve(size);
40
+ for (int i = 0; i < size; i++) {
41
+ result.push_back(
42
+ jsi::PropNameID::forUtf8(rt, names->getElement(i)->toStdString())
43
+ );
44
+ }
45
+ return result;
46
+ }
47
+ } // namespace expo
@@ -0,0 +1,32 @@
1
+ // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2
+
3
+ #pragma once
4
+
5
+ #include "JSIInteropModuleRegistry.h"
6
+
7
+ #include <jsi/jsi.h>
8
+
9
+ #include <vector>
10
+
11
+ namespace jsi = facebook::jsi;
12
+
13
+ namespace expo {
14
+ /**
15
+ * An entry point to all exported functionalities like modules.
16
+ *
17
+ * An instance of this class will be added to the JS global object.
18
+ */
19
+ class ExpoModulesHostObject : public jsi::HostObject {
20
+ public:
21
+ ExpoModulesHostObject(JSIInteropModuleRegistry *installer);
22
+
23
+ jsi::Value get(jsi::Runtime &, const jsi::PropNameID &name) override;
24
+
25
+ void set(jsi::Runtime &, const jsi::PropNameID &name, const jsi::Value &value) override;
26
+
27
+ std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
28
+
29
+ private:
30
+ JSIInteropModuleRegistry *installer;
31
+ };
32
+ } // namespace expo