react-native-nitro-modules 0.31.10 → 0.32.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 (50) hide show
  1. package/NitroModules.podspec +2 -1
  2. package/android/build.gradle +1 -1
  3. package/android/src/main/cpp/core/JAnyMap.cpp +218 -0
  4. package/android/src/main/cpp/core/JAnyMap.hpp +46 -56
  5. package/android/src/main/cpp/platform/NitroLogger.cpp +3 -1
  6. package/android/src/main/java/com/margelo/nitro/core/AnyMap.kt +22 -24
  7. package/android/src/main/java/com/margelo/nitro/core/ArrayBuffer.kt +2 -2
  8. package/android/src/main/java/com/margelo/nitro/core/HybridObject.kt +3 -3
  9. package/cpp/core/AnyMap.cpp +1 -1
  10. package/cpp/core/AnyMap.hpp +3 -3
  11. package/cpp/core/ArrayBuffer.hpp +3 -3
  12. package/cpp/core/HybridObject.cpp +10 -10
  13. package/cpp/core/HybridObject.hpp +3 -3
  14. package/cpp/entrypoint/HybridNitroModulesProxy.cpp +1 -1
  15. package/cpp/entrypoint/InstallNitro.cpp +2 -2
  16. package/cpp/jsi/JSICache.cpp +10 -5
  17. package/cpp/jsi/JSICache.hpp +6 -0
  18. package/cpp/jsi/JSIConverter+AnyMap.hpp +4 -3
  19. package/cpp/jsi/JSIConverter+ArrayBuffer.hpp +2 -2
  20. package/cpp/jsi/JSIConverter+Date.hpp +8 -10
  21. package/cpp/jsi/JSIConverter+Exception.hpp +5 -5
  22. package/cpp/jsi/JSIConverter+Function.hpp +4 -1
  23. package/cpp/jsi/JSIConverter+NativeState.hpp +1 -1
  24. package/cpp/jsi/JSIConverter+Promise.hpp +8 -14
  25. package/cpp/jsi/JSIConverter+UnorderedMap.hpp +2 -1
  26. package/cpp/jsi/JSIHelpers.hpp +1 -1
  27. package/cpp/platform/NitroLogger.hpp +3 -1
  28. package/cpp/prototype/HybridObjectPrototype.cpp +28 -28
  29. package/cpp/prototype/PrototypeChain.hpp +1 -1
  30. package/cpp/registry/HybridObjectRegistry.hpp +1 -1
  31. package/cpp/threading/CallInvokerDispatcher.hpp +1 -1
  32. package/cpp/threading/Dispatcher.cpp +5 -5
  33. package/cpp/utils/BorrowingReference.hpp +6 -6
  34. package/cpp/utils/CommonGlobals.cpp +215 -0
  35. package/cpp/utils/CommonGlobals.hpp +158 -0
  36. package/cpp/utils/JSCallback.hpp +1 -1
  37. package/cpp/utils/NitroDefines.hpp +1 -1
  38. package/cpp/utils/PropNameIDCache.cpp +38 -0
  39. package/cpp/utils/PropNameIDCache.hpp +44 -0
  40. package/cpp/utils/{WeakReference+Owning.hpp → WeakReference+Borrowing.hpp} +1 -1
  41. package/cpp/utils/WeakReference.hpp +1 -1
  42. package/ios/core/HybridObject.swift +1 -1
  43. package/ios/platform/NitroLogger.cpp +37 -0
  44. package/ios/platform/ThreadUtils.cpp +43 -0
  45. package/ios/utils/SwiftClosure.swift +1 -1
  46. package/package.json +1 -2
  47. package/cpp/utils/ObjectUtils.cpp +0 -172
  48. package/cpp/utils/ObjectUtils.hpp +0 -94
  49. package/ios/platform/NitroLogger.mm +0 -36
  50. package/ios/platform/ThreadUtils.mm +0 -46
