expo-modules-core 1.3.2 → 1.4.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 (64) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/ExpoModulesCore.podspec +26 -5
  3. package/android/ExpoModulesCorePlugin.gradle +4 -0
  4. package/android/build.gradle +13 -14
  5. package/android/src/main/AndroidManifest.xml +1 -2
  6. package/android/src/main/cpp/ExpoModulesHostObject.cpp +3 -0
  7. package/android/src/main/cpp/JNIDeallocator.cpp +17 -0
  8. package/android/src/main/cpp/JNIDeallocator.h +25 -0
  9. package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +8 -1
  10. package/android/src/main/cpp/JSIInteropModuleRegistry.h +6 -1
  11. package/android/src/main/cpp/JavaCallback.cpp +9 -0
  12. package/android/src/main/cpp/JavaCallback.h +12 -2
  13. package/android/src/main/cpp/JavaScriptFunction.cpp +13 -0
  14. package/android/src/main/cpp/JavaScriptFunction.h +7 -1
  15. package/android/src/main/cpp/JavaScriptModuleObject.cpp +2 -1
  16. package/android/src/main/cpp/JavaScriptObject.cpp +17 -2
  17. package/android/src/main/cpp/JavaScriptObject.h +10 -3
  18. package/android/src/main/cpp/JavaScriptRuntime.cpp +5 -4
  19. package/android/src/main/cpp/JavaScriptRuntime.h +5 -3
  20. package/android/src/main/cpp/JavaScriptTypedArray.cpp +14 -0
  21. package/android/src/main/cpp/JavaScriptTypedArray.h +6 -0
  22. package/android/src/main/cpp/JavaScriptValue.cpp +32 -4
  23. package/android/src/main/cpp/JavaScriptValue.h +10 -3
  24. package/android/src/main/cpp/MethodMetadata.cpp +1 -1
  25. package/android/src/main/cpp/types/FrontendConverter.cpp +8 -4
  26. package/android/src/main/java/expo/modules/core/interfaces/ReactActivityHandler.java +14 -0
  27. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +4 -1
  28. package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +7 -3
  29. package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +19 -12
  30. package/android/src/main/java/expo/modules/kotlin/devtools/ExpoNetworkInspectOkHttpInterceptors.kt +70 -0
  31. package/android/src/main/java/expo/modules/kotlin/devtools/ExpoRequestCdpInterceptor.kt +72 -0
  32. package/android/src/main/java/expo/modules/kotlin/devtools/OkHttpHeadersExtension.kt +18 -0
  33. package/android/src/main/java/expo/modules/kotlin/devtools/cdp/CdpNetworkTypes.kt +257 -0
  34. package/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt +24 -15
  35. package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +8 -1
  36. package/android/src/main/java/expo/modules/kotlin/jni/JavaCallback.kt +0 -4
  37. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptFunction.kt +0 -4
  38. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +5 -2
  39. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +0 -5
  40. package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +0 -4
  41. package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +1 -1
  42. package/android/src/main/java/expo/modules/kotlin/types/ColorTypeConverter.kt +3 -0
  43. package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +1 -2
  44. package/android-annotation/build.gradle +2 -2
  45. package/android-annotation-processor/build.gradle +2 -2
  46. package/ios/JSI/EXJSIInstaller.h +2 -2
  47. package/ios/JSI/EXJSIInstaller.mm +6 -6
  48. package/ios/JSI/EXJavaScriptRuntime.h +0 -6
  49. package/ios/JSI/EXJavaScriptRuntime.mm +0 -23
  50. package/ios/RCTComponentData+Privates.h +17 -0
  51. package/ios/RCTComponentData+Privates.m +15 -0
  52. package/ios/Swift/AppContext.swift +20 -11
  53. package/ios/Swift/DevTools/CdpNetworkTypes.swift +163 -0
  54. package/ios/Swift/DevTools/ExpoRequestCdpInterceptor.swift +71 -0
  55. package/ios/Swift/DevTools/ExpoRequestInterceptorProtocol.swift +183 -0
  56. package/ios/Swift/DevTools/URLRequest+httpBodyData.swift +43 -0
  57. package/ios/Swift/ExpoRuntime.swift +28 -0
  58. package/ios/Swift/Modules/CoreModule.swift +7 -0
  59. package/ios/Swift/SharedObjects/SharedRef.swift +12 -0
  60. package/ios/Swift/Views/ComponentData.swift +1 -1
  61. package/ios/Tests/CoreModuleSpec.swift +27 -0
  62. package/ios/Tests/ExpoRequestCdpInterceptorSpec.swift +165 -0
  63. package/ios/Tests/SharedRefSpec.swift +60 -0
  64. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -10,6 +10,29 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 1.4.0 — 2023-06-13
