react-native-nitro-modules 0.20.1 → 0.22.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 (71) hide show
  1. package/NitroModules.podspec +4 -1
  2. package/README.md +1 -1
  3. package/android/CMakeLists.txt +1 -0
  4. package/android/build.gradle +4 -2
  5. package/android/gradle.properties +2 -2
  6. package/android/src/main/cpp/platform/ThreadUtils.cpp +4 -4
  7. package/android/src/main/cpp/registry/JHybridObjectRegistry.hpp +2 -0
  8. package/android/src/main/java/com/margelo/nitro/core/ArrayBuffer.kt +29 -8
  9. package/android/src/main/java/com/margelo/nitro/core/HybridObject.kt +11 -10
  10. package/android/src/main/java/com/margelo/nitro/core/HybridObjectInitializer.java +4 -0
  11. package/android/src/main/java/com/margelo/nitro/core/HybridObjectRegistry.java +2 -0
  12. package/android/src/main/java/com/margelo/nitro/views/HybridView.kt +23 -0
  13. package/cpp/core/ArrayBuffer.cpp +16 -1
  14. package/cpp/core/ArrayBuffer.hpp +20 -1
  15. package/cpp/core/HybridFunction.hpp +1 -1
  16. package/cpp/core/HybridObject.cpp +7 -6
  17. package/cpp/core/HybridObject.hpp +2 -2
  18. package/cpp/core/Promise.hpp +1 -1
  19. package/cpp/entrypoint/HybridNitroModulesProxy.cpp +8 -0
  20. package/cpp/entrypoint/HybridNitroModulesProxy.hpp +1 -0
  21. package/cpp/jsi/JSICache.cpp +1 -0
  22. package/cpp/jsi/JSICache.hpp +6 -0
  23. package/cpp/jsi/JSIConverter+Exception.hpp +1 -1
  24. package/cpp/jsi/JSIConverter+HostObject.hpp +1 -1
  25. package/cpp/jsi/JSIConverter+HybridObject.hpp +1 -1
  26. package/cpp/jsi/JSIConverter+Tuple.hpp +1 -1
  27. package/cpp/jsi/JSIConverter+Variant.hpp +1 -1
  28. package/cpp/jsi/JSIHelpers.hpp +1 -1
  29. package/cpp/prototype/HybridObjectPrototype.cpp +1 -1
  30. package/cpp/registry/HybridObjectRegistry.cpp +25 -12
  31. package/cpp/registry/HybridObjectRegistry.hpp +1 -0
  32. package/cpp/utils/AssertPromiseState.hpp +1 -1
  33. package/cpp/utils/BorrowingReference.hpp +4 -2
  34. package/cpp/utils/NitroDefines.hpp +13 -1
  35. package/cpp/utils/NitroHash.hpp +17 -0
  36. package/cpp/utils/{TypeInfo.hpp → NitroTypeInfo.hpp} +1 -1
  37. package/cpp/utils/OwningReference.hpp +15 -2
  38. package/cpp/views/CachedProp.hpp +43 -0
  39. package/ios/core/ArrayBufferHolder.hpp +3 -3
  40. package/ios/core/ArrayBufferHolder.swift +97 -9
  41. package/ios/core/HybridContext.hpp +1 -1
  42. package/ios/core/{HybridObjectSpec.swift → HybridObject.swift} +10 -2
  43. package/ios/core/PromiseHolder.hpp +1 -1
  44. package/ios/utils/RuntimeError.hpp +1 -1
  45. package/ios/views/HybridView.swift +41 -0
  46. package/lib/commonjs/index.js +11 -0
  47. package/lib/commonjs/index.js.map +1 -1
  48. package/lib/commonjs/views/HybridView.js +17 -0
  49. package/lib/commonjs/views/HybridView.js.map +1 -0
  50. package/lib/commonjs/views/getHostComponent.js +22 -0
  51. package/lib/commonjs/views/getHostComponent.js.map +1 -0
  52. package/lib/module/index.js +1 -0
  53. package/lib/module/index.js.map +1 -1
  54. package/lib/module/views/HybridView.js +30 -0
  55. package/lib/module/views/HybridView.js.map +1 -0
  56. package/lib/module/views/getHostComponent.js +15 -0
  57. package/lib/module/views/getHostComponent.js.map +1 -0
  58. package/lib/tsconfig.build.tsbuildinfo +1 -1
  59. package/lib/typescript/NitroModulesProxy.d.ts +7 -0
  60. package/lib/typescript/NitroModulesProxy.d.ts.map +1 -1
  61. package/lib/typescript/index.d.ts +1 -0
  62. package/lib/typescript/index.d.ts.map +1 -1
  63. package/lib/typescript/views/HybridView.d.ts +35 -0
  64. package/lib/typescript/views/HybridView.d.ts.map +1 -0
  65. package/lib/typescript/views/getHostComponent.d.ts +13 -0
  66. package/lib/typescript/views/getHostComponent.d.ts.map +1 -0
  67. package/package.json +3 -3
  68. package/src/NitroModulesProxy.ts +8 -0
  69. package/src/index.ts +1 -0
  70. package/src/views/HybridView.ts +37 -0
  71. package/src/views/getHostComponent.ts +26 -0