@@ -0,0 +1,215 @@
1
+ //
2
+ // CommonGlobals.cpp
3
+ // react-native-nitro
4
+ //
5
+ // Created by Marc Rousavy on 17.10.25.
6
+ //
7
+
8
+ #include "CommonGlobals.hpp"
9
+ #include "JSICache.hpp"
10
+ #include "JSIHelpers.hpp"
11
+ #include "NitroDefines.hpp"
12
+ #include "PropNameIDCache.hpp"
13
+
14
+ #if __has_include(<cxxreact/ReactNativeVersion.h>)
15
+ #include <cxxreact/ReactNativeVersion.h>
16
+ #if REACT_NATIVE_VERSION_MINOR >= 78
17
+ #define ENABLE_NATIVE_OBJECT_CREATE
18
+ #endif
19
+ #endif
20
+
21
+ namespace margelo::nitro {
22
+
23
+ using namespace facebook;
24
+
25
+ std::unordered_map<jsi::Runtime*, CommonGlobals::FunctionCache> CommonGlobals::_cache;
26
+
27
+ // pragma MARK: Object
28
+
29
+ jsi::Object CommonGlobals::Object::create(jsi::Runtime& runtime, const jsi::Value& prototype) {
30
+ #ifdef ENABLE_NATIVE_OBJECT_CREATE
31
+ return jsi::Object::create(runtime, prototype);
32
+ #else
33
+ const jsi::Function& createFn = getGlobalFunction(runtime, "Object.create", [](jsi::Runtime& runtime) {
34
+ return runtime.global().getPropertyAsObject(runtime, "Object").getPropertyAsFunction(runtime, "create");
35
+ });
36
+ return createFn.call(runtime, prototype).getObject(runtime);
37
+ #endif
38
+ }
39
+
40
+ void CommonGlobals::Object::defineProperty(jsi::Runtime& runtime, const jsi::Object& object, const char* propertyName,
41
+ PlainPropertyDescriptor&& descriptor) {
42
+ const jsi::Function& definePropertyFn = getGlobalFunction(runtime, "Object.defineProperty", [](jsi::Runtime& runtime) {
43
+ return runtime.global().getPropertyAsObject(runtime, "Object").getPropertyAsFunction(runtime, "defineProperty");
44
+ });
45
+
46
+ jsi::String nameJs = jsi::String::createFromAscii(runtime, propertyName);
47
+
48
+ jsi::Object descriptorJs(runtime);
49
+ descriptorJs.setProperty(runtime, PropNameIDCache::get(runtime, "configurable"), jsi::Value(descriptor.configurable));
50
+ descriptorJs.setProperty(runtime, PropNameIDCache::get(runtime, "enumerable"), jsi::Value(descriptor.enumerable));
51
+ descriptorJs.setProperty(runtime, PropNameIDCache::get(runtime, "value"), std::move(descriptor.value));
52
+ descriptorJs.setProperty(runtime, PropNameIDCache::get(runtime, "writable"), jsi::Value(descriptor.writable));
53
+
54
+ definePropertyFn.call(runtime, object, std::move(nameJs), std::move(descriptorJs));
55
+ }
56
+
57
+ void CommonGlobals::Object::defineProperty(jsi::Runtime& runtime, const jsi::Object& object, const char* propertyName,
58
+ ComputedReadonlyPropertyDescriptor&& descriptor) {
59
+ const jsi::Function& definePropertyFn = getGlobalFunction(runtime, "Object.defineProperty", [](jsi::Runtime& runtime) {
60
+ return runtime.global().getPropertyAsObject(runtime, "Object").getPropertyAsFunction(runtime, "defineProperty");
61
+ });
62
+
63
+ jsi::String nameJs = jsi::String::createFromAscii(runtime, propertyName);
64
+
65
+ jsi::Object descriptorJs(runtime);
66
+ descriptorJs.setProperty(runtime, PropNameIDCache::get(runtime, "configurable"), jsi::Value(descriptor.configurable));
67
+ descriptorJs.setProperty(runtime, PropNameIDCache::get(runtime, "enumerable"), jsi::Value(descriptor.enumerable));
68
+ descriptorJs.setProperty(runtime, PropNameIDCache::get(runtime, "get"), std::move(descriptor.get));
69
+
70
+ definePropertyFn.call(runtime, object, std::move(nameJs), std::move(descriptorJs));
71
+ }
72
+
73
+ void CommonGlobals::Object::defineProperty(jsi::Runtime& runtime, const jsi::Object& object, const char* propertyName,
74
+ ComputedPropertyDescriptor&& descriptor) {
75
+ const jsi::Function& definePropertyFn = getGlobalFunction(runtime, "Object.defineProperty", [](jsi::Runtime& runtime) {
76
+ return runtime.global().getPropertyAsObject(runtime, "Object").getPropertyAsFunction(runtime, "defineProperty");
77
+ });
78
+
79
+ jsi::String nameJs = jsi::String::createFromAscii(runtime, propertyName);
80
+
81
+ jsi::Object descriptorJs(runtime);
82
+ descriptorJs.setProperty(runtime, PropNameIDCache::get(runtime, "configurable"), jsi::Value(descriptor.configurable));
83
+ descriptorJs.setProperty(runtime, PropNameIDCache::get(runtime, "enumerable"), jsi::Value(descriptor.enumerable));
84
+ descriptorJs.setProperty(runtime, PropNameIDCache::get(runtime, "get"), std::move(descriptor.get));
85
+ descriptorJs.setProperty(runtime, PropNameIDCache::get(runtime, "set"), std::move(descriptor.set));
86
+
87
+ definePropertyFn.call(runtime, object, std::move(nameJs), std::move(descriptorJs));
88
+ }
89
+
90
+ void CommonGlobals::Object::freeze(jsi::Runtime& runtime, const jsi::Object& object) {
91
+ const jsi::Function& freezeFn = getGlobalFunction(runtime, "Object.freeze", [](jsi::Runtime& runtime) {
92
+ return runtime.global().getPropertyAsObject(runtime, "Object").getPropertyAsFunction(runtime, "freeze");
93
+ });
94
+
95
+ freezeFn.call(runtime, object);
96
+ }
97
+
98
+ // pragma MARK: Promise
99
+
100
+ jsi::Value CommonGlobals::Promise::resolved(jsi::Runtime& runtime) {
101
+ const jsi::Function& resolvedFunc = getGlobalFunction(runtime, "Promise.resolve", [](jsi::Runtime& runtime) {
102
+ return runtime.global().getPropertyAsObject(runtime, "Promise").getPropertyAsFunction(runtime, "resolve");
103
+ });
104
+ return resolvedFunc.call(runtime);
105
+ }
106
+ jsi::Value CommonGlobals::Promise::resolved(jsi::Runtime& runtime, jsi::Value&& value) {
107
+ const jsi::Function& resolvedFunc = getGlobalFunction(runtime, "Promise.resolve", [](jsi::Runtime& runtime) {
108
+ return runtime.global().getPropertyAsObject(runtime, "Promise").getPropertyAsFunction(runtime, "resolve");
109
+ });
110
+ return resolvedFunc.call(runtime, {std::move(value)});
111
+ }
112
+ jsi::Value CommonGlobals::Promise::rejected(jsi::Runtime& runtime, jsi::Value&& error) {
113
+ const jsi::Function& rejectedFunc = getGlobalFunction(runtime, "Promise.reject", [](jsi::Runtime& runtime) {
114
+ return runtime.global().getPropertyAsObject(runtime, "Promise").getPropertyAsFunction(runtime, "reject");
115
+ });
116
+ return rejectedFunc.call(runtime, {std::move(error)});
117
+ }
118
+
119
+ jsi::Value CommonGlobals::Promise::callConstructor(jsi::Runtime& runtime, jsi::HostFunctionType&& executor) {
120
+ const jsi::Function& promiseCtor = getGlobalFunction(
121
+ runtime, "Promise", [](jsi::Runtime& runtime) { return runtime.global().getPropertyAsFunction(runtime, "Promise"); });
122
+ jsi::Function executorFunc =
123
+ jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forAscii(runtime, "executor"), 2, std::move(executor));
124
+ return promiseCtor.callAsConstructor(runtime, std::move(executorFunc));
125
+ }
126
+ bool CommonGlobals::Promise::isInstanceOf(jsi::Runtime& runtime, const jsi::Object& object) {
127
+ const jsi::Function& promiseCtor = getGlobalFunction(
128
+ runtime, "Promise", [](jsi::Runtime& runtime) { return runtime.global().getPropertyAsFunction(runtime, "Promise"); });
129
+ return object.instanceOf(runtime, promiseCtor);
130
+ }
131
+
132
+ // pragma MARK: Date
133
+
134
+ jsi::Value CommonGlobals::Date::callConstructor(jsi::Runtime& runtime, double msSinceEpoch) {
135
+ const jsi::Function& dateCtor =
136
+ getGlobalFunction(runtime, "Date", [](jsi::Runtime& runtime) { return runtime.global().getPropertyAsFunction(runtime, "Date"); });
137
+ return dateCtor.callAsConstructor(runtime, {jsi::Value(msSinceEpoch)});
138
+ }
139
+ bool CommonGlobals::Date::isInstanceOf(jsi::Runtime& runtime, const jsi::Object& object) {
140
+ const jsi::Function& dateCtor =
141
+ getGlobalFunction(runtime, "Date", [](jsi::Runtime& runtime) { return runtime.global().getPropertyAsFunction(runtime, "Date"); });
142
+ return object.instanceOf(runtime, dateCtor);
143
+ }
144
+
145
+ // pragma MARK: Error
146
+
147
+ bool CommonGlobals::Error::isInstanceOf(jsi::Runtime& runtime, const jsi::Object& object) {
148
+ const jsi::Function& errorCtor =
149
+ getGlobalFunction(runtime, "Error", [](jsi::Runtime& runtime) { return runtime.global().getPropertyAsFunction(runtime, "Error"); });
150
+ return object.instanceOf(runtime, errorCtor);
151
+ }
152
+
153
+ // pragma MARK: CommonGlobals
154
+
155
+ void CommonGlobals::defineGlobal(jsi::Runtime& runtime, KnownGlobalPropertyName name, jsi::Value&& value) {
156
+ const char* nameString = getKnownGlobalPropertyNameString(name);
157
+
158
+ #ifdef NITRO_DEBUG
159
+ // In debug, let's perform additional safety checks.
160
+ if (runtime.global().hasProperty(runtime, nameString)) [[unlikely]] {
161
+ throw std::runtime_error("Failed to set `global." + std::string(nameString) + "` - it already exists for Runtime \"" +
162
+ getRuntimeId(runtime) + "\"! Did you call `defineGlobal(\"" + std::string(nameString) +
163
+ "\")` twice? Did you link Nitro Modules twice?");
164
+ }
165
+ Object::defineProperty(runtime, runtime.global(), nameString,
166
+ PlainPropertyDescriptor{.configurable = false, .enumerable = true, .value = std::move(value), .writable = false});
167
+ #else
168
+ // In release, just set the property.
169
+ runtime.global().setProperty(runtime, nameString, std::move(value));
170
+ #endif
171
+ }
172
+
173
+ const char* CommonGlobals::getKnownGlobalPropertyNameString(KnownGlobalPropertyName name) {
174
+ switch (name) {
175
+ case KnownGlobalPropertyName::DISPATCHER:
176
+ return "__nitroDispatcher";
177
+ case KnownGlobalPropertyName::JSI_CACHE:
178
+ return "__nitroJsiCache";
179
+ case KnownGlobalPropertyName::NITRO_MODULES_PROXY:
180
+ return "NitroModulesProxy";
181
+ }
182
+ }
183
+
184
+ const jsi::PropNameID& CommonGlobals::getKnownGlobalPropertyName(jsi::Runtime& runtime, KnownGlobalPropertyName name) {
185
+ return PropNameIDCache::get(runtime, getKnownGlobalPropertyNameString(name));
186
+ }
187
+
188
+ const jsi::Function& CommonGlobals::getGlobalFunction(jsi::Runtime& runtime, const char* key,
189
+ std::function<jsi::Function(jsi::Runtime&)> getFunction) {
190
+ // Let's try to find the function in cache
191
+ FunctionCache& functionCache = _cache[&runtime];
192
+ std::string stringKey = key;
193
+ auto iterator = functionCache.find(stringKey);
194
+ if (iterator != functionCache.end()) {
195
+ // We found it! Let's check if the reference is still valid...
196
+ BorrowingReference<jsi::Function> function = iterator->second;
197
+ if (function != nullptr) [[likely]] {
198
+ // It's still alive - let's use it from cache!
199
+ return *function;
200
+ }
201
+ }
202
+
203
+ // We haven't found the function with the given key in cache - so let's get it:
204
+ jsi::Function function = getFunction(runtime);
205
+
206
+ // Let's throw it in cache!
207
+ JSICacheReference jsiCache = JSICache::getOrCreateCache(runtime);
208
+ BorrowingReference<jsi::Function> sharedFunction = jsiCache.makeShared(std::move(function));
209
+ functionCache[stringKey] = sharedFunction;
210
+
211
+ // And now return:
212
+ return *sharedFunction;
213
+ }
214
+
215
+ } // namespace margelo::nitro
@@ -0,0 +1,158 @@
1
+ //
2
+ // CommonGlobals.hpp
3
+ // react-native-nitro
4
+ //
5
+ // Created by Marc Rousavy on 17.10.25.
6
+ //
7
+
8
+ #pragma once
9
+
10
+ #include "BorrowingReference.hpp"
11
+ #include <jsi/jsi.h>
12
+ #include <unordered_map>
13
+
14
+ namespace margelo::nitro {
15
+
16
+ using namespace facebook;
17
+
18
+ struct PlainPropertyDescriptor {
19
+ bool configurable;
20
+ bool enumerable;
21
+ jsi::Value value;
22
+ bool writable;
23
+ };
24
+ struct ComputedReadonlyPropertyDescriptor {
25
+ bool configurable;
26
+ bool enumerable;
27
+ jsi::Function get;
28
+ };
29
+ struct ComputedPropertyDescriptor {
30
+ bool configurable;
31
+ bool enumerable;
32
+ jsi::Function get;
33
+ jsi::Function set;
34
+ };
35
+
36
+ enum class KnownGlobalPropertyName { DISPATCHER, JSI_CACHE, NITRO_MODULES_PROXY };
37
+
38
+ class CommonGlobals final {
39
+ public:
40
+ CommonGlobals() = delete;
41
+ ~CommonGlobals() = delete;
42
+
43
+ public:
44
+ /**
45
+ * Define a global value for the given Runtime.
46
+ * In debug, this performs additional safety checks such as freezing the property.
47
+ */
48
+ static void defineGlobal(jsi::Runtime& runtime, KnownGlobalPropertyName name, jsi::Value&& value);
49
+ /**
50
+ * Get a string name for a known global property name.
51
+ */
52
+ static const char* getKnownGlobalPropertyNameString(KnownGlobalPropertyName name);
53
+ /**
54
+ * Get a `jsi::PropNameID` for a known global property name.
55
+ */
56
+ static const jsi::PropNameID& getKnownGlobalPropertyName(jsi::Runtime& runtime, KnownGlobalPropertyName name);
57
+
58
+ /**
59
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
60
+ */
61
+ class Object final {
62
+ public:
63
+ Object() = delete;
64
+ ~Object() = delete;
65
+
66
+ /**
67
+ * Create a new `jsi::Object` with the given `prototype`.
68
+ * Uses a native implementation if possible.
69
+ */
70
+ static jsi::Object create(jsi::Runtime& runtime, const jsi::Value& prototype);
71
+
72
+ /**
73
+ * Define a plain property on the given `object` with the given `propertyName`.
74
+ * The `descriptor` defines the attributes of this property.
75
+ */
76
+ static void defineProperty(jsi::Runtime& runtime, const jsi::Object& object, const char* propertyName,
77
+ PlainPropertyDescriptor&& descriptor);
78
+ /**
79
+ * Define a plain property on the given `object` with the given `propertyName`.
80
+ * The `descriptor` defines the attributes of this property.
81
+ */
82
+ static void defineProperty(jsi::Runtime& runtime, const jsi::Object& object, const char* propertyName,
83
+ ComputedReadonlyPropertyDescriptor&& descriptor);
84
+ /**
85
+ * Define a plain property on the given `object` with the given `propertyName`.
86
+ * The `descriptor` defines the attributes of this property.
87
+ */
88
+ static void defineProperty(jsi::Runtime& runtime, const jsi::Object& object, const char* propertyName,
89
+ ComputedPropertyDescriptor&& descriptor);
90
+
91
+ /**
92
+ * Freezes all values of the given `object`.
93
+ */
94
+ static void freeze(jsi::Runtime& runtime, const jsi::Object& object);
95
+ };
96
+
97
+ /**
98
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
99
+ */
100
+ class Promise final {
101
+ public:
102
+ Promise() = delete;
103
+ ~Promise() = delete;
104
+
105
+ static jsi::Value resolved(jsi::Runtime& runtime);
106
+ static jsi::Value resolved(jsi::Runtime& runtime, jsi::Value&& value);
107
+ static jsi::Value rejected(jsi::Runtime& runtime, jsi::Value&& error);
108
+
109
+ static jsi::Value callConstructor(jsi::Runtime& runtime, jsi::HostFunctionType&& executor);
110
+ static bool isInstanceOf(jsi::Runtime& runtime, const jsi::Object& object);
111
+ };
112
+
113
+ /**
114
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
115
+ */
116
+ class Date final {
117
+ public:
118
+ Date() = delete;
119
+ ~Date() = delete;
120
+
121
+ static jsi::Value callConstructor(jsi::Runtime& runtime, double msSinceEpoch);
122
+ static bool isInstanceOf(jsi::Runtime& runtime, const jsi::Object& object);
123
+ };
124
+
125
+ /**
126
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
127
+ */
128
+ class Error final {
129
+ public:
130
+ Error() = delete;
131
+ ~Error() = delete;
132
+
133
+ static bool isInstanceOf(jsi::Runtime& runtime, const jsi::Object& object);
134
+ };
135
+
136
+ private:
137
+ friend Object;
138
+ friend Promise;
139
+ friend Date;
140
+ friend Error;
141
+
142
+ private:
143
+ /**
144
+ * Get a global Function, and optionally cache it in the Runtime via the `key`.
145
+ *
146
+ * The returned const-ref to a `jsi::Function` should only be used within the callee's
147
+ * synchronous scope.
148
+ * It may no longer be active after the scope ends (function return).
149
+ */
150
+ static const jsi::Function& getGlobalFunction(jsi::Runtime& runtime, const char* key,
151
+ std::function<jsi::Function(jsi::Runtime&)> getFunction);
152
+
153
+ private:
154
+ using FunctionCache = std::unordered_map<std::string, BorrowingReference<jsi::Function>>;
155
+ static std::unordered_map<jsi::Runtime*, FunctionCache> _cache;
156
+ };
157
+
158
+ } // namespace margelo::nitro
@@ -35,7 +35,7 @@ public:
35
35
  public:
36
36
  /**
37
37
  * Calls this `SyncJSCallback` synchronously, and
38
- * returns it's result (`R`).
38
+ * returns its result (`R`).
39
39
  * The callee is responsible for ensuring that the
40
40
  * underlying `jsi::Function` can actually be called from this Thread.
41
41
  * In Debug, sanity checks are made to ensure the `jsi::Function` is still alive.
@@ -9,7 +9,7 @@
9
9
  #define NitroDefines_h
10
10
 
11
11
  // Sets the version of the native Nitro core library
12
- #define NITRO_VERSION "0.31.10"
12
+ #define NITRO_VERSION "0.32.0"
13
13
 
14
14
  // Sets whether to use debug or optimized production build flags
15
15
  #ifdef DEBUG
@@ -0,0 +1,38 @@
1
+ //
2
+ // PropNameIDCache.cpp
3
+ // react-native-nitro
4
+ //
5
+ // Created by Marc Rousavy on 17.10.25.
6
+ //
7
+
8
+ #include "PropNameIDCache.hpp"
9
+ #include "JSICache.hpp"
10
+
11
+ namespace margelo::nitro {
12
+
13
+ using namespace facebook;
14
+
15
+ std::unordered_map<jsi::Runtime*, PropNameIDCache::CacheMap> PropNameIDCache::_cache;
16
+
17
+ const jsi::PropNameID& PropNameIDCache::get(jsi::Runtime& runtime, std::string value) {
18
+ CacheMap& cache = _cache[&runtime];
19
+ const auto& cachedName = cache.find(value);
20
+ if (cachedName != cache.end()) {
21
+ // cache warm!
22
+ const BorrowingReference<jsi::PropNameID>& value = cachedName->second;
23
+ return *value;
24
+ }
25
+
26
+ // not cached - create the jsi::PropNameID...
27
+ auto propName = jsi::PropNameID::forAscii(runtime, value);
28
+ auto jsiCache = JSICache::getOrCreateCache(runtime);
29
+ auto sharedPropName = jsiCache.makeShared(std::move(propName));
30
+
31
+ // store it in cache...
32
+ cache.emplace(value, sharedPropName);
33
+
34
+ // return it!
35
+ return *sharedPropName;
36
+ }
37
+
38
+ } // namespace margelo::nitro
@@ -0,0 +1,44 @@
1
+ //
2
+ // PropNameIDCache.hpp
3
+ // react-native-nitro
4
+ //
5
+ // Created by Marc Rousavy on 17.10.25.
6
+ //
7
+
8
+ #pragma once
9
+
10
+ #include "BorrowingReference.hpp"
11
+ #include <jsi/jsi.h>
12
+ #include <unordered_map>
13
+
14
+ namespace margelo::nitro {
15
+
16
+ using namespace facebook;
17
+
18
+ /**
19
+ * Allows caching `jsi::PropNameID`s via `std::string`s.
20
+ * The returned `jsi::PropNameID` can be used for JSI operations like
21
+ * - `jsi::Object::getProperty(...)`
22
+ * - `jsi::Object::setProperty(...)`
23
+ * - `jsi::Object::hasProperty(...)`
24
+ * And is more efficient than the string equivalent overloads of those
25
+ * functions due to caching.
26
+ */
27
+ class PropNameIDCache final {
28
+ public:
29
+ PropNameIDCache() = delete;
30
+ ~PropNameIDCache() = delete;
31
+
32
+ /**
33
+ * Get a `jsi::PropNameID` for the given `std::string` value.
34
+ * The `jsi::PropNameID` is only valid within the callee's current
35
+ * synchronous scope, and must be non-escaping.
36
+ */
37
+ static const jsi::PropNameID& get(jsi::Runtime& runtime, std::string value);
38
+
39
+ private:
40
+ using CacheMap = std::unordered_map<std::string, BorrowingReference<jsi::PropNameID>>;
41
+ static std::unordered_map<jsi::Runtime*, CacheMap> _cache;
42
+ };
43
+
44
+ } // namespace margelo::nitro
@@ -1,5 +1,5 @@
1
1
  //
2
- // WeakReference+Owning.hpp
2
+ // WeakReference+Borrowing.hpp
3
3
  // react-native-nitro
4
4
  //
5
5
  // Created by Marc Rousavy on 23.06.24.
@@ -72,7 +72,7 @@ public:
72
72
  }
73
73
 
74
74
  /**
75
- Try to lock the borrowing reference to an owning reference, or `nullptr` if it has already been deleted.
75
+ * Try to lock the weak reference to a borrowing reference, or `nullptr` if it has already been deleted.
76
76
  */
77
77
  [[nodiscard]]
78
78
  BorrowingReference<T> lock() const;
@@ -30,7 +30,7 @@ public protocol HybridObject: AnyObject {
30
30
  * Eagerly- (and manually-) dispose all native resources this `HybridObject` holds.
31
31
  * This method can only be manually called from JS using `dispose()`.
32
32
  *
33
- * If this method is never manually called, a `HybridObject` is expected to disposes it's
33
+ * If this method is never manually called, a `HybridObject` is expected to disposes its
34
34
  * resources as usual via the object's destructor (`~HybridObject()`, `deinit` or `finalize()`).
35
35
  *
36
36
  * By default, this method does nothing. It can be overridden to perform actual disposing/cleanup
@@ -0,0 +1,37 @@
1
+ //
2
+ // NitroLogger.cpp
3
+ // react-native-nitro
4
+ //
5
+ // Created by Marc Rousavy on 14.07.24.
6
+ //
7
+
8
+ #include "NitroLogger.hpp"
9
+ #include "NitroDefines.hpp"
10
+ #include <os/log.h>
11
+
12
+ namespace margelo::nitro {
13
+
14
+ void Logger::nativeLog([[maybe_unused]] LogLevel level, //
15
+ [[maybe_unused]] const char* NON_NULL tag, //
16
+ [[maybe_unused]] const std::string& message) {
17
+ #ifdef NITRO_DEBUG
18
+ static os_log_t logger = os_log_create("com.margelo.nitro", "nitro");
19
+
20
+ switch (level) {
21
+ case LogLevel::Debug:
22
+ os_log_debug(logger, "[%s] %s", tag, message.c_str());
23
+ break;
24
+ case LogLevel::Info:
25
+ os_log_info(logger, "[%s] %s", tag, message.c_str());
26
+ break;
27
+ case LogLevel::Warning:
28
+ os_log_error(logger, "[%s] %s", tag, message.c_str());
29
+ break;
30
+ case LogLevel::Error:
31
+ os_log_error(logger, "[%s] %s", tag, message.c_str());
32
+ break;
33
+ }
34
+ #endif
35
+ }
36
+
37
+ } // namespace margelo::nitro
@@ -0,0 +1,43 @@
1
+ //
2
+ // ThreadUtils.cpp
3
+ // react-native-nitro
4
+ //
5
+ // Created by Marc Rousavy on 14.07.24.
6
+ //
7
+
8
+ #include "ThreadUtils.hpp"
9
+ #include <dispatch/dispatch.h>
10
+ #include <pthread.h>
11
+ #include <sstream>
12
+ #include <thread>
13
+
14
+ namespace margelo::nitro {
15
+
16
+ std::string ThreadUtils::getThreadName() {
17
+ // Try using pthread APIs
18
+ char threadName[64] = {};
19
+ int pthreadResult = pthread_getname_np(pthread_self(), threadName, sizeof(threadName));
20
+ if (pthreadResult == 0 && threadName[0] != '\0') {
21
+ // We have a pthread name
22
+ return std::string(threadName);
23
+ }
24
+
25
+ // Try getting DispatchQueue name
26
+ const char* queueName = dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL);
27
+ if (queueName != nullptr && queueName[0] != '\0') {
28
+ // We are on a DispatchQueue with a name
29
+ return std::string(queueName);
30
+ }
31
+
32
+ // Fall back to std::this_thread
33
+ std::stringstream stream;
34
+ stream << std::this_thread::get_id();
35
+ std::string threadId = stream.str();
36
+ return std::string("Thread #") + threadId;
37
+ }
38
+
39
+ void ThreadUtils::setThreadName(const std::string& name) {
40
+ pthread_setname_np(name.c_str());
41
+ }
42
+
43
+ } // namespace margelo::nitro
@@ -31,7 +31,7 @@ extension SwiftClosure {
31
31
  * This can then be called from both C++ and Swift.
32
32
  */
33
33
  public init(wrappingClosure closure: @escaping () -> Void) {
34
- // Wrap closure in void*, and increment it's ref count so it stays alive.
34
+ // Wrap closure in void*, and increment its ref count so it stays alive.
35
35
  let context = Unmanaged.passRetained(ClosureWrapper(closure: closure)).toOpaque()
36
36
 
37
37
  // Create a C-style Function Pointer, which calls the actual Swift closure.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-modules",
3
- "version": "0.31.10",
3
+ "version": "0.32.0",
4
4
  "description": "Insanely fast native C++, Swift or Kotlin modules with a statically compiled binding layer to JSI.",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -59,7 +59,6 @@
59
59
  "registry": "https://registry.npmjs.org/"
60
60
  },
61
61
  "scripts": {
62
- "postinstall": "bun build || exit 0;",
63
62
  "write-native-version": "version=$(node -p \"require('./package.json').version\") && sed -i '' \"s/#define NITRO_VERSION \\\".*\\\"/#define NITRO_VERSION \\\"$version\\\"/\" ./cpp/utils/NitroDefines.hpp",
64
63
  "postversion": "bun run write-native-version",
65
64
  "build": "rm -rf lib && bun typecheck && bob build",