14
+
15
+ ### 📚 3rd party library updates
16
+
17
+ - Updated `robolectric` to `4.10` and `junit` to `4.13.2`. ([#22395](https://github.com/expo/expo/pull/22395) by [@josephyanks](https://github.com/josephyanks))
18
+
19
+ ### 🎉 New features
20
+
21
+ - Added `ReactActivityHandler.getDelayLoadAppHandler` interface on Android. ([#20273](https://github.com/expo/expo/pull/20273) by [@kudo](https://github.com/kudo))
22
+ - [iOS] Introduced shared refs – a way to pass native objects among different independent modules. ([#22583](https://github.com/expo/expo/pull/22583) by [@tsapeta](https://github.com/tsapeta))
23
+ - Added support for React Native 0.72. ([#22588](https://github.com/expo/expo/pull/22588) by [@kudo](https://github.com/kudo))
24
+
25
+ ### 🐛 Bug fixes
26
+
27
+ - Fix failing instrumentation tests in JavaScriptViewModule. ([#22518](https://github.com/expo/expo/pull/22518) by [@aleqsio](https://github.com/aleqsio))
28
+ - Fixed Android build warnings for Gradle version 8. ([#22537](https://github.com/expo/expo/pull/22537), [#22609](https://github.com/expo/expo/pull/22609) by [@kudo](https://github.com/kudo))
29
+ - [Android] Fix the `Color` converter doesn't work on devices with SDK version below 26. ([#22191](https://github.com/expo/expo/pull/22191) by [@lukmccall](https://github.com/lukmccall))
30
+ - Refactored network inspector code and add unit tests. ([#22669](https://github.com/expo/expo/pull/22669), [#22693](https://github.com/expo/expo/pull/22693) by [@kudo](https://github.com/kudo))
31
+
32
+ ### 💡 Others
33
+
34
+ - Updated `androidx.activity:activity-ktx` to `1.7.1` and `androidx.fragment:fragment-ktx` to `1.5.7` [#22658](https://github.com/expo/expo/pull/22658) by [@fobos531](https://github.com/fobos531)
35
+
13
36
  ## 1.3.2 — 2023-05-09
14
37
 
15
38
  ### 🐛 Bug fixes
@@ -12,7 +12,7 @@ if ENV["REACT_NATIVE_OVERRIDE_VERSION"]
12
12
  reactNativeVersion = ENV["REACT_NATIVE_OVERRIDE_VERSION"]
13
13
  end
14
14
 
15
- REACT_NATIVE_MINOR_VERSION = reactNativeVersion.split('.')[1].to_i
15
+ reactNativeMinorVersion = reactNativeVersion.split('.')[1].to_i
16
16
 
17
17
  fabric_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'
18
18
  fabric_compiler_flags = '-DRN_FABRIC_ENABLED -DRCT_NEW_ARCH_ENABLED'
@@ -59,16 +59,30 @@ Pod::Spec.new do |s|
59
59
  "FRAMEWORK_SEARCH_PATHS" => "\"${PODS_CONFIGURATION_BUILD_DIR}/React-hermes\"",
60
60
  'OTHER_SWIFT_FLAGS' => "$(inherited) #{fabric_enabled ? fabric_compiler_flags : ''}"
61
61
  }
62
+ user_header_search_paths = [
63
+ '"${PODS_CONFIGURATION_BUILD_DIR}/ExpoModulesCore/Swift Compatibility Header"',
64
+ '"$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging"',
65
+ '"$(PODS_CONFIGURATION_BUILD_DIR)/React-bridging/react_bridging.framework/Headers"',
66
+ ]
67
+ if fabric_enabled && ENV['USE_FRAMEWORKS']
68
+ user_header_search_paths << "\"$(PODS_ROOT)/DoubleConversion\""
69
+ user_header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers\""
70
+ user_header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\""
71
+ user_header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers\""
72
+ user_header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers\""
73
+ user_header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\""
74
+ user_header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTFabric/RCTFabric.framework/Headers\""
75
+ end
62
76
  s.user_target_xcconfig = {
63
- "HEADER_SEARCH_PATHS" => "\"${PODS_CONFIGURATION_BUILD_DIR}/ExpoModulesCore/Swift Compatibility Header\" \"$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-bridging/react_bridging.framework/Headers\"",
77
+ "HEADER_SEARCH_PATHS" => user_header_search_paths,
64
78
  }
65
79
 
66
- compiler_flags = folly_compiler_flags + ' ' + "-DREACT_NATIVE_MINOR_VERSION=#{REACT_NATIVE_MINOR_VERSION}"
80
+ compiler_flags = folly_compiler_flags + ' ' + "-DREACT_NATIVE_MINOR_VERSION=#{reactNativeMinorVersion}"
67
81
 
68
82
  s.dependency 'React-Core'
69
83
  s.dependency 'ReactCommon/turbomodule/core'
70
- s.dependency 'React-RCTAppDelegate' if REACT_NATIVE_MINOR_VERSION >= 71
71
- s.dependency 'React-NativeModulesApple' if REACT_NATIVE_MINOR_VERSION >= 72
84
+ s.dependency 'React-RCTAppDelegate' if reactNativeMinorVersion >= 71
85
+ s.dependency 'React-NativeModulesApple' if reactNativeMinorVersion >= 72
72
86
 
73
87
  if fabric_enabled
74
88
  compiler_flags << ' ' << fabric_compiler_flags
@@ -77,6 +91,13 @@ Pod::Spec.new do |s|
77
91
  s.dependency 'RCT-Folly', folly_version
78
92
  end
79
93
 
94
+ unless defined?(install_modules_dependencies)
95
+ # `install_modules_dependencies` is defined from react_native_pods.rb.
96
+ # when running with `pod ipc spec`, this method is not defined and we have to require manually.
97
+ require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")
98
+ end
99
+ install_modules_dependencies(s)
100
+
80
101
  if !$ExpoUseSources&.include?(package['name']) && ENV['EXPO_USE_SOURCE'].to_i == 0 && File.exist?("ios/#{s.name}.xcframework") && Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0')
81
102
  s.source_files = 'ios/**/*.h', 'common/cpp/**/*.h'
82
103
  s.vendored_frameworks = "ios/#{s.name}.xcframework"
@@ -30,6 +30,10 @@ ext.applyKotlinExpoModulesCorePlugin = {
30
30
  apply plugin: KotlinExpoModulesCorePlugin
31
31
  }
32
32
 
33
+ ext.boolish = { value ->
34
+ return value.toString().toBoolean()
35
+ }
36
+
33
37
  // [BEGIN] Remove when we drop SDK 47
34
38
  abstract class ExtractReactNativeAARTask extends DefaultTask {
35
39
  @Input
@@ -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.3.2'
9
+ version = '1.4.0'
10
10
 
11
11
  buildscript {
12
12
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
@@ -126,19 +126,11 @@ if (USE_HERMES) {
126
126
 
127
127
  def isNewArchitectureEnabled = findProperty("newArchEnabled") == "true"
128
128
 
129
- // Creating sources with comments
130
- task androidSourcesJar(type: Jar) {
131
- classifier = 'sources'
132
- from android.sourceSets.main.java.srcDirs
133
- }
134
-
135
129
  afterEvaluate {
136
130
  publishing {
137
131
  publications {
138
132
  release(MavenPublication) {
139
133
  from components.release
140
- // Add additional sourcesJar to artifacts
141
- artifact(androidSourcesJar)
142
134
  }
143
135
  }
144
136
  repositories {
@@ -168,12 +160,13 @@ android {
168
160
  jvmTarget = JavaVersion.VERSION_11.majorVersion
169
161
  }
170
162
 
163
+ namespace "expo.modules"
171
164
  defaultConfig {
172
165
  minSdkVersion safeExtGet("minSdkVersion", 21)
173
166
  targetSdkVersion safeExtGet("targetSdkVersion", 33)
174
167
  consumerProguardFiles 'proguard-rules.pro'
175
168
  versionCode 1
176
- versionName "1.3.2"
169
+ versionName "1.4.0"
177
170
  buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled.toString()
178
171
 
179
172
  testInstrumentationRunner "expo.modules.TestRunner"
@@ -263,6 +256,11 @@ android {
263
256
  }
264
257
  }
265
258
  }
259
+ publishing {
260
+ singleVariant("release") {
261
+ withSourcesJar()
262
+ }
263
+ }
266
264
  }
267
265
 
268
266
 
@@ -284,8 +282,8 @@ dependencies {
284
282
  * We're enforcing the most up-to-date versions of the dependencies here that are used in subclassing chain for ReactActivity.
285
283
  */
286
284
  implementation "androidx.appcompat:appcompat:1.4.1"
287
- 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
288
- 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
285
+ implementation "androidx.activity:activity-ktx:1.7.1" // androidx.appcompat:appcompat:1.4.1 depends on version 1.2.3, so we enforce higher one here
286
+ implementation "androidx.fragment:fragment-ktx:1.5.7" // androidx.appcomapt:appcompat:1.4.1 depends on version 1.3.4, so we enforce higher one here
289
287
 
290
288
  //noinspection GradleDynamicVersion
291
289
  implementation 'com.facebook.react:react-native:+'
@@ -293,11 +291,12 @@ dependencies {
293
291
  compileOnly 'com.facebook.fbjni:fbjni:0.3.0'
294
292
 
295
293
  testImplementation 'androidx.test:core:1.4.0'
296
- testImplementation 'junit:junit:4.13.1'
294
+ testImplementation 'junit:junit:4.13.2'
297
295
  testImplementation 'io.mockk:mockk:1.12.3'
298
296
  testImplementation "com.google.truth:truth:1.1.2"
299
- testImplementation "org.robolectric:robolectric:4.5.1"
297
+ testImplementation "org.robolectric:robolectric:4.10"
300
298
  testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0"
299
+ testImplementation "org.json:json:20230227"
301
300
 
302
301
  androidTestImplementation 'androidx.test:runner:1.4.0'
303
302
  androidTestImplementation 'androidx.test:core:1.4.0'
@@ -1,5 +1,4 @@
1
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
- package="expo.modules">
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
2
 
4
3
  <application>
5
4
  <meta-data
@@ -21,6 +21,9 @@ ExpoModulesHostObject::~ExpoModulesHostObject() {
21
21
  facebook::react::LongLivedObjectCollection::get().clear();
22
22
  installer->jsRegistry.reset();
23
23
  installer->runtimeHolder.reset();
24
+ installer->jsInvoker.reset();
25
+ installer->nativeInvoker.reset();
26
+ installer->jniDeallocator.reset();
24
27
  }
25
28
 
26
29
  jsi::Value ExpoModulesHostObject::get(jsi::Runtime &runtime, const jsi::PropNameID &name) {
@@ -0,0 +1,17 @@
1
+ // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2
+
3
+ #include "JNIDeallocator.h"
4
+
5
+ namespace expo {
6
+
7
+ void JNIDeallocator::addReference(
8
+ jni::local_ref<Destructible::javaobject> jniObject
9
+ ) {
10
+ const static auto method = JNIDeallocator::javaClassLocal()
11
+ ->getMethod<void(jni::local_ref<Destructible>)>(
12
+ "addReference"
13
+ );
14
+ method(self(), std::move(jniObject));
15
+ }
16
+
17
+ } // namespace expo
@@ -0,0 +1,25 @@
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
+ class Destructible : public jni::JavaClass<Destructible> {
12
+ public:
13
+ static auto constexpr kJavaDescriptor = "Lexpo/modules/kotlin/jni/Destructible;";
14
+ };
15
+
16
+ class JNIDeallocator : public jni::JavaClass<JNIDeallocator> {
17
+ public:
18
+ static auto constexpr kJavaDescriptor = "Lexpo/modules/kotlin/jni/JNIDeallocator;";
19
+
20
+ void addReference(
21
+ jni::local_ref<Destructible::javaobject> jniObject
22
+ );
23
+ };
24
+
25
+ } // namespace expo
@@ -37,9 +37,12 @@ JSIInteropModuleRegistry::JSIInteropModuleRegistry(jni::alias_ref<jhybridobject>
37
37
 
38
38
  void JSIInteropModuleRegistry::installJSI(
39
39
  jlong jsRuntimePointer,
40
+ jni::alias_ref<JNIDeallocator::javaobject> jniDeallocator,
40
41
  jni::alias_ref<react::CallInvokerHolder::javaobject> jsInvokerHolder,
41
42
  jni::alias_ref<react::CallInvokerHolder::javaobject> nativeInvokerHolder
42
43
  ) {
44
+ this->jniDeallocator = jni::make_global(jniDeallocator);
45
+
43
46
  auto runtime = reinterpret_cast<jsi::Runtime *>(jsRuntimePointer);
44
47
 
45
48
  jsRegistry = std::make_unique<JSReferencesCache>(*runtime);
@@ -73,10 +76,14 @@ void JSIInteropModuleRegistry::installJSI(
73
76
  );
74
77
  }
75
78
 
76
- void JSIInteropModuleRegistry::installJSIForTests() {
79
+ void JSIInteropModuleRegistry::installJSIForTests(
80
+ jni::alias_ref<JNIDeallocator::javaobject> jniDeallocator
81
+ ) {
77
82
  #if !UNIT_TEST
78
83
  throw std::logic_error("The function is only available when UNIT_TEST is defined.");
79
84
  #else
85
+ this->jniDeallocator = jni::make_global(jniDeallocator);
86
+
80
87
  runtimeHolder = std::make_shared<JavaScriptRuntime>(this);
81
88
  jsi::Runtime &jsiRuntime = runtimeHolder->get();
82
89
 
@@ -8,6 +8,7 @@
8
8
  #include "JavaScriptObject.h"
9
9
  #include "JavaReferencesCache.h"
10
10
  #include "JSReferencesCache.h"
11
+ #include "JNIDeallocator.h"
11
12
 
12
13
  #include <fbjni/fbjni.h>
13
14
  #include <jsi/jsi.h>
@@ -39,6 +40,7 @@ public:
39
40
  */
40
41
  void installJSI(
41
42
  jlong jsRuntimePointer,
43
+ jni::alias_ref<JNIDeallocator::javaobject> jniDeallocator,
42
44
  jni::alias_ref<react::CallInvokerHolder::javaobject> jsInvokerHolder,
43
45
  jni::alias_ref<react::CallInvokerHolder::javaobject> nativeInvokerHolder
44
46
  );
@@ -46,7 +48,9 @@ public:
46
48
  /**
47
49
  * Initializes the test runtime. Shouldn't be used in the production.
48
50
  */
49
- void installJSIForTests();
51
+ void installJSIForTests(
52
+ jni::alias_ref<JNIDeallocator::javaobject> jniDeallocator
53
+ );
50
54
 
51
55
  /**
52
56
  * Gets a module for a given name. It will throw an exception if the module doesn't exist.
@@ -97,6 +101,7 @@ public:
97
101
  std::shared_ptr<react::CallInvoker> nativeInvoker;
98
102
  std::shared_ptr<JavaScriptRuntime> runtimeHolder;
99
103
  std::unique_ptr<JSReferencesCache> jsRegistry;
104
+ jni::global_ref<JNIDeallocator::javaobject> jniDeallocator;
100
105
  private:
101
106
  friend HybridBase;
102
107
  jni::global_ref<JSIInteropModuleRegistry::javaobject> javaPart_;
@@ -1,6 +1,7 @@
1
1
  // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2
2
 
3
3
  #include "JavaCallback.h"
4
+ #include "JSIInteropModuleRegistry.h"
4
5
 
5
6
  namespace expo {
6
7
 
@@ -21,6 +22,14 @@ void JavaCallback::registerNatives() {
21
22
  });
22
23
  }
23
24
 
25
+ jni::local_ref<JavaCallback::javaobject> JavaCallback::newInstance(
26
+ JSIInteropModuleRegistry *jsiInteropModuleRegistry,
27
+ Callback callback
28
+ ) {
29
+ auto object = JavaCallback::newObjectCxxArgs(std::move(callback));
30
+ jsiInteropModuleRegistry->jniDeallocator->addReference(object);
31
+ return object;
32
+ }
24
33
 
25
34
  void JavaCallback::invoke() {
26
35
  callback(nullptr);
@@ -2,6 +2,8 @@
2
2
 
3
3
  #pragma once
4
4
 
5
+ #include "JNIDeallocator.h"
6
+
5
7
  #include <fbjni/fbjni.h>
6
8
  #include <folly/dynamic.h>
7
9
 
@@ -12,18 +14,26 @@ namespace jni = facebook::jni;
12
14
  namespace react = facebook::react;
13
15
 
14
16
  namespace expo {
15
- class JavaCallback : public jni::HybridClass<JavaCallback> {
17
+ class JSIInteropModuleRegistry;
18
+
19
+ class JavaCallback : public jni::HybridClass<JavaCallback, Destructible> {
16
20
  public:
17
21
  static auto constexpr
18
22
  kJavaDescriptor = "Lexpo/modules/kotlin/jni/JavaCallback;";
19
23
  static auto constexpr TAG = "JavaCallback";
20
24
 
25
+ using Callback = std::function<void(folly::dynamic)>;
26
+
21
27
  static void registerNatives();
22
28
 
29
+ static jni::local_ref<JavaCallback::javaobject> newInstance(
30
+ JSIInteropModuleRegistry *jsiInteropModuleRegistry,
31
+ Callback callback
32
+ );
33
+
23
34
  private:
24
35
  friend HybridBase;
25
36
 
26
- using Callback = std::function<void(folly::dynamic)>;
27
37
 
28
38
  JavaCallback(Callback callback);
29
39
 
@@ -53,4 +53,17 @@ jobject JavaScriptFunction::invoke(
53
53
  auto convertedResult = converter->convert(rt, env, moduleRegistry, result);
54
54
  return convertedResult;
55
55
  }
56
+
57
+ jni::local_ref<JavaScriptFunction::javaobject> JavaScriptFunction::newInstance(
58
+ JSIInteropModuleRegistry *jsiInteropModuleRegistry,
59
+ std::weak_ptr<JavaScriptRuntime> runtime,
60
+ std::shared_ptr<jsi::Function> jsFunction
61
+ ) {
62
+ auto function = JavaScriptFunction::newObjectCxxArgs(
63
+ std::move(runtime),
64
+ std::move(jsFunction)
65
+ );
66
+ jsiInteropModuleRegistry->jniDeallocator->addReference(function);
67
+ return function;
68
+ }
56
69
  } // namespace expo
@@ -18,7 +18,7 @@ namespace expo {
18
18
  /**
19
19
  * Represents any JavaScript function. Its purpose is to expose the `jsi::Function` API back to Kotlin.
20
20
  */
21
- class JavaScriptFunction : public jni::HybridClass<JavaScriptFunction>, JSIFunctionWrapper {
21
+ class JavaScriptFunction : public jni::HybridClass<JavaScriptFunction, Destructible>, JSIFunctionWrapper {
22
22
  public:
23
23
  static auto constexpr
24
24
  kJavaDescriptor = "Lexpo/modules/kotlin/jni/JavaScriptFunction;";
@@ -26,6 +26,12 @@ public:
26
26
 
27
27
  static void registerNatives();
28
28
 
29
+ static jni::local_ref<JavaScriptFunction::javaobject> newInstance(
30
+ JSIInteropModuleRegistry *jsiInteropModuleRegistry,
31
+ std::weak_ptr<JavaScriptRuntime> runtime,
32
+ std::shared_ptr<jsi::Function> jsFunction
33
+ );
34
+
29
35
  JavaScriptFunction(
30
36
  std::weak_ptr<JavaScriptRuntime> runtime,
31
37
  std::shared_ptr<jsi::Function> jsFunction
@@ -199,7 +199,8 @@ std::shared_ptr<jsi::Object> JavaScriptModuleObject::getJSIObject(jsi::Runtime &
199
199
  JavaReferencesCache::instance()->getJClass(
200
200
  "expo/modules/kotlin/sharedobjects/SharedObject").clazz
201
201
  )) {
202
- auto jsThisObject = JavaScriptObject::newObjectCxxArgs(
202
+ auto jsThisObject = JavaScriptObject::newInstance(
203
+ jsiInteropModuleRegistry,
203
204
  jsiInteropModuleRegistry->runtimeHolder,
204
205
  thisObject
205
206
  );
@@ -7,6 +7,7 @@
7
7
  #include "JSITypeConverter.h"
8
8
  #include "ObjectDeallocator.h"
9
9
  #include "JavaReferencesCache.h"
10
+ #include "JSIInteropModuleRegistry.h"
10
11
 
11
12
  namespace expo {
12
13
  void JavaScriptObject::registerNatives() {
@@ -73,7 +74,11 @@ jni::local_ref<JavaScriptValue::javaobject> JavaScriptObject::jniGetProperty(
73
74
  jni::alias_ref<jstring> name
74
75
  ) {
75
76
  auto result = std::make_shared<jsi::Value>(getProperty(name->toStdString()));
76
- return JavaScriptValue::newObjectCxxArgs(runtimeHolder, result);
77
+ return JavaScriptValue::newInstance(
78
+ runtimeHolder.getModuleRegistry(),
79
+ runtimeHolder,
80
+ result
81
+ );
77
82
  }
78
83
 
79
84
  std::vector<std::string> JavaScriptObject::getPropertyNames() {
@@ -107,7 +112,7 @@ jni::local_ref<jni::JArrayClass<jstring>> JavaScriptObject::jniGetPropertyNames(
107
112
  jni::local_ref<JavaScriptFunction::javaobject> JavaScriptObject::jniAsFunction() {
108
113
  auto &jsRuntime = runtimeHolder.getJSRuntime();
109
114
  auto jsFuncion = std::make_shared<jsi::Function>(jsObject->asFunction(jsRuntime));
110
- return JavaScriptFunction::newObjectCxxArgs(runtimeHolder, jsFuncion);
115
+ return JavaScriptFunction::newInstance(runtimeHolder.getModuleRegistry(), runtimeHolder, jsFuncion);
111
116
  }
112
117
 
113
118
  void JavaScriptObject::setProperty(const std::string &name, jsi::Value value) {
@@ -159,6 +164,16 @@ void JavaScriptObject::defineProperty(
159
164
  });
160
165
  }
161
166
 
167
+ jni::local_ref<JavaScriptObject::javaobject> JavaScriptObject::newInstance(
168
+ JSIInteropModuleRegistry *jsiInteropModuleRegistry,
169
+ std::weak_ptr<JavaScriptRuntime> runtime,
170
+ std::shared_ptr<jsi::Object> jsObject
171
+ ) {
172
+ auto object = JavaScriptObject::newObjectCxxArgs(std::move(runtime), std::move(jsObject));
173
+ jsiInteropModuleRegistry->jniDeallocator->addReference(object);
174
+ return object;
175
+ }
176
+
162
177
  void JavaScriptObject::defineNativeDeallocator(
163
178
  jni::alias_ref<JNIFunctionBody::javaobject> deallocator
164
179
  ) {
@@ -7,6 +7,7 @@
7
7
  #include "JavaScriptRuntime.h"
8
8
  #include "WeakRuntimeHolder.h"
9
9
  #include "JNIFunctionBody.h"
10
+ #include "JNIDeallocator.h"
10
11
 
11
12
  #include <fbjni/fbjni.h>
12
13
  #include <jsi/jsi.h>
@@ -24,7 +25,7 @@ class JavaScriptFunction;
24
25
  /**
25
26
  * Represents any JavaScript object. Its purpose is to exposes `jsi::Object` API back to Kotlin.
26
27
  */
27
- class JavaScriptObject : public jni::HybridClass<JavaScriptObject>, JSIObjectWrapper {
28
+ class JavaScriptObject : public jni::HybridClass<JavaScriptObject, Destructible>, JSIObjectWrapper {
28
29
  public:
29
30
  static auto constexpr
30
31
  kJavaDescriptor = "Lexpo/modules/kotlin/jni/JavaScriptObject;";
@@ -32,6 +33,12 @@ public:
32
33
 
33
34
  static void registerNatives();
34
35
 
36
+ static jni::local_ref<JavaScriptObject::javaobject> newInstance(
37
+ JSIInteropModuleRegistry *jsiInteropModuleRegistry,
38
+ std::weak_ptr<JavaScriptRuntime> runtime,
39
+ std::shared_ptr<jsi::Object> jsObject
40
+ );
41
+
35
42
  JavaScriptObject(
36
43
  std::weak_ptr<JavaScriptRuntime> runtime,
37
44
  std::shared_ptr<jsi::Object> jsObject
@@ -84,13 +91,13 @@ private:
84
91
 
85
92
  bool jniHasProperty(jni::alias_ref<jstring> name);
86
93
 
87
- jni::local_ref<jni::HybridClass<JavaScriptValue>::javaobject> jniGetProperty(
94
+ jni::local_ref<jni::HybridClass<JavaScriptValue, Destructible>::javaobject> jniGetProperty(
88
95
  jni::alias_ref<jstring> name
89
96
  );
90
97
 
91
98
  jni::local_ref<jni::JArrayClass<jstring>> jniGetPropertyNames();
92
99
 
93
- jni::local_ref<jni::HybridClass<JavaScriptFunction>::javaobject> jniAsFunction();
100
+ jni::local_ref<jni::HybridClass<JavaScriptFunction, Destructible>::javaobject> jniAsFunction();
94
101
 
95
102
  /**
96
103
  * Unsets property with the given name.
@@ -4,7 +4,7 @@
4
4
  #include "JavaScriptValue.h"
5
5
  #include "JavaScriptObject.h"
6
6
  #include "Exceptions.h"
7
- #include "JavaScriptRuntime.h"
7
+ #include "JSIInteropModuleRegistry.h"
8
8
 
9
9
  #if UNIT_TEST
10
10
 
@@ -125,7 +125,8 @@ jni::local_ref<JavaScriptValue::javaobject>
125
125
  JavaScriptRuntime::evaluateScript(const std::string &script) {
126
126
  auto scriptBuffer = std::make_shared<jsi::StringBuffer>(script);
127
127
  try {
128
- return JavaScriptValue::newObjectCxxArgs(
128
+ return JavaScriptValue::newInstance(
129
+ jsiInteropModuleRegistry,
129
130
  weak_from_this(),
130
131
  std::make_shared<jsi::Value>(runtime->evaluateJavaScript(scriptBuffer, "<<evaluated>>"))
131
132
  );
@@ -148,12 +149,12 @@ JavaScriptRuntime::evaluateScript(const std::string &script) {
148
149
 
149
150
  jni::local_ref<JavaScriptObject::javaobject> JavaScriptRuntime::global() {
150
151
  auto global = std::make_shared<jsi::Object>(runtime->global());
151
- return JavaScriptObject::newObjectCxxArgs(weak_from_this(), global);
152
+ return JavaScriptObject::newInstance(jsiInteropModuleRegistry, weak_from_this(), global);
152
153
  }
153
154
 
154
155
  jni::local_ref<JavaScriptObject::javaobject> JavaScriptRuntime::createObject() {
155
156
  auto newObject = std::make_shared<jsi::Object>(*runtime);
156
- return JavaScriptObject::newObjectCxxArgs(weak_from_this(), newObject);
157
+ return JavaScriptObject::newInstance(jsiInteropModuleRegistry, weak_from_this(), newObject);
157
158
  }
158
159
 
159
160
  void JavaScriptRuntime::drainJSEventLoop() {
@@ -2,6 +2,8 @@
2
2
 
3
3
  #pragma once
4
4
 
5
+ #include "JNIDeallocator.h"
6
+
5
7
  #include <jsi/jsi.h>
6
8
  #include <fbjni/fbjni.h>
7
9
  #include <ReactCommon/CallInvoker.h>
@@ -65,19 +67,19 @@ public:
65
67
  * @throws if the input format is unknown, or evaluation causes an error,
66
68
  * a jni::JniException<JavaScriptEvaluateException> will be thrown.
67
69
  */
68
- jni::local_ref<jni::HybridClass<JavaScriptValue>::javaobject> evaluateScript(
70
+ jni::local_ref<jni::HybridClass<JavaScriptValue, Destructible>::javaobject> evaluateScript(
69
71
  const std::string &script
70
72
  );
71
73
 
72
74
  /**
73
75
  * Returns the runtime global object for use in Kotlin.
74
76
  */
75
- jni::local_ref<jni::HybridClass<JavaScriptObject>::javaobject> global();
77
+ jni::local_ref<jni::HybridClass<JavaScriptObject, Destructible>::javaobject> global();
76
78
 
77
79
  /**
78
80
  * Creates a new object for use in Kotlin.
79
81
  */
80
- jni::local_ref<jni::HybridClass<JavaScriptObject>::javaobject> createObject();
82
+ jni::local_ref<jni::HybridClass<JavaScriptObject, Destructible>::javaobject> createObject();
81
83
 
82
84
  /**
83
85
  * Drains the JavaScript VM internal Microtask (a.k.a. event loop) queue.
@@ -1,6 +1,7 @@
1
1
  #include "JavaScriptTypedArray.h"
2
2
 
3
3
  #include "JavaScriptRuntime.h"
4
+ #include "JSIInteropModuleRegistry.h"
4
5
 
5
6
  namespace expo {
6
7
 
@@ -88,4 +89,17 @@ void JavaScriptTypedArray::writeBuffer(
88
89
  auto region = buffer->getRegion(0, size);
89
90
  memcpy(rawPointer + position, region.get(), size);
90
91
  }
92
+
93
+ jni::local_ref<JavaScriptTypedArray::javaobject> JavaScriptTypedArray::newInstance(
94
+ JSIInteropModuleRegistry *jsiInteropModuleRegistry,
95
+ std::weak_ptr<JavaScriptRuntime> runtime,
96
+ std::shared_ptr<jsi::Object> jsObject
97
+ ) {
98
+ auto object = JavaScriptTypedArray::newObjectCxxArgs(
99
+ std::move(runtime),
100
+ std::move(jsObject)
101
+ );
102
+ jsiInteropModuleRegistry->jniDeallocator->addReference(object);
103
+ return object;
104
+ }
91
105
  }
@@ -25,6 +25,12 @@ public:
25
25
 
26
26
  static void registerNatives();
27
27
 
28
+ static jni::local_ref<JavaScriptTypedArray::javaobject> newInstance(
29
+ JSIInteropModuleRegistry *jsiInteropModuleRegistry,
30
+ std::weak_ptr<JavaScriptRuntime> runtime,
31
+ std::shared_ptr<jsi::Object> jsObject
32
+ );
33
+
28
34
  JavaScriptTypedArray(
29
35
  std::weak_ptr<JavaScriptRuntime> runtime,
30
36
  std::shared_ptr<jsi::Object> jsObject