expo-modules-core 1.2.7 → 1.3.1

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 +32 -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 +42 -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 +29 -2
  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 +26 -13
  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 +60 -19
  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
package/CHANGELOG.md CHANGED
@@ -10,32 +10,59 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
- ## 1.2.7 — 2023-05-03
13
+ ## 1.3.1 — 2023-05-08
14
+
15
+ _This version does not introduce any user-facing changes._
16
+
17
+ ## 1.3.0 — 2023-05-08
18
+
19
+ ### 🎉 New features
20
+
21
+ - [iOS] Introduced native functions on the native component instances. ([#21746](https://github.com/expo/expo/pull/21746) by [@tsapeta](https://github.com/tsapeta))
22
+ - View tag and React component ref can now be converted to an instance of the native view when used as a function's argument. ([#21816](https://github.com/expo/expo/pull/21816) by [@lukmccall](https://github.com/lukmccall), [#21829](https://github.com/expo/expo/pull/21829) by [@tsapeta](https://github.com/tsapeta))
23
+ - JavaScript functions can now be passed as an argument to a module method. ([#21976](https://github.com/expo/expo/pull/21976) by [@lukmccall](https://github.com/lukmccall), [#22245](https://github.com/expo/expo/pull/22245) by [@tsapeta](https://github.com/tsapeta))
24
+ - [iOS] Initializing and returning shared objects from the native side. ([#22195](https://github.com/expo/expo/pull/22195) by [@tsapeta](https://github.com/tsapeta))
25
+
26
+ ### 🐛 Bug fixes
27
+
28
+ - Fixed build errors on React Native 0.72.x. ([#22170](https://github.com/expo/expo/pull/22170), [#22189](https://github.com/expo/expo/pull/22189) by [@kudo](https://github.com/kudo))
29
+ - [Android] Fixed argument trailing not working correctly when all parameters are optional. ([#22293](https://github.com/expo/expo/pull/22293) by [@lukmccall](https://github.com/lukmccall))
30
+
31
+ ### 💡 Others
32
+
33
+ - [Android] Made `fallbackCallback` optional in the `registerForActivityResult` method. ([#21661](https://github.com/expo/expo/pull/21661) by [@lukmccall](https://github.com/lukmccall))
34
+ - [iOS] Removed the legacy implementation of view managers. ([#21760](https://github.com/expo/expo/pull/21760) by [@tsapeta](https://github.com/tsapeta))
35
+ - [iOS] Passed the app context instance down to dynamic types, object builders and convertibles. ([#21819](https://github.com/expo/expo/pull/21819) by [@tsapeta](https://github.com/tsapeta))
36
+ - [iOS] Use `jsi::WeakObject` for weak objects on Hermes. ([#21986](https://github.com/expo/expo/pull/21986) by [@tsapeta](https://github.com/tsapeta))
37
+ - [iOS] Removed legacyViewManager references from ExpoFabricView. ([#22089](https://github.com/expo/expo/pull/22089) by [@gabrieldonadel](https://github.com/gabrieldonadel))
38
+ - [iOS] Dropped `proxiedProperties` prop. ([#22280](https://github.com/expo/expo/pull/22280) by [@tsapeta](https://github.com/tsapeta))
39
+
40
+ ## 1.2.7 - 2023-05-03
14
41
 
15
42
  ### 🐛 Bug fixes
16
43
 
17
44
  - [Android] Improve the initial loading speed of the native view. ([#22153](https://github.com/expo/expo/pull/22153) by [@lukmccall](https://github.com/lukmccall))
18
45
 
19
- ## 1.2.6 2023-03-20
46
+ ## 1.2.6 - 2023-03-20
20
47
 
21
48
  ### 🐛 Bug fixes
22
49
 
23
50
  - [Android] Fixed `ReadableNativeMap` cannot be cast to the `Record`. ([#21773](https://github.com/expo/expo/pull/21773) by [@lukmccall](https://github.com/lukmccall))
24
51
 
25
- ## 1.2.5 2023-03-14
52
+ ## 1.2.5 - 2023-03-14
26
53
 
27
54
  ### 🐛 Bug fixes
28
55
 
29
56
  - [Android] Fixed coroutine functions crashing when invoked with more than 1 argument. ([#21635](https://github.com/expo/expo/pull/21635) by [@lukmccall](https://github.com/lukmccall))
30
57
  - [iOS] Fix automatic percent-encoding when converting to the `URL` object. ([#21569](https://github.com/expo/expo/pull/21569) by [@tsapeta](https://github.com/tsapeta))
31
58
 
32
- ## 1.2.4 2023-03-03
59
+ ## 1.2.4 - 2023-03-03
33
60
 
34
61
  ### 🐛 Bug fixes
35
62
 
36
63
  - [iOS] Fixed jsc import when using use_frameworks ([#21479](https://github.com/expo/expo/pull/21479) by [@gabrieldonadel](https://github.com/gabrieldonadel))
37
64
 
38
- ## 1.2.3 2023-02-21
65
+ ## 1.2.3 - 2023-02-21
39
66
 
40
67
  ### 🐛 Bug fixes
41
68
 
@@ -68,6 +68,7 @@ Pod::Spec.new do |s|
68
68
  s.dependency 'React-Core'
69
69
  s.dependency 'ReactCommon/turbomodule/core'
70
70
  s.dependency 'React-RCTAppDelegate' if REACT_NATIVE_MINOR_VERSION >= 71
71
+ s.dependency 'React-NativeModulesApple' if REACT_NATIVE_MINOR_VERSION >= 72
71
72
 
72
73
  if fabric_enabled
73
74
  compiler_flags << ' ' << fabric_compiler_flags
package/README.md CHANGED
@@ -11,7 +11,7 @@ The core of Expo Modules architecture.
11
11
 
12
12
  # Installation in managed Expo projects
13
13
 
14
- 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.
14
+ For [managed](https://docs.expo.dev/archive/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.
15
15
 
16
16
  # Installation in bare React Native projects
17
17
 
@@ -6,6 +6,22 @@ class KotlinExpoModulesCorePlugin implements Plugin<Project> {
6
6
  ? project.rootProject.ext.get("kotlinVersion")
7
7
  : "1.8.10"
8
8
  }
9
+
10
+ project.ext.kspVersion = {
11
+ def kspVersionsMap = [
12
+ "1.6.10": "1.6.10-1.0.4",
13
+ "1.6.21": "1.6.21-1.0.6",
14
+ "1.7.22": "1.7.22-1.0.8",
15
+ "1.8.0": "1.8.0-1.0.9",
16
+ "1.8.10": "1.8.10-1.0.9"
17
+ ]
18
+
19
+ project.rootProject.ext.has("kspVersion")
20
+ ? project.rootProject.ext.get("kspVersion")
21
+ : kspVersionsMap.containsKey(project.ext.kotlinVersion())
22
+ ? kspVersionsMap.get(project.ext.kotlinVersion())
23
+ : "1.8.10-1.0.9"
24
+ }
9
25
  }
10
26
  }
11
27
  }
@@ -6,7 +6,7 @@ apply plugin: 'maven-publish'
6
6
  apply plugin: "de.undercouch.download"
7
7
 
8
8
  group = 'host.exp.exponent'
9
- version = '1.2.7'
9
+ version = '1.3.1'
10
10
 
11
11
  buildscript {
12
12
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
@@ -173,7 +173,7 @@ android {
173
173
  targetSdkVersion safeExtGet("targetSdkVersion", 33)
174
174
  consumerProguardFiles 'proguard-rules.pro'
175
175
  versionCode 1
176
- versionName "1.2.7"
176
+ versionName "1.3.1"
177
177
  buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled.toString()
178
178
 
179
179
  testInstrumentationRunner "expo.modules.TestRunner"
@@ -274,6 +274,7 @@ dependencies {
274
274
  api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0"
275
275
  api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0"
276
276
  api "androidx.core:core-ktx:1.6.0"
277
+ api project(':expo-modules-core$android-annotation')
277
278
 
278
279
  /**
279
280
  * ReactActivity (the base activity for every React Native application) is subclassing AndroidX classes.
@@ -46,6 +46,14 @@ jni::local_ref<UnexpectedException> UnexpectedException::create(const std::strin
46
46
  );
47
47
  }
48
48
 
49
+ jni::local_ref<InvalidArgsNumberException> InvalidArgsNumberException::create(int received, int expected) {
50
+ return InvalidArgsNumberException::newInstance(
51
+ received,
52
+ expected,
53
+ expected // number of required arguments
54
+ );
55
+ }
56
+
49
57
  jsi::Value makeCodedError(
50
58
  jsi::Runtime &rt,
51
59
  jsi::String code,
@@ -60,6 +60,17 @@ public:
60
60
  );
61
61
  };
62
62
 
63
+ class InvalidArgsNumberException
64
+ : public jni::JavaClass<InvalidArgsNumberException, CodedException> {
65
+ public:
66
+ static auto constexpr kJavaDescriptor = "Lexpo/modules/kotlin/exception/InvalidArgsNumberException;";
67
+
68
+ static jni::local_ref<InvalidArgsNumberException> create(
69
+ int received,
70
+ int expected
71
+ );
72
+ };
73
+
63
74
  /**
64
75
  * Tries to rethrow an jni::JniException as a js version of the CodedException
65
76
  */
@@ -1,9 +1,11 @@
1
1
  // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2
2
 
3
3
  #include "ExpoModulesHostObject.h"
4
+ #include "LazyObject.h"
4
5
 
5
6
  #include <folly/dynamic.h>
6
7
  #include <jsi/JSIDynamic.h>
8
+ #include <react/bridging/LongLivedObject.h>
7
9
 
8
10
  namespace jsi = facebook::jsi;
9
11
 
@@ -16,20 +18,35 @@ ExpoModulesHostObject::ExpoModulesHostObject(JSIInteropModuleRegistry *installer
16
18
  * Clears jsi references held by JSRegistry and JavaScriptRuntime.
17
19
  */
18
20
  ExpoModulesHostObject::~ExpoModulesHostObject() {
21
+ facebook::react::LongLivedObjectCollection::get().clear();
19
22
  installer->jsRegistry.reset();
20
23
  installer->runtimeHolder.reset();
21
24
  }
22
25
 
23
26
  jsi::Value ExpoModulesHostObject::get(jsi::Runtime &runtime, const jsi::PropNameID &name) {
24
27
  auto cName = name.utf8(runtime);
25
- auto module = installer->getModule(cName);
26
- if (module == nullptr) {
28
+
29
+ if (!installer->hasModule(cName)) {
30
+ modulesCache.erase(cName);
27
31
  return jsi::Value::undefined();
28
32
  }
33
+ if (UniqueJSIObject &cachedObject = modulesCache[cName]) {
34
+ return jsi::Value(runtime, *cachedObject);
35
+ }
36
+
37
+ // Create a lazy object for the specific module. It defers initialization of the final module object.
38
+ LazyObject::Shared moduleLazyObject = std::make_shared<LazyObject>(
39
+ [this, cName](jsi::Runtime &rt) {
40
+ auto module = installer->getModule(cName);
41
+ module->cthis()->jsiInteropModuleRegistry = installer;
42
+ return module->cthis()->getJSIObject(rt);
43
+ });
44
+
45
+ // Save the module's lazy host object for later use.
46
+ modulesCache[cName] = std::make_unique<jsi::Object>(
47
+ jsi::Object::createFromHostObject(runtime, moduleLazyObject));
29
48
 
30
- module->cthis()->jsiInteropModuleRegistry = installer;
31
- auto jsiObject = module->cthis()->getJSIObject(runtime);
32
- return jsi::Value(runtime, *jsiObject);
49
+ return jsi::Value(runtime, *modulesCache[cName]);
33
50
  }
34
51
 
35
52
  void ExpoModulesHostObject::set(jsi::Runtime &runtime, const jsi::PropNameID &name,
@@ -7,10 +7,14 @@
7
7
  #include <jsi/jsi.h>
8
8
 
9
9
  #include <vector>
10
+ #import <unordered_map>
10
11
 
11
12
  namespace jsi = facebook::jsi;
12
13
 
13
14
  namespace expo {
15
+
16
+ using UniqueJSIObject = std::unique_ptr<jsi::Object>;
17
+
14
18
  /**
15
19
  * An entry point to all exported functionalities like modules.
16
20
  *
@@ -30,5 +34,6 @@ public:
30
34
 
31
35
  private:
32
36
  JSIInteropModuleRegistry *installer;
37
+ std::unordered_map<std::string, UniqueJSIObject> modulesCache;
33
38
  };
34
39
  } // namespace expo
@@ -4,6 +4,7 @@
4
4
  #include "JavaScriptModuleObject.h"
5
5
  #include "JavaScriptValue.h"
6
6
  #include "JavaScriptObject.h"
7
+ #include "JavaScriptFunction.h"
7
8
  #include "JavaScriptTypedArray.h"
8
9
  #include "JavaReferencesCache.h"
9
10
  #include "JavaCallback.h"
@@ -27,6 +28,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
27
28
  expo::JavaScriptModuleObject::registerNatives();
28
29
  expo::JavaScriptValue::registerNatives();
29
30
  expo::JavaScriptObject::registerNatives();
31
+ expo::JavaScriptFunction::registerNatives();
30
32
  expo::JavaScriptTypedArray::registerNatives();
31
33
  expo::JavaCallback::registerNatives();
32
34
  #if RN_FABRIC_ENABLED
@@ -45,6 +45,7 @@ void JSIInteropModuleRegistry::installJSI(
45
45
  jsRegistry = std::make_unique<JSReferencesCache>(*runtime);
46
46
 
47
47
  runtimeHolder = std::make_shared<JavaScriptRuntime>(
48
+ this,
48
49
  runtime,
49
50
  jsInvokerHolder->cthis()->getCallInvoker(),
50
51
  nativeInvokerHolder->cthis()->getCallInvoker()
@@ -76,7 +77,7 @@ void JSIInteropModuleRegistry::installJSIForTests() {
76
77
  #if !UNIT_TEST
77
78
  throw std::logic_error("The function is only available when UNIT_TEST is defined.");
78
79
  #else
79
- runtimeHolder = std::make_shared<JavaScriptRuntime>();
80
+ runtimeHolder = std::make_shared<JavaScriptRuntime>(this);
80
81
  jsi::Runtime &jsiRuntime = runtimeHolder->get();
81
82
 
82
83
  jsRegistry = std::make_unique<JSReferencesCache>(jsiRuntime);
@@ -114,11 +115,23 @@ JSIInteropModuleRegistry::callGetJavaScriptModulesNames() const {
114
115
  return method(javaPart_);
115
116
  }
116
117
 
118
+ bool JSIInteropModuleRegistry::callHasModule(const std::string &moduleName) const {
119
+ const static auto method = expo::JSIInteropModuleRegistry::javaClassLocal()
120
+ ->getMethod<jboolean(std::string)>(
121
+ "hasModule"
122
+ );
123
+ return (bool) method(javaPart_, moduleName);
124
+ }
125
+
117
126
  jni::local_ref<JavaScriptModuleObject::javaobject>
118
127
  JSIInteropModuleRegistry::getModule(const std::string &moduleName) const {
119
128
  return callGetJavaScriptModuleObjectMethod(moduleName);
120
129
  }
121
130
 
131
+ bool JSIInteropModuleRegistry::hasModule(const std::string &moduleName) const {
132
+ return callHasModule(moduleName);
133
+ }
134
+
122
135
  jni::local_ref<jni::JArrayClass<jni::JString>> JSIInteropModuleRegistry::getModulesName() const {
123
136
  return callGetJavaScriptModulesNames();
124
137
  }
@@ -140,4 +153,15 @@ jni::local_ref<JavaScriptObject::javaobject> JSIInteropModuleRegistry::createObj
140
153
  void JSIInteropModuleRegistry::drainJSEventLoop() {
141
154
  runtimeHolder->drainJSEventLoop();
142
155
  }
156
+
157
+ void JSIInteropModuleRegistry::registerSharedObject(
158
+ jni::local_ref<jobject> native,
159
+ jni::local_ref<JavaScriptObject::javaobject> js
160
+ ) {
161
+ const static auto method = expo::JSIInteropModuleRegistry::javaClassLocal()
162
+ ->getMethod<void(jni::local_ref<jobject>, jni::local_ref<JavaScriptObject::javaobject>)>(
163
+ "registerSharedObject"
164
+ );
165
+ method(javaPart_, std::move(native), std::move(js));
166
+ }
143
167
  } // namespace expo
@@ -56,6 +56,8 @@ public:
56
56
  */
57
57
  jni::local_ref<JavaScriptModuleObject::javaobject> getModule(const std::string &moduleName) const;
58
58
 
59
+ bool hasModule(const std::string &moduleName) const;
60
+
59
61
  /**
60
62
  * Gets names of all available modules.
61
63
  */
@@ -76,6 +78,16 @@ public:
76
78
  */
77
79
  jni::local_ref<JavaScriptObject::javaobject> createObject();
78
80
 
81
+ /**
82
+ * Adds a shared object to the internal registry
83
+ * @param native part of the shared object
84
+ * @param js part of the shared object
85
+ */
86
+ void registerSharedObject(
87
+ jni::local_ref<jobject> native,
88
+ jni::local_ref<JavaScriptObject::javaobject> js
89
+ );
90
+
79
91
  /**
80
92
  * Exposes a `JavaScriptRuntime::drainJSEventLoop` function to Kotlin
81
93
  */
@@ -95,5 +107,7 @@ private:
95
107
  callGetJavaScriptModuleObjectMethod(const std::string &moduleName) const;
96
108
 
97
109
  inline jni::local_ref<jni::JArrayClass<jni::JString>> callGetJavaScriptModulesNames() const;
110
+
111
+ inline bool callHasModule(const std::string &moduleName) const;
98
112
  };
99
113
  } // namespace expo
@@ -10,24 +10,35 @@ namespace jsi = facebook::jsi;
10
10
 
11
11
  namespace expo {
12
12
  /**
13
- * An interface for classes which wrap jsi::Object.
13
+ * An interface for classes which wrap `jsi::Object`.
14
14
  */
15
15
  class JSIObjectWrapper {
16
16
  public:
17
17
  /**
18
- * @return a pointer to the underlying jsi::Object.
18
+ * @return a pointer to the underlying `jsi::Object`.
19
19
  */
20
20
  virtual std::shared_ptr<jsi::Object> get() = 0;
21
21
  };
22
22
 
23
23
  /**
24
- * An interface for classes which wrap jsi::Value.
24
+ * An interface for classes which wrap `jsi::Value`.
25
25
  */
26
26
  class JSIValueWrapper {
27
27
  public:
28
28
  /**
29
- * @return a pointer to the underlying jsi::Value.
29
+ * @return a pointer to the underlying `jsi::Value`.
30
30
  */
31
31
  virtual std::shared_ptr<jsi::Value> get() = 0;
32
32
  };
33
+
34
+ /**
35
+ * An interface for classes which wrap `jsi::Function`.
36
+ */
37
+ class JSIFunctionWrapper {
38
+ public:
39
+ /**
40
+ * @return a pointer to the underlying `jsi::Function`.
41
+ */
42
+ virtual std::shared_ptr<jsi::Function> get() = 0;
43
+ };
33
44
  } // namespace expo
@@ -23,7 +23,7 @@ struct jsi_type_converter {
23
23
  };
24
24
 
25
25
  /**
26
- * Conversion from jni::alias_ref<T::javaobject> to jsi::Value where T extends JSIValueWrapper or JSIObjectWrapper.
26
+ * Conversion from jni::alias_ref<T::javaobject> to jsi::Value where T extends JSIValueWrapper, JSIObjectWrapper or JSIFunctionWrapper.
27
27
  */
28
28
  template<class T>
29
29
  struct jsi_type_converter<
@@ -31,7 +31,8 @@ struct jsi_type_converter<
31
31
  std::enable_if_t<
32
32
  // jni::ReprType<T>::HybridType>::value if T looks like `R::javaobject`, it will return R
33
33
  std::is_base_of<JSIValueWrapper, typename jni::ReprType<T>::HybridType>::value ||
34
- std::is_base_of<JSIObjectWrapper, typename jni::ReprType<T>::HybridType>::value
34
+ std::is_base_of<JSIObjectWrapper, typename jni::ReprType<T>::HybridType>::value ||
35
+ std::is_base_of<JSIValueWrapper, typename jni::ReprType<T>::HybridType>::value
35
36
  >
36
37
  > {
37
38
  static const bool isDefined = true;
@@ -48,6 +48,8 @@ void JavaReferencesCache::loadJClasses(JNIEnv *env) {
48
48
  loadJClass(env, "com/facebook/react/bridge/ReadableNativeMap", {});
49
49
  loadJClass(env, "com/facebook/react/bridge/WritableNativeArray", {});
50
50
  loadJClass(env, "com/facebook/react/bridge/WritableNativeMap", {});
51
+
52
+ loadJClass(env, "expo/modules/kotlin/sharedobjects/SharedObject", {});
51
53
  }
52
54
 
53
55
  void JavaReferencesCache::loadJClass(
@@ -0,0 +1,56 @@
1
+ // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2
+
3
+ #include "JavaScriptFunction.h"
4
+ #include "types/JNIToJSIConverter.h"
5
+ #include "types/AnyType.h"
6
+
7
+ namespace expo {
8
+
9
+ void JavaScriptFunction::registerNatives() {
10
+ registerHybrid({
11
+ makeNativeMethod("invoke", JavaScriptFunction::invoke),
12
+ });
13
+ }
14
+
15
+ JavaScriptFunction::JavaScriptFunction(
16
+ std::weak_ptr<JavaScriptRuntime> runtime,
17
+ std::shared_ptr<jsi::Function> jsFunction
18
+ ) : runtimeHolder(std::move(runtime)), jsFunction(std::move(jsFunction)) {
19
+ runtimeHolder.ensureRuntimeIsValid();
20
+ }
21
+
22
+ JavaScriptFunction::JavaScriptFunction(
23
+ WeakRuntimeHolder runtime,
24
+ std::shared_ptr<jsi::Function> jsFunction
25
+ ) : runtimeHolder(std::move(runtime)), jsFunction(std::move(jsFunction)) {
26
+ runtimeHolder.ensureRuntimeIsValid();
27
+ }
28
+
29
+ std::shared_ptr<jsi::Function> JavaScriptFunction::get() {
30
+ return jsFunction;
31
+ }
32
+
33
+ jobject JavaScriptFunction::invoke(
34
+ jni::alias_ref<jni::JArrayClass<jni::JObject>> args,
35
+ jni::alias_ref<ExpectedType::javaobject> expectedReturnType
36
+ ) {
37
+ auto &rt = runtimeHolder.getJSRuntime();
38
+ auto moduleRegistry = runtimeHolder.getModuleRegistry();
39
+ JNIEnv *env = jni::Environment::current();
40
+
41
+ size_t size = args->size();
42
+ std::vector<jsi::Value> convertedArgs;
43
+ convertedArgs.reserve(size);
44
+
45
+ for (size_t i = 0; i < size; i++) {
46
+ jni::local_ref<jni::JObject> arg = args->getElement(i);
47
+ convertedArgs.push_back(convert(moduleRegistry, env, rt, std::move(arg)));
48
+ }
49
+
50
+ // TODO(@lukmccall): add better error handling
51
+ jsi::Value result = jsFunction->call(rt, (const jsi::Value *) convertedArgs.data(), size);
52
+ auto converter = AnyType(jni::make_local(expectedReturnType)).converter;
53
+ auto convertedResult = converter->convert(rt, env, moduleRegistry, result);
54
+ return convertedResult;
55
+ }
56
+ } // namespace expo
@@ -0,0 +1,54 @@
1
+ // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2
+
3
+ #pragma once
4
+
5
+ #include "JSIObjectWrapper.h"
6
+ #include "JavaScriptRuntime.h"
7
+ #include "WeakRuntimeHolder.h"
8
+ #include "types/ExpectedType.h"
9
+
10
+ #include <fbjni/fbjni.h>
11
+ #include <jsi/jsi.h>
12
+
13
+ namespace jni = facebook::jni;
14
+ namespace jsi = facebook::jsi;
15
+
16
+ namespace expo {
17
+
18
+ /**
19
+ * Represents any JavaScript function. Its purpose is to expose the `jsi::Function` API back to Kotlin.
20
+ */
21
+ class JavaScriptFunction : public jni::HybridClass<JavaScriptFunction>, JSIFunctionWrapper {
22
+ public:
23
+ static auto constexpr
24
+ kJavaDescriptor = "Lexpo/modules/kotlin/jni/JavaScriptFunction;";
25
+ static auto constexpr TAG = "JavaScriptFunction";
26
+
27
+ static void registerNatives();
28
+
29
+ JavaScriptFunction(
30
+ std::weak_ptr<JavaScriptRuntime> runtime,
31
+ std::shared_ptr<jsi::Function> jsFunction
32
+ );
33
+
34
+ JavaScriptFunction(
35
+ WeakRuntimeHolder runtime,
36
+ std::shared_ptr<jsi::Function> jsFunction
37
+ );
38
+
39
+ std::shared_ptr<jsi::Function> get() override;
40
+
41
+
42
+ private:
43
+ friend HybridBase;
44
+
45
+ WeakRuntimeHolder runtimeHolder;
46
+ std::shared_ptr<jsi::Function> jsFunction;
47
+
48
+ jobject invoke(
49
+ jni::alias_ref<jni::JArrayClass<jni::JObject>> args,
50
+ jni::alias_ref<ExpectedType::javaobject> expectedReturnType
51
+ );
52
+ };
53
+
54
+ } // namespace expo