@@ -43,6 +43,7 @@ Pod::Spec.new do |s|
43
43
  "cpp/threading/Dispatcher.hpp",
44
44
  "cpp/utils/NitroHash.hpp",
45
45
  "cpp/utils/NitroDefines.hpp",
46
+ "cpp/views/CachedProp.hpp",
46
47
  # Public iOS-specific headers that will be exposed in modulemap (for Swift)
47
48
  "ios/core/ArrayBufferHolder.hpp",
48
49
  "ios/core/AnyMapHolder.hpp",
@@ -60,11 +61,13 @@ Pod::Spec.new do |s|
60
61
  "SWIFT_OBJC_INTEROP_MODE" => "objcxx",
61
62
  # Enables stricter modular headers
62
63
  "DEFINES_MODULE" => "YES",
63
- # C++ compiler flags, mainly for folly.
64
+ # C++ compiler flags, mainly for RN version and folly.
64
65
  "GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) FOLLY_NO_CONFIG FOLLY_CFG_NO_COROUTINES"
65
66
  }
66
67
 
68
+ # Nitro depends on JSI.
67
69
  s.dependency 'React-jsi'
70
+ # For React Native, we implement nitro::Dispatcher using react::CallInvoker
68
71
  s.dependency 'React-callinvoker'
69
72
  install_modules_dependencies(s)
70
73
  end
package/README.md CHANGED
@@ -208,7 +208,7 @@ The following C++ / JS types are supported out of the box:
208
208
  <tr>
209
209
  <td>..any <code><a href="./src/HybridObject.ts">HybridObject</a></code></td>
210
210
  <td><code>std::shared_ptr&lt;<a href="./cpp/core/HybridObject.hpp">HybridObject</a>&gt;</code></td>
211
- <td><code><a href="./ios/core/HybridObjectSpec.swift">HybridObjectSpec</a></code></td>
211
+ <td><code><a href="./ios/core/HybridObject.swift">HybridObject</a></code></td>
212
212
  <td><code><a href="./android/src/main/java/com/margelo/nitro/core/HybridObject.kt">HybridObject</a></code></td>
213
213
  </tr>
214
214
  <tr>
@@ -32,6 +32,7 @@ include_directories(
32
32
  ../cpp/threading
33
33
  ../cpp/turbomodule
34
34
  ../cpp/utils
35
+ ../cpp/views
35
36
  # Android-specific C++ includes
36
37
  src/main/cpp/core
37
38
  src/main/cpp/registry
@@ -1,3 +1,5 @@
1
+ import groovy.json.JsonSlurper
2
+
1
3
  buildscript {
2
4
  repositories {
3
5
  google()
@@ -5,7 +7,7 @@ buildscript {
5
7
  }
6
8
 
7
9
  dependencies {
8
- classpath "com.android.tools.build:gradle:8.7.3"
10
+ classpath "com.android.tools.build:gradle:8.8.0"
9
11
  }
10
12
  }
11
13
 
@@ -154,7 +156,7 @@ if (isNewArchitectureEnabled()) {
154
156
  }
155
157
  }
156
158
 
157
- task prepareHeaders(type: Copy) {
159
+ tasks.register('prepareHeaders', Copy) {
158
160
  from fileTree('./src/main/cpp').filter { it.isFile() }
159
161
  from fileTree('../cpp/').filter { it.isFile() }
160
162
  include "*.hpp"
@@ -1,5 +1,5 @@
1
- Nitro_kotlinVersion=1.9.24
1
+ Nitro_kotlinVersion=2.0.21
2
2
  Nitro_minSdkVersion=23
3
3
  Nitro_targetSdkVersion=34
4
4
  Nitro_compileSdkVersion=34
5
- Nitro_ndkVersion=26.1.10909125
5
+ Nitro_ndkVersion=27.1.12297006
@@ -17,12 +17,12 @@ namespace margelo::nitro {
17
17
  std::string ThreadUtils::getThreadName() {
18
18
  #ifdef HAVE_ANDROID_PTHREAD_SETNAME_NP
19
19
  // Try using pthread APIs
20
- pthread_t this_thread = pthread_self();
21
- char thread_name[16]; // Thread name length limit in Android is 16 characters
20
+ pthread_t thisThread = pthread_self();
21
+ char threadName[16]; // Thread name length limit in Android is 16 characters
22
22
 
23
- int result = pthread_getname_np(this_thread, thread_name, sizeof(thread_name));
23
+ int result = pthread_getname_np(thisThread, threadName, sizeof(threadName));
24
24
  if (result == 0) {
25
- return std::string(thread_name);
25
+ return std::string(threadName);
26
26
  }
27
27
  #endif
28
28
 
@@ -20,6 +20,8 @@ public:
20
20
  static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/core/HybridObjectRegistry;";
21
21
 
22
22
  public:
23
+ [[deprecated("HybridObjects should be registered from C++ instead. Either autolink them using `nitro.json`, "
24
+ "or add them manually in the C++ HybridObjectRegistry.")]]
23
25
  static void registerHybridObjectConstructor(jni::alias_ref<jni::JClass> clazz, std::string hybridObjectName,
24
26
  jni::alias_ref<JHybridObjectInitializer> constructorFn);
25
27
 
@@ -107,19 +107,40 @@ class ArrayBuffer {
107
107
  /**
108
108
  * Copy the given `ArrayBuffer` into a new **owning** `ArrayBuffer`.
109
109
  */
110
- fun copyOf(other: ArrayBuffer): ArrayBuffer {
111
- // 1. Create a new buffer with the same size as the other
112
- val newBuffer = ByteBuffer.allocateDirect(other.size)
113
- // 2. Prepare the source buffer
114
- val originalBuffer = other.getBuffer(false)
115
- originalBuffer.rewind()
110
+ fun copy(other: ArrayBuffer): ArrayBuffer {
111
+ val byteBuffer = other.getBuffer(false)
112
+ return copy(byteBuffer)
113
+ }
114
+
115
+ /**
116
+ * Copy the given `ByteBuffer` into a new **owning** `ArrayBuffer`.
117
+ */
118
+ fun copy(byteBuffer: ByteBuffer): ArrayBuffer {
119
+ // 1. Find out size
120
+ byteBuffer.rewind()
121
+ val size = byteBuffer.remaining()
122
+ // 2. Create a new buffer with the same size as the other
123
+ val newBuffer = ByteBuffer.allocateDirect(size)
116
124
  // 3. Copy over the source buffer into the new buffer
117
- newBuffer.put(originalBuffer)
125
+ newBuffer.put(byteBuffer)
118
126
  // 4. Rewind both buffers again to index 0
119
127
  newBuffer.rewind()
120
- originalBuffer.rewind()
128
+ byteBuffer.rewind()
121
129
  // 5. Create a new `ArrayBuffer`
122
130
  return ArrayBuffer(newBuffer)
123
131
  }
132
+
133
+ /**
134
+ * Wrap the given `ByteBuffer` in a new **owning** `ArrayBuffer`.
135
+ */
136
+ fun wrap(byteBuffer: ByteBuffer): ArrayBuffer {
137
+ byteBuffer.rewind()
138
+ return ArrayBuffer(byteBuffer)
139
+ }
140
+
141
+ @Deprecated("Use copy(...) instead", level = DeprecationLevel.WARNING)
142
+ fun copyOf(other: ArrayBuffer): ArrayBuffer {
143
+ return copy(other)
144
+ }
124
145
  }
125
146
  }
@@ -4,16 +4,12 @@ import androidx.annotation.Keep
4
4
  import com.facebook.jni.HybridData
5
5
  import com.facebook.proguard.annotations.DoNotStrip
6
6
 
7
- interface ExtendableHybridClass {
8
- fun updateNative(hybridData: HybridData)
9
- }
10
-
11
7
  /**
12
8
  * A base class for all Kotlin-based HybridObjects.
13
9
  */
14
10
  @Keep
15
11
  @DoNotStrip
16
- abstract class HybridObject: ExtendableHybridClass {
12
+ abstract class HybridObject {
17
13
  /**
18
14
  * Get the memory size of the Kotlin instance (plus any external heap allocations),
19
15
  * in bytes.
@@ -23,7 +19,7 @@ abstract class HybridObject: ExtendableHybridClass {
23
19
  *
24
20
  * @example
25
21
  * ```kotlin
26
- * val memorySize: ULong
22
+ * override val memorySize: ULong
27
23
  * get() {
28
24
  * val imageSize = this.bitmap.bytesPerRow * this.bitmap.height
29
25
  * return imageSize
@@ -32,7 +28,8 @@ abstract class HybridObject: ExtendableHybridClass {
32
28
  */
33
29
  @get:DoNotStrip
34
30
  @get:Keep
35
- abstract val memorySize: Long
31
+ open val memorySize: Long
32
+ get() = 0L
36
33
 
37
34
  /**
38
35
  * Holds the native C++ instance.
@@ -42,10 +39,14 @@ abstract class HybridObject: ExtendableHybridClass {
42
39
  private var mHybridData: HybridData? = null
43
40
 
44
41
  /**
45
- * Must be called in the constructor of a subclass of `HybridObject`, to initialize the C++
46
- * `JHybridObject` with a subclass of it.
42
+ * If `HybridObject` is subclassed, the sub-class needs to create it's own `HybridData`
43
+ * with a C++ `jni::HybridClass` representing the subclass directly.
44
+ * Then, that `HybridData` must be passed upwards to `HybridObject` using `updateNative(..)`.
45
+ *
46
+ * This must happen for each sub/base class in the whole inheritance chain to ensure
47
+ * overrides and type-erasure works as expected.
47
48
  */
48
- override fun updateNative(hybridData: HybridData) {
49
+ protected open fun updateNative(hybridData: HybridData) {
49
50
  mHybridData = hybridData
50
51
  }
51
52
  }
@@ -4,8 +4,12 @@ import androidx.annotation.Keep;
4
4
 
5
5
  import com.facebook.proguard.annotations.DoNotStrip;
6
6
 
7
+ /**
8
+ * @deprecated HybridObjects should be registered from C++ instead. Either autolink them using `nitro.json`, or add them manually in the C++ `HybridObjectRegistry`.
9
+ */
7
10
  @Keep
8
11
  @DoNotStrip
12
+ @Deprecated(forRemoval = true)
9
13
  public interface HybridObjectInitializer {
10
14
  @Keep
11
15
  @DoNotStrip
@@ -20,6 +20,8 @@ public class HybridObjectRegistry {
20
20
  * Registers the given HybridObject in the `HybridObjectRegistry`.
21
21
  * It will be uniquely identified via it's `hybridObjectName`, and can be initialized from
22
22
  * JS using `NitroModules.createHybridObject<T>(name)` - which will call the `constructorFn` here.
23
+ * @deprecated HybridObjects should be registered from C++ instead. Either autolink them using `nitro.json`, or add them manually in the C++ `HybridObjectRegistry`.
23
24
  */
25
+ @Deprecated(forRemoval = true)
24
26
  public static native void registerHybridObjectConstructor(String hybridObjectName, HybridObjectInitializer initializer);
25
27
  }
@@ -0,0 +1,23 @@
1
+ package com.margelo.nitro.views
2
+
3
+ import android.view.View
4
+ import androidx.annotation.Keep
5
+ import com.facebook.jni.HybridData
6
+ import com.facebook.proguard.annotations.DoNotStrip
7
+ import com.margelo.nitro.core.HybridObject
8
+
9
+ /**
10
+ * A base class for all Kotlin-based Hybrid Views.
11
+ */
12
+ @Keep
13
+ @DoNotStrip
14
+ abstract class HybridView: HybridObject() {
15
+ /**
16
+ * Get the `UIView` this HybridView is holding.
17
+ *
18
+ * This value should not change during the lifetime of this `HybridView`.
19
+ */
20
+ @get:DoNotStrip
21
+ @get:Keep
22
+ abstract val view: View
23
+ }
@@ -17,10 +17,25 @@ using namespace facebook;
17
17
 
18
18
  // 1. ArrayBuffer
19
19
 
20
- std::shared_ptr<ArrayBuffer> ArrayBuffer::makeBuffer(uint8_t* data, size_t size, DeleteFn&& deleteFunc) {
20
+ std::shared_ptr<ArrayBuffer> ArrayBuffer::wrap(uint8_t* data, size_t size, DeleteFn&& deleteFunc) {
21
21
  return std::make_shared<NativeArrayBuffer>(data, size, std::move(deleteFunc));
22
22
  }
23
23
 
24
+ std::shared_ptr<ArrayBuffer> ArrayBuffer::copy(uint8_t* data, size_t size) {
25
+ uint8_t* copy = new uint8_t[size];
26
+ std::memcpy(copy, data, size);
27
+ return ArrayBuffer::wrap(copy, size, [=]() { delete[] copy; });
28
+ }
29
+
30
+ std::shared_ptr<ArrayBuffer> ArrayBuffer::copy(std::vector<uint8_t>& data) {
31
+ return ArrayBuffer::copy(data.data(), data.size());
32
+ }
33
+
34
+ std::shared_ptr<ArrayBuffer> ArrayBuffer::allocate(size_t size) {
35
+ uint8_t* data = new uint8_t[size];
36
+ return ArrayBuffer::wrap(data, size, [=]() { delete[] data; });
37
+ }
38
+
24
39
  // 2. NativeArrayBuffer
25
40
 
26
41
  NativeArrayBuffer::NativeArrayBuffer(uint8_t* data, size_t size, DeleteFn&& deleteFunc)
@@ -10,6 +10,7 @@
10
10
  #include "OwningReference.hpp"
11
11
  #include <jsi/jsi.h>
12
12
  #include <thread>
13
+ #include <vector>
13
14
 
14
15
  namespace margelo::nitro {
15
16
 
@@ -52,7 +53,25 @@ public:
52
53
  * Create a new `NativeArrayBuffer` that wraps the given data (without copy) of the given size,
53
54
  * and calls `deleteFunc` in which `data` should be deleted.
54
55
  */
55
- static std::shared_ptr<ArrayBuffer> makeBuffer(uint8_t* data, size_t size, DeleteFn&& deleteFunc);
56
+ static std::shared_ptr<ArrayBuffer> wrap(uint8_t* data, size_t size, DeleteFn&& deleteFunc);
57
+ /**
58
+ * Create a new `NativeArrayBuffer` that copies the given data of the given size
59
+ * into a newly allocated buffer.
60
+ */
61
+ static std::shared_ptr<ArrayBuffer> copy(uint8_t* data, size_t size);
62
+ /**
63
+ * Create a new `NativeArrayBuffer` that copies the given `std::vector`.
64
+ */
65
+ static std::shared_ptr<ArrayBuffer> copy(std::vector<uint8_t>& data);
66
+ /**
67
+ * Create a new `NativeArrayBuffer` that allocates a new buffer of the given size.
68
+ */
69
+ static std::shared_ptr<ArrayBuffer> allocate(size_t size);
70
+
71
+ [[deprecated("Use wrapBuffer(...) instead.")]]
72
+ static std::shared_ptr<ArrayBuffer> makeBuffer(uint8_t* data, size_t size, DeleteFn&& deleteFunc) {
73
+ return ArrayBuffer::wrap(data, size, std::move(deleteFunc));
74
+ }
56
75
  };
57
76
 
58
77
  /**
@@ -15,7 +15,7 @@ struct JSIConverter;
15
15
  #include "CountTrailingOptionals.hpp"
16
16
  #include "JSIConverter.hpp"
17
17
  #include "NitroDefines.hpp"
18
- #include "TypeInfo.hpp"
18
+ #include "NitroTypeInfo.hpp"
19
19
  #include <exception>
20
20
  #include <functional>
21
21
  #include <jsi/jsi.h>
@@ -9,7 +9,6 @@
9
9
  namespace margelo::nitro {
10
10
 
11
11
  HybridObject::HybridObject(const char* name) : HybridObjectPrototype(), _name(name) {}
12
- HybridObject::~HybridObject() {}
13
12
 
14
13
  std::string HybridObject::toString() {
15
14
  return "[HybridObject " + std::string(_name) + "]";
@@ -19,7 +18,7 @@ std::string HybridObject::getName() {
19
18
  return _name;
20
19
  }
21
20
 
22
- bool HybridObject::equals(std::shared_ptr<HybridObject> other) {
21
+ bool HybridObject::equals(const std::shared_ptr<HybridObject>& other) {
23
22
  return this == other.get();
24
23
  }
25
24
 
@@ -48,10 +47,12 @@ jsi::Value HybridObject::toObject(jsi::Runtime& runtime) {
48
47
  if (cachedObject != _objectCache.end()) {
49
48
  // 1.1. We have a WeakObject, try to see if it is still alive
50
49
  OwningLock<jsi::WeakObject> lock = cachedObject->second.lock();
51
- jsi::Value object = cachedObject->second->lock(runtime);
52
- if (!object.isUndefined()) {
53
- // 1.2. It is still alive - we can use it instead of creating a new one!
54
- return object;
50
+ jsi::Value value = cachedObject->second->lock(runtime);
51
+ if (!value.isUndefined()) {
52
+ // 1.2. It is still alive - we can use it instead of creating a new one! But first, let's update memory-size
53
+ value.getObject(runtime).setExternalMemoryPressure(runtime, getExternalMemorySize());
54
+ // 1.3. Return it now
55
+ return value;
55
56
  }
56
57
  }
57
58
 
@@ -34,7 +34,7 @@ public:
34
34
  * Called when no more references to the given `HybridObject` exist in both C++ and JS.
35
35
  * JS might keep references for longer, as it is a garbage collected language.
36
36
  */
37
- virtual ~HybridObject();
37
+ ~HybridObject() override = default;
38
38
  /**
39
39
  * HybridObjects cannot be copied.
40
40
  */
@@ -80,7 +80,7 @@ public:
80
80
  * While two `jsi::Object`s of the same `HybridObject` might not be equal when compared with `==`,
81
81
  * they might still be the same `HybridObject` - in this case `equals(other)` will return true.
82
82
  */
83
- bool equals(std::shared_ptr<HybridObject> other);
83
+ bool equals(const std::shared_ptr<HybridObject>& other);
84
84
  /**
85
85
  * Get a string representation of this `HybridObject` - useful for logging or debugging.
86
86
  */
@@ -6,8 +6,8 @@
6
6
 
7
7
  #include "AssertPromiseState.hpp"
8
8
  #include "NitroDefines.hpp"
9
+ #include "NitroTypeInfo.hpp"
9
10
  #include "ThreadPool.hpp"
10
- #include "TypeInfo.hpp"
11
11
  #include <exception>
12
12
  #include <future>
13
13
  #include <jsi/jsi.h>
@@ -7,6 +7,7 @@
7
7
 
8
8
  #include "HybridNitroModulesProxy.hpp"
9
9
  #include "HybridObjectRegistry.hpp"
10
+ #include "JSIConverter.hpp"
10
11
  #include "NitroDefines.hpp"
11
12
 
12
13
  namespace margelo::nitro {
@@ -20,6 +21,7 @@ void HybridNitroModulesProxy::loadHybridMethods() {
20
21
  prototype.registerHybridMethod("getAllHybridObjectNames", &HybridNitroModulesProxy::getAllHybridObjectNames);
21
22
 
22
23
  prototype.registerHybridMethod("box", &HybridNitroModulesProxy::box);
24
+ prototype.registerHybridMethod("updateMemorySize", &HybridNitroModulesProxy::updateMemorySize);
23
25
 
24
26
  prototype.registerRawHybridMethod("hasNativeState", 1, &HybridNitroModulesProxy::hasNativeState);
25
27
 
@@ -53,6 +55,12 @@ jsi::Value HybridNitroModulesProxy::hasNativeState(jsi::Runtime& runtime, const
53
55
  return args[0].getObject(runtime).hasNativeState(runtime);
54
56
  }
55
57
 
58
+ std::shared_ptr<HybridObject> HybridNitroModulesProxy::updateMemorySize(const std::shared_ptr<HybridObject>& hybridObject) {
59
+ // If a hybridObject goes from Native -> JS, it will update it's memory size internally (in `HybridObject::toObject(..)`).
60
+ // This is all that function does.
61
+ return hybridObject;
62
+ }
63
+
56
64
  // Build Info
57
65
  std::string HybridNitroModulesProxy::getBuildType() {
58
66
  #ifdef NITRO_DEBUG
@@ -37,6 +37,7 @@ public:
37
37
 
38
38
  // Helpers
39
39
  std::shared_ptr<BoxedHybridObject> box(const std::shared_ptr<HybridObject>& hybridObject);
40
+ std::shared_ptr<HybridObject> updateMemorySize(const std::shared_ptr<HybridObject>& hybridObject);
40
41
  jsi::Value hasNativeState(jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* args, size_t size);
41
42
 
42
43
  // Build Info
@@ -28,6 +28,7 @@ JSICache::~JSICache() {
28
28
  Logger::log(LogLevel::Info, TAG, "Destroying JSICache...");
29
29
  std::unique_lock lock(_mutex);
30
30
 
31
+ destroyReferences(_valueCache);
31
32
  destroyReferences(_objectCache);
32
33
  destroyReferences(_functionCache);
33
34
  destroyReferences(_weakObjectCache);
@@ -59,6 +59,7 @@ private:
59
59
 
60
60
  private:
61
61
  std::mutex _mutex;
62
+ std::vector<BorrowingReference<jsi::Value>> _valueCache;
62
63
  std::vector<BorrowingReference<jsi::Object>> _objectCache;
63
64
  std::vector<BorrowingReference<jsi::Function>> _functionCache;
64
65
  std::vector<BorrowingReference<jsi::WeakObject>> _weakObjectCache;
@@ -82,6 +83,11 @@ public:
82
83
  }
83
84
 
84
85
  public:
86
+ OwningReference<jsi::Value> makeShared(jsi::Value&& value) {
87
+ OwningReference<jsi::Value> owning(new jsi::Value(std::move(value)));
88
+ _strongCache->_valueCache.push_back(owning.weak());
89
+ return owning;
90
+ }
85
91
  OwningReference<jsi::Object> makeShared(jsi::Object&& value) {
86
92
  OwningReference<jsi::Object> owning(new jsi::Object(std::move(value)));
87
93
  _strongCache->_objectCache.push_back(owning.weak());
@@ -12,7 +12,7 @@ struct JSIConverter;
12
12
 
13
13
  #include "JSIConverter.hpp"
14
14
 
15
- #include "TypeInfo.hpp"
15
+ #include "NitroTypeInfo.hpp"
16
16
  #include <exception>
17
17
  #include <jsi/jsi.h>
18
18
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  #include "IsSharedPtrTo.hpp"
8
8
  #include "NitroDefines.hpp"
9
- #include "TypeInfo.hpp"
9
+ #include "NitroTypeInfo.hpp"
10
10
  #include <jsi/jsi.h>
11
11
  #include <type_traits>
12
12
 
@@ -11,7 +11,7 @@ class HybridObject;
11
11
 
12
12
  #include "IsSharedPtrTo.hpp"
13
13
  #include "NitroDefines.hpp"
14
- #include "TypeInfo.hpp"
14
+ #include "NitroTypeInfo.hpp"
15
15
  #include <jsi/jsi.h>
16
16
  #include <type_traits>
17
17
 
@@ -12,7 +12,7 @@ struct JSIConverter;
12
12
 
13
13
  #include "JSIConverter.hpp"
14
14
 
15
- #include "TypeInfo.hpp"
15
+ #include "NitroTypeInfo.hpp"
16
16
  #include <jsi/jsi.h>
17
17
  #include <memory>
18
18
  #include <tuple>
@@ -18,7 +18,7 @@ struct JSIConverter;
18
18
  #include "JSIConverter.hpp"
19
19
 
20
20
  #include "AnyMap.hpp"
21
- #include "TypeInfo.hpp"
21
+ #include "NitroTypeInfo.hpp"
22
22
  #include <jsi/jsi.h>
23
23
  #include <memory>
24
24
  #include <variant>
@@ -46,7 +46,7 @@ static inline bool isPlainObject(jsi::Runtime& runtime, const jsi::Object& objec
46
46
  */
47
47
  static inline std::string getRuntimeId(jsi::Runtime& runtime) {
48
48
  std::string threadName = ThreadUtils::getThreadName();
49
- return runtime.description() + std::string(" (") + threadName + std::string(")");
49
+ return runtime.description() + " (" + threadName + ")";
50
50
  }
51
51
 
52
52
  } // namespace margelo::nitro
@@ -8,7 +8,7 @@
8
8
  #include "HybridObjectPrototype.hpp"
9
9
  #include "NitroDefines.hpp"
10
10
  #include "NitroLogger.hpp"
11
- #include "TypeInfo.hpp"
11
+ #include "NitroTypeInfo.hpp"
12
12
 
13
13
  namespace margelo::nitro {
14
14
 
@@ -8,6 +8,7 @@
8
8
  #include "HybridObjectRegistry.hpp"
9
9
  #include "NitroDefines.hpp"
10
10
  #include "NitroLogger.hpp"
11
+ #include <numeric>
11
12
 
12
13
  namespace margelo::nitro {
13
14
 
@@ -29,17 +30,25 @@ std::vector<std::string> HybridObjectRegistry::getAllHybridObjectNames() {
29
30
  return keys;
30
31
  }
31
32
 
33
+ std::string HybridObjectRegistry::getAllRegisteredHybridObjectNamesToString() {
34
+ std::vector<std::string> names = getAllHybridObjectNames();
35
+ return std::accumulate(std::next(names.begin()), names.end(), names[0], [](std::string a, std::string b) { return a + ", " + b; });
36
+ }
37
+
32
38
  void HybridObjectRegistry::registerHybridObjectConstructor(const std::string& hybridObjectName, HybridObjectConstructorFn&& constructorFn) {
33
39
  Logger::log(LogLevel::Info, TAG, "Registering HybridObject \"%s\"...", hybridObjectName.c_str());
34
40
  auto& map = HybridObjectRegistry::getRegistry();
35
41
  #ifdef NITRO_DEBUG
36
42
  if (map.contains(hybridObjectName)) [[unlikely]] {
43
+ auto allObjectNames = getAllRegisteredHybridObjectNamesToString();
37
44
  auto message =
38
- "HybridObject \"" + std::string(hybridObjectName) +
45
+ "HybridObject \"" + hybridObjectName +
39
46
  "\" has already been "
40
47
  "registered in the Nitro Modules HybridObjectRegistry! Suggestions:\n"
41
48
  "- If you just installed another library, maybe both libraries are using the same name?\n"
42
- "- If you just registered your own HybridObject, maybe you accidentally called `registerHybridObjectConstructor(...)` twice?";
49
+ "- If you just registered your own HybridObject, maybe you accidentally called `registerHybridObjectConstructor(...)` twice?\n"
50
+ "- All registered HybridObjects: [" +
51
+ allObjectNames + "]";
43
52
  throw std::runtime_error(message);
44
53
  }
45
54
  #endif
@@ -57,16 +66,20 @@ std::shared_ptr<HybridObject> HybridObjectRegistry::createHybridObject(const std
57
66
  auto& map = HybridObjectRegistry::getRegistry();
58
67
  auto fn = map.find(hybridObjectName);
59
68
  if (fn == map.end()) [[unlikely]] {
60
- auto message = "Cannot create an instance of HybridObject \"" + std::string(hybridObjectName) +
61
- "\" - It has not yet been registered in the Nitro Modules HybridObjectRegistry! Suggestions:\n"
62
- "- If you use Nitrogen, make sure your `nitro.json` contains `" +
63
- std::string(hybridObjectName) +
64
- "` on this platform.\n"
65
- "- If you use Nitrogen, make sure your library (*Package.java)/app (MainApplication.java) calls "
66
- "`System.loadLibrary(\"$$androidCxxLibName$$\")` somewhere on app-startup.\n"
67
- "- If you use Nitrogen, make sure your cpp-adapter.cpp calls `margelo::nitro::$$cxxNamespace$$::initialize(vm)`.\n"
68
- "- If you use Nitrogen, inspect the generated `$$androidCxxLibName$$OnLoad.cpp` file.\n"
69
- "- If you don't use Nitrogen, make sure you called `HybridObjectRegistry.registerHybridObject(...)`.";
69
+ auto allObjectNames = getAllRegisteredHybridObjectNamesToString();
70
+ auto message =
71
+ "Cannot create an instance of HybridObject \"" + hybridObjectName +
72
+ "\" - It has not yet been registered in the Nitro Modules HybridObjectRegistry! Suggestions:\n"
73
+ "- If you use Nitrogen, make sure your `nitro.json` contains `" +
74
+ hybridObjectName +
75
+ "` on this platform.\n"
76
+ "- If you use Nitrogen, make sure your library (*Package.java)/app (MainApplication.java) calls "
77
+ "`$$androidCxxLibName$$OnLoad.initializeNative()` somewhere on app-startup.\n"
78
+ "- If you use Nitrogen, make sure your `cpp-adapter.cpp`/`OnLoad.cpp` calls `margelo::nitro::$$cxxNamespace$$::initialize(vm)`.\n"
79
+ "- If you use Nitrogen, inspect the generated `$$androidCxxLibName$$OnLoad.cpp` file.\n"
80
+ "- If you don't use Nitrogen, make sure you called `HybridObjectRegistry.registerHybridObject(...)`."
81
+ "- All registered HybridObjects: [" +
82
+ allObjectNames + "]";
70
83
  throw std::runtime_error(message);
71
84
  }
72
85
  std::shared_ptr<HybridObject> instance = fn->second();
@@ -44,6 +44,7 @@ public:
44
44
 
45
45
  private:
46
46
  static std::unordered_map<std::string, HybridObjectConstructorFn>& getRegistry();
47
+ static std::string getAllRegisteredHybridObjectNamesToString();
47
48
 
48
49
  private:
49
50
  static constexpr auto TAG = "HybridObjectRegistry";
@@ -12,8 +12,8 @@ template <typename TResult>
12
12
  class Promise;
13
13
  } // namespace margelo::nitro
14
14
 
15
+ #include "NitroTypeInfo.hpp"
15
16
  #include "Promise.hpp"
16
- #include "TypeInfo.hpp"
17
17
  #include <exception>
18
18
  #include <string>
19
19
 
@@ -32,8 +32,10 @@ public:
32
32
  BorrowingReference(const BorrowingReference& ref)
33
33
  : _value(ref._value), _isDeleted(ref._isDeleted), _strongRefCount(ref._strongRefCount), _weakRefCount(ref._weakRefCount),
34
34
  _mutex(ref._mutex) {
35
- // increment ref count after copy
36
- (*_weakRefCount)++;
35
+ if (_weakRefCount != nullptr) {
36
+ // increment ref count after copy
37
+ (*_weakRefCount)++;
38
+ }
37
39
  }
38
40
 
39
41
  BorrowingReference(BorrowingReference&& ref)