react-native-nitro-modules 0.31.9 → 0.32.0-beta.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.
- package/NitroModules.podspec +1 -0
- package/android/build.gradle +1 -1
- package/android/src/main/cpp/core/JAnyMap.cpp +120 -0
- package/android/src/main/cpp/core/JAnyMap.hpp +20 -56
- package/android/src/main/cpp/platform/NitroLogger.cpp +3 -1
- package/android/src/main/java/com/margelo/nitro/core/AnyMap.kt +16 -7
- package/cpp/core/AnyMap.hpp +2 -2
- package/cpp/core/HybridObject.cpp +10 -10
- package/cpp/entrypoint/InstallNitro.cpp +2 -2
- package/cpp/jsi/JSICache.cpp +10 -5
- package/cpp/jsi/JSICache.hpp +6 -0
- package/cpp/jsi/JSIConverter+AnyMap.hpp +4 -3
- package/cpp/jsi/JSIConverter+Date.hpp +8 -10
- package/cpp/jsi/JSIConverter+Exception.hpp +5 -5
- package/cpp/jsi/JSIConverter+Function.hpp +4 -1
- package/cpp/jsi/JSIConverter+Promise.hpp +8 -14
- package/cpp/jsi/JSIConverter+UnorderedMap.hpp +2 -1
- package/cpp/jsi/JSIHelpers.hpp +1 -1
- package/cpp/platform/NitroLogger.hpp +3 -1
- package/cpp/prototype/HybridObjectPrototype.cpp +28 -28
- package/cpp/threading/Dispatcher.cpp +5 -5
- package/cpp/utils/BorrowingReference.hpp +6 -6
- package/cpp/utils/CommonGlobals.cpp +215 -0
- package/cpp/utils/CommonGlobals.hpp +158 -0
- package/cpp/utils/NitroDefines.hpp +1 -1
- package/cpp/utils/PropNameIDCache.cpp +38 -0
- package/cpp/utils/PropNameIDCache.hpp +44 -0
- package/cpp/utils/{WeakReference+Owning.hpp → WeakReference+Borrowing.hpp} +1 -1
- package/cpp/utils/WeakReference.hpp +1 -1
- package/ios/platform/NitroLogger.cpp +37 -0
- package/ios/platform/ThreadUtils.cpp +43 -0
- package/package.json +1 -2
- package/cpp/utils/ObjectUtils.cpp +0 -172
- package/cpp/utils/ObjectUtils.hpp +0 -94
- package/ios/platform/NitroLogger.mm +0 -36
- package/ios/platform/ThreadUtils.mm +0 -46
package/NitroModules.podspec
CHANGED
|
@@ -48,6 +48,7 @@ Pod::Spec.new do |s|
|
|
|
48
48
|
"cpp/utils/FastVectorCopy.hpp",
|
|
49
49
|
"cpp/utils/NitroHash.hpp",
|
|
50
50
|
"cpp/utils/NitroDefines.hpp",
|
|
51
|
+
"cpp/utils/PropNameIDCache.hpp",
|
|
51
52
|
"cpp/views/CachedProp.hpp",
|
|
52
53
|
# Public iOS-specific headers that will be exposed in modulemap (for Swift)
|
|
53
54
|
"ios/core/ArrayBufferHolder.hpp",
|
package/android/build.gradle
CHANGED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
//
|
|
2
|
+
// JAnyMap.cpp
|
|
3
|
+
// react-native-nitro
|
|
4
|
+
//
|
|
5
|
+
// Created by Marc Rousavy on 14.07.24.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include "JAnyMap.hpp"
|
|
11
|
+
|
|
12
|
+
namespace margelo::nitro {
|
|
13
|
+
|
|
14
|
+
using namespace facebook;
|
|
15
|
+
|
|
16
|
+
jni::local_ref<jni::JArrayClass<jni::JString>> JAnyMap::getAllKeys() {
|
|
17
|
+
auto& map = _map->getMap();
|
|
18
|
+
auto array = jni::JArrayClass<jni::JString>::newArray(map.size());
|
|
19
|
+
size_t index = 0;
|
|
20
|
+
for (const auto& pair : map) {
|
|
21
|
+
auto jKey = jni::make_jstring(pair.first);
|
|
22
|
+
array->setElement(index, *jKey);
|
|
23
|
+
index++;
|
|
24
|
+
}
|
|
25
|
+
return array;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
jni::local_ref<JAnyArray> JAnyMap::getAnyArray(const std::string& key) {
|
|
29
|
+
const auto& vector = _map->getArray(key);
|
|
30
|
+
auto javaArray = jni::JArrayClass<JAnyValue::javaobject>::newArray(vector.size());
|
|
31
|
+
for (size_t i = 0; i < vector.size(); i++) {
|
|
32
|
+
auto value = JAnyValue::create(vector[i]);
|
|
33
|
+
javaArray->setElement(i, value.get());
|
|
34
|
+
}
|
|
35
|
+
return javaArray;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
jni::local_ref<JAnyObject> JAnyMap::getAnyObject(const std::string& key) {
|
|
39
|
+
const auto& map = _map->getObject(key);
|
|
40
|
+
auto javaMap = jni::JHashMap<jni::JString, JAnyValue::javaobject>::create(map.size());
|
|
41
|
+
for (const auto& entry : map) {
|
|
42
|
+
auto string = jni::make_jstring(entry.first);
|
|
43
|
+
auto value = JAnyValue::create(entry.second);
|
|
44
|
+
javaMap->put(string, value);
|
|
45
|
+
}
|
|
46
|
+
return javaMap;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
jni::local_ref<JAnyValue::javaobject> JAnyMap::getAnyValue(const std::string& key) {
|
|
50
|
+
const auto& any = _map->getAny(key);
|
|
51
|
+
return JAnyValue::create(any);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
void JAnyMap::setAnyArray(const std::string& key, jni::alias_ref<JAnyArray> value) {
|
|
55
|
+
std::vector<AnyValue> vector;
|
|
56
|
+
size_t size = value->size();
|
|
57
|
+
vector.reserve(size);
|
|
58
|
+
for (size_t i = 0; i < size; i++) {
|
|
59
|
+
auto anyValue = value->getElement(i);
|
|
60
|
+
vector.push_back(anyValue->cthis()->getValue());
|
|
61
|
+
}
|
|
62
|
+
_map->setArray(key, vector);
|
|
63
|
+
}
|
|
64
|
+
void JAnyMap::setAnyObject(const std::string& key, const jni::alias_ref<JAnyObject>& value) {
|
|
65
|
+
std::unordered_map<std::string, AnyValue> map;
|
|
66
|
+
map.reserve(value->size());
|
|
67
|
+
for (const auto& entry : *value) {
|
|
68
|
+
map.emplace(entry.first->toStdString(), entry.second->cthis()->getValue());
|
|
69
|
+
}
|
|
70
|
+
_map->setObject(key, map);
|
|
71
|
+
}
|
|
72
|
+
void JAnyMap::setAnyValue(const std::string& key, const jni::alias_ref<JAnyValue::javaobject>& value) {
|
|
73
|
+
_map->setAny(key, value->cthis()->getValue());
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
jni::local_ref<jni::JHashMap<jni::JString, jni::JObject>> JAnyMap::toHashMap() {
|
|
77
|
+
const auto& map = _map->getMap();
|
|
78
|
+
auto javaMap = jni::JHashMap<jni::JString, jni::JObject>::create(map.size());
|
|
79
|
+
for (const auto& [key, value] : map) {
|
|
80
|
+
javaMap->put(jni::make_jstring(key), anyValueToJObject(value));
|
|
81
|
+
}
|
|
82
|
+
return javaMap;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
jni::local_ref<jni::JObject> JAnyMap::anyValueToJObject(const AnyValue& value) {
|
|
86
|
+
if (std::holds_alternative<NullType>(value)) {
|
|
87
|
+
return nullptr;
|
|
88
|
+
} else if (std::holds_alternative<double>(value)) {
|
|
89
|
+
return jni::JDouble::valueOf(std::get<double>(value));
|
|
90
|
+
} else if (std::holds_alternative<bool>(value)) {
|
|
91
|
+
return jni::JBoolean::valueOf(std::get<bool>(value));
|
|
92
|
+
} else if (std::holds_alternative<int64_t>(value)) {
|
|
93
|
+
return jni::JLong::valueOf(std::get<int64_t>(value));
|
|
94
|
+
} else if (std::holds_alternative<std::string>(value)) {
|
|
95
|
+
return jni::make_jstring(std::get<std::string>(value));
|
|
96
|
+
} else if (std::holds_alternative<AnyArray>(value)) {
|
|
97
|
+
return jni::static_ref_cast<jni::JObject>(anyArrayToJList(std::get<AnyArray>(value)));
|
|
98
|
+
} else if (std::holds_alternative<AnyObject>(value)) {
|
|
99
|
+
return jni::static_ref_cast<jni::JObject>(anyObjectToJHashMap(std::get<AnyObject>(value)));
|
|
100
|
+
}
|
|
101
|
+
return nullptr;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
jni::local_ref<jni::JArrayList<jni::JObject>> JAnyMap::anyArrayToJList(const AnyArray& array) {
|
|
105
|
+
auto jList = jni::JArrayList<jni::JObject>::create(static_cast<int>(array.size()));
|
|
106
|
+
for (const auto& item : array) {
|
|
107
|
+
jList->add(anyValueToJObject(item));
|
|
108
|
+
}
|
|
109
|
+
return jList;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
jni::local_ref<jni::JHashMap<jni::JString, jni::JObject>> JAnyMap::anyObjectToJHashMap(const AnyObject& object) {
|
|
113
|
+
auto jMap = jni::JHashMap<jni::JString, jni::JObject>::create(object.size());
|
|
114
|
+
for (const auto& [key, val] : object) {
|
|
115
|
+
jMap->put(jni::make_jstring(key), anyValueToJObject(val));
|
|
116
|
+
}
|
|
117
|
+
return jMap;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
} // namespace margelo::nitro
|
|
@@ -61,17 +61,7 @@ protected:
|
|
|
61
61
|
void clear() {
|
|
62
62
|
_map->clear();
|
|
63
63
|
}
|
|
64
|
-
jni::local_ref<jni::JArrayClass<jni::JString>> getAllKeys()
|
|
65
|
-
auto& map = _map->getMap();
|
|
66
|
-
auto array = jni::JArrayClass<jni::JString>::newArray(map.size());
|
|
67
|
-
size_t index = 0;
|
|
68
|
-
for (const auto& pair : map) {
|
|
69
|
-
auto jKey = jni::make_jstring(pair.first);
|
|
70
|
-
array->setElement(index, *jKey);
|
|
71
|
-
index++;
|
|
72
|
-
}
|
|
73
|
-
return array;
|
|
74
|
-
}
|
|
64
|
+
jni::local_ref<jni::JArrayClass<jni::JString>> getAllKeys();
|
|
75
65
|
|
|
76
66
|
protected:
|
|
77
67
|
bool isNull(const std::string& key) {
|
|
@@ -109,29 +99,9 @@ protected:
|
|
|
109
99
|
std::string getString(const std::string& key) {
|
|
110
100
|
return _map->getString(key);
|
|
111
101
|
}
|
|
112
|
-
jni::local_ref<JAnyArray> getAnyArray(const std::string& key)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
for (size_t i = 0; i < vector.size(); i++) {
|
|
116
|
-
auto value = JAnyValue::create(vector[i]);
|
|
117
|
-
javaArray->setElement(i, value.get());
|
|
118
|
-
}
|
|
119
|
-
return javaArray;
|
|
120
|
-
}
|
|
121
|
-
jni::local_ref<JAnyObject> getAnyObject(const std::string& key) {
|
|
122
|
-
const auto& map = _map->getObject(key);
|
|
123
|
-
auto javaMap = jni::JHashMap<jni::JString, JAnyValue::javaobject>::create(map.size());
|
|
124
|
-
for (const auto& entry : map) {
|
|
125
|
-
auto string = jni::make_jstring(entry.first);
|
|
126
|
-
auto value = JAnyValue::create(entry.second);
|
|
127
|
-
javaMap->put(string, value);
|
|
128
|
-
}
|
|
129
|
-
return javaMap;
|
|
130
|
-
}
|
|
131
|
-
jni::local_ref<JAnyValue::javaobject> getAnyValue(const std::string& key) {
|
|
132
|
-
const auto& any = _map->getAny(key);
|
|
133
|
-
return JAnyValue::create(any);
|
|
134
|
-
}
|
|
102
|
+
jni::local_ref<JAnyArray> getAnyArray(const std::string& key);
|
|
103
|
+
jni::local_ref<JAnyObject> getAnyObject(const std::string& key);
|
|
104
|
+
jni::local_ref<JAnyValue::javaobject> getAnyValue(const std::string& key);
|
|
135
105
|
|
|
136
106
|
protected:
|
|
137
107
|
void setNull(const std::string& key) {
|
|
@@ -149,33 +119,25 @@ protected:
|
|
|
149
119
|
void setString(const std::string& key, const std::string& value) {
|
|
150
120
|
_map->setString(key, value);
|
|
151
121
|
}
|
|
152
|
-
void setAnyArray(const std::string& key, jni::alias_ref<JAnyArray> value)
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
vector.reserve(size);
|
|
156
|
-
for (size_t i = 0; i < size; i++) {
|
|
157
|
-
auto anyValue = value->getElement(i);
|
|
158
|
-
vector.push_back(anyValue->cthis()->getValue());
|
|
159
|
-
}
|
|
160
|
-
_map->setArray(key, vector);
|
|
161
|
-
}
|
|
162
|
-
void setAnyObject(const std::string& key, const jni::alias_ref<JAnyObject>& value) {
|
|
163
|
-
std::unordered_map<std::string, AnyValue> map;
|
|
164
|
-
map.reserve(value->size());
|
|
165
|
-
for (const auto& entry : *value) {
|
|
166
|
-
map.emplace(entry.first->toStdString(), entry.second->cthis()->getValue());
|
|
167
|
-
}
|
|
168
|
-
_map->setObject(key, map);
|
|
169
|
-
}
|
|
170
|
-
void setAnyValue(const std::string& key, const jni::alias_ref<JAnyValue::javaobject>& value) {
|
|
171
|
-
_map->setAny(key, value->cthis()->getValue());
|
|
172
|
-
}
|
|
122
|
+
void setAnyArray(const std::string& key, jni::alias_ref<JAnyArray> value);
|
|
123
|
+
void setAnyObject(const std::string& key, const jni::alias_ref<JAnyObject>& value);
|
|
124
|
+
void setAnyValue(const std::string& key, const jni::alias_ref<JAnyValue::javaobject>& value);
|
|
173
125
|
|
|
174
126
|
protected:
|
|
175
127
|
void merge(jni::alias_ref<JAnyMap::javaobject> other) {
|
|
176
128
|
_map->merge(other->cthis()->_map);
|
|
177
129
|
}
|
|
178
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Bulk-converts the entire `JAnyMap` to a Java `HashMap<String, Object>` in a single JNI call.
|
|
133
|
+
*/
|
|
134
|
+
jni::local_ref<jni::JHashMap<jni::JString, jni::JObject>> toHashMap();
|
|
135
|
+
|
|
136
|
+
private:
|
|
137
|
+
static jni::local_ref<jni::JObject> anyValueToJObject(const AnyValue& value);
|
|
138
|
+
static jni::local_ref<jni::JArrayList<jni::JObject>> anyArrayToJList(const AnyArray& array);
|
|
139
|
+
static jni::local_ref<jni::JHashMap<jni::JString, jni::JObject>> anyObjectToJHashMap(const AnyObject& object);
|
|
140
|
+
|
|
179
141
|
public:
|
|
180
142
|
[[nodiscard]]
|
|
181
143
|
std::shared_ptr<AnyMap> getMap() const {
|
|
@@ -225,8 +187,10 @@ public:
|
|
|
225
187
|
makeNativeMethod("setAnyValue", JAnyMap::setAnyValue),
|
|
226
188
|
// merge
|
|
227
189
|
makeNativeMethod("merge", JAnyMap::merge),
|
|
190
|
+
// bulk conversion
|
|
191
|
+
makeNativeMethod("toHashMap", JAnyMap::toHashMap),
|
|
228
192
|
});
|
|
229
193
|
}
|
|
230
194
|
};
|
|
231
195
|
|
|
232
|
-
} // namespace margelo::nitro
|
|
196
|
+
} // namespace margelo::nitro
|
|
@@ -26,7 +26,9 @@ int levelToAndroidLevel(LogLevel level) {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
void Logger::nativeLog([[maybe_unused]] LogLevel level,
|
|
29
|
+
void Logger::nativeLog([[maybe_unused]] LogLevel level, //
|
|
30
|
+
[[maybe_unused]] const char* tag, //
|
|
31
|
+
[[maybe_unused]] const std::string& message) {
|
|
30
32
|
#ifdef NITRO_DEBUG
|
|
31
33
|
int logLevel = levelToAndroidLevel(level);
|
|
32
34
|
std::string combinedTag = "Nitro." + std::string(tag);
|
|
@@ -39,21 +39,28 @@ class AnyMap {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
companion object {
|
|
42
|
-
fun fromMap(
|
|
42
|
+
fun fromMap(
|
|
43
|
+
map: Map<String, Any?>,
|
|
44
|
+
ignoreIncompatible: Boolean = false,
|
|
45
|
+
): AnyMap {
|
|
43
46
|
val anyMap = AnyMap(map.size)
|
|
44
47
|
for ((key, value) in map) {
|
|
45
|
-
|
|
48
|
+
try {
|
|
49
|
+
anyMap.setAny(key, value)
|
|
50
|
+
} catch (error: Throwable) {
|
|
51
|
+
if (ignoreIncompatible) {
|
|
52
|
+
continue
|
|
53
|
+
} else {
|
|
54
|
+
throw error
|
|
55
|
+
}
|
|
56
|
+
}
|
|
46
57
|
}
|
|
47
58
|
return anyMap
|
|
48
59
|
}
|
|
49
60
|
}
|
|
50
61
|
|
|
51
62
|
fun toMap(): Map<String, Any?> {
|
|
52
|
-
|
|
53
|
-
for (key in getAllKeys()) {
|
|
54
|
-
map.put(key, getAny(key))
|
|
55
|
-
}
|
|
56
|
-
return map
|
|
63
|
+
return toHashMap()
|
|
57
64
|
}
|
|
58
65
|
|
|
59
66
|
fun setAny(
|
|
@@ -67,6 +74,8 @@ class AnyMap {
|
|
|
67
74
|
return getAnyValue(key).toAny()
|
|
68
75
|
}
|
|
69
76
|
|
|
77
|
+
external fun toHashMap(): HashMap<String, Any?>
|
|
78
|
+
|
|
70
79
|
@FastNative
|
|
71
80
|
external fun contains(key: String): Boolean
|
|
72
81
|
|
package/cpp/core/AnyMap.hpp
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
#include "HybridObject.hpp"
|
|
6
|
+
#include "CommonGlobals.hpp"
|
|
6
7
|
#include "JSIConverter.hpp"
|
|
7
8
|
#include "NitroDefines.hpp"
|
|
8
|
-
#include "ObjectUtils.hpp"
|
|
9
9
|
|
|
10
10
|
namespace margelo::nitro {
|
|
11
11
|
|
|
@@ -75,7 +75,7 @@ jsi::Value HybridObject::toObject(jsi::Runtime& runtime) {
|
|
|
75
75
|
jsi::Value prototype = getPrototype(runtime);
|
|
76
76
|
|
|
77
77
|
// 3. Create the object using Object.create(...)
|
|
78
|
-
jsi::Object object =
|
|
78
|
+
jsi::Object object = CommonGlobals::Object::create(runtime, prototype);
|
|
79
79
|
|
|
80
80
|
// 4. Assign NativeState to the object so the prototype can resolve the native methods
|
|
81
81
|
object.setNativeState(runtime, shared());
|
|
@@ -86,14 +86,14 @@ jsi::Value HybridObject::toObject(jsi::Runtime& runtime) {
|
|
|
86
86
|
#ifdef NITRO_DEBUG
|
|
87
87
|
// 6. Assign a private __type property for debugging - this will be used so users know it's not just an empty object.
|
|
88
88
|
std::string typeName = "HybridObject<" + std::string(_name) + ">";
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
89
|
+
CommonGlobals::Object::defineProperty(runtime, object, "__type",
|
|
90
|
+
PlainPropertyDescriptor{
|
|
91
|
+
// .configurable has to be true because this property is non-frozen
|
|
92
|
+
.configurable = true,
|
|
93
|
+
.enumerable = true,
|
|
94
|
+
.value = jsi::String::createFromUtf8(runtime, typeName),
|
|
95
|
+
.writable = false,
|
|
96
|
+
});
|
|
97
97
|
#endif
|
|
98
98
|
|
|
99
99
|
// 7. Throw a jsi::WeakObject pointing to our object into cache so subsequent calls can use it from cache
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
//
|
|
7
7
|
|
|
8
8
|
#include "InstallNitro.hpp"
|
|
9
|
+
#include "CommonGlobals.hpp"
|
|
9
10
|
#include "HybridNitroModulesProxy.hpp"
|
|
10
|
-
#include "ObjectUtils.hpp"
|
|
11
11
|
|
|
12
12
|
namespace margelo::nitro {
|
|
13
13
|
|
|
@@ -23,7 +23,7 @@ void install(jsi::Runtime& runtime, std::shared_ptr<Dispatcher> dispatcher) {
|
|
|
23
23
|
void install(jsi::Runtime& runtime) {
|
|
24
24
|
// Installs global.NitroModulesProxy
|
|
25
25
|
auto proxy = std::make_shared<HybridNitroModulesProxy>();
|
|
26
|
-
|
|
26
|
+
CommonGlobals::defineGlobal(runtime, KnownGlobalPropertyName::NITRO_MODULES_PROXY, proxy->toObject(runtime));
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
} // namespace margelo::nitro
|
package/cpp/jsi/JSICache.cpp
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
//
|
|
7
7
|
|
|
8
8
|
#include "JSICache.hpp"
|
|
9
|
+
#include "CommonGlobals.hpp"
|
|
9
10
|
#include "JSIHelpers.hpp"
|
|
10
11
|
#include "NitroDefines.hpp"
|
|
11
|
-
#include "ObjectUtils.hpp"
|
|
12
12
|
|
|
13
13
|
namespace margelo::nitro {
|
|
14
14
|
|
|
@@ -54,11 +54,16 @@ JSICacheReference JSICache::getOrCreateCache(jsi::Runtime& runtime) {
|
|
|
54
54
|
// Wrap it in a jsi::Value using NativeState
|
|
55
55
|
jsi::Object cache(runtime);
|
|
56
56
|
cache.setNativeState(runtime, nativeState);
|
|
57
|
-
//
|
|
58
|
-
// We pass `allowCache = false` because we are the JSICache, and this would cause recursion.
|
|
59
|
-
ObjectUtils::defineGlobal(runtime, KnownGlobalPropertyName::JSI_CACHE, std::move(cache), /* allowCache */ false);
|
|
60
|
-
// Add it to our map of caches
|
|
57
|
+
// Add it to our map of caches first, because the next `::defineGlobal(...)` call will already be using it (recursively)
|
|
61
58
|
_globalCache[&runtime] = nativeState;
|
|
59
|
+
try {
|
|
60
|
+
// Call Object.defineProperty(global, ...) now with our cache (it internally already uses cache)
|
|
61
|
+
CommonGlobals::defineGlobal(runtime, KnownGlobalPropertyName::JSI_CACHE, std::move(cache));
|
|
62
|
+
} catch (...) {
|
|
63
|
+
// If `defineGlobal(...)` failed, we should remove it from `_globalCache` so we don't have invalid caches.
|
|
64
|
+
_globalCache.erase(&runtime);
|
|
65
|
+
throw;
|
|
66
|
+
}
|
|
62
67
|
// Return it
|
|
63
68
|
return JSICacheReference(nativeState);
|
|
64
69
|
}
|
package/cpp/jsi/JSICache.hpp
CHANGED
|
@@ -63,6 +63,7 @@ private:
|
|
|
63
63
|
std::vector<WeakReference<jsi::Object>> _objectCache;
|
|
64
64
|
std::vector<WeakReference<jsi::Function>> _functionCache;
|
|
65
65
|
std::vector<WeakReference<jsi::WeakObject>> _weakObjectCache;
|
|
66
|
+
std::vector<WeakReference<jsi::PropNameID>> _propNameIDCache;
|
|
66
67
|
std::vector<WeakReference<jsi::ArrayBuffer>> _arrayBufferCache;
|
|
67
68
|
|
|
68
69
|
private:
|
|
@@ -103,6 +104,11 @@ public:
|
|
|
103
104
|
_strongCache->_weakObjectCache.push_back(owning.weak());
|
|
104
105
|
return owning;
|
|
105
106
|
}
|
|
107
|
+
BorrowingReference<jsi::PropNameID> makeShared(jsi::PropNameID&& value) {
|
|
108
|
+
BorrowingReference<jsi::PropNameID> owning(new jsi::PropNameID(std::move(value)));
|
|
109
|
+
_strongCache->_propNameIDCache.push_back(owning.weak());
|
|
110
|
+
return owning;
|
|
111
|
+
}
|
|
106
112
|
BorrowingReference<jsi::ArrayBuffer> makeShared(jsi::ArrayBuffer&& value) {
|
|
107
113
|
BorrowingReference<jsi::ArrayBuffer> owning(new jsi::ArrayBuffer(std::move(value)));
|
|
108
114
|
_strongCache->_arrayBufferCache.push_back(owning.weak());
|
|
@@ -18,6 +18,7 @@ struct JSIConverter;
|
|
|
18
18
|
|
|
19
19
|
#include "AnyMap.hpp"
|
|
20
20
|
#include "JSIHelpers.hpp"
|
|
21
|
+
#include "PropNameIDCache.hpp"
|
|
21
22
|
#include <jsi/jsi.h>
|
|
22
23
|
#include <memory>
|
|
23
24
|
|
|
@@ -48,9 +49,9 @@ struct JSIConverter<std::shared_ptr<AnyMap>> final {
|
|
|
48
49
|
size_t size = propNames.size(runtime);
|
|
49
50
|
std::shared_ptr<AnyMap> map = AnyMap::make();
|
|
50
51
|
for (size_t i = 0; i < size; i++) {
|
|
51
|
-
|
|
52
|
-
jsi::Value jsValue = object.getProperty(runtime, jsKey);
|
|
53
|
-
map->setAny(jsKey
|
|
52
|
+
std::string jsKey = propNames.getValueAtIndex(runtime, i).getString(runtime).utf8(runtime);
|
|
53
|
+
jsi::Value jsValue = object.getProperty(runtime, PropNameIDCache::get(runtime, jsKey));
|
|
54
|
+
map->setAny(jsKey, JSIConverter<AnyValue>::fromJSI(runtime, jsValue));
|
|
54
55
|
}
|
|
55
56
|
return map;
|
|
56
57
|
}
|
|
@@ -14,6 +14,8 @@ struct JSIConverter;
|
|
|
14
14
|
|
|
15
15
|
#include "JSIConverter.hpp"
|
|
16
16
|
|
|
17
|
+
#include "CommonGlobals.hpp"
|
|
18
|
+
#include "PropNameIDCache.hpp"
|
|
17
19
|
#include <chrono>
|
|
18
20
|
#include <jsi/jsi.h>
|
|
19
21
|
#include <memory>
|
|
@@ -38,15 +40,15 @@ struct JSIConverter<std::chrono::system_clock::time_point> final {
|
|
|
38
40
|
|
|
39
41
|
jsi::Object object = arg.asObject(runtime);
|
|
40
42
|
#ifdef NITRO_DEBUG
|
|
41
|
-
if (!object.hasProperty(runtime, "getTime")) {
|
|
43
|
+
if (!object.hasProperty(runtime, PropNameIDCache::get(runtime, "getTime"))) {
|
|
42
44
|
throw std::invalid_argument("Object \"" + arg.toString(runtime).utf8(runtime) +
|
|
43
45
|
"\" does not have a .getTime() function! "
|
|
44
46
|
"It's not a valid Date object.");
|
|
45
47
|
}
|
|
46
48
|
#endif
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
jsi::Function getTimeFunc =
|
|
51
|
+
object.getProperty(runtime, PropNameIDCache::get(runtime, "getTime")).getObject(runtime).getFunction(runtime);
|
|
50
52
|
double msSinceEpoch = getTimeFunc.callWithThis(runtime, object).getNumber();
|
|
51
53
|
|
|
52
54
|
// ms -> std::chrono::system_clock::time_point
|
|
@@ -62,19 +64,15 @@ struct JSIConverter<std::chrono::system_clock::time_point> final {
|
|
|
62
64
|
auto ms = chrono::duration_cast<chrono::milliseconds>(date.time_since_epoch()).count();
|
|
63
65
|
auto msSinceEpoch = static_cast<double>(ms);
|
|
64
66
|
|
|
65
|
-
//
|
|
66
|
-
jsi::
|
|
67
|
-
|
|
68
|
-
jsi::Value jsDate = dateCtor.callAsConstructor(runtime, {jsi::Value(msSinceEpoch)});
|
|
67
|
+
// 2. Call `new Date(...)` with the milliseconds since epoch
|
|
68
|
+
jsi::Value jsDate = CommonGlobals::Date::callConstructor(runtime, msSinceEpoch);
|
|
69
69
|
return jsDate;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
73
73
|
if (value.isObject()) {
|
|
74
74
|
jsi::Object object = value.getObject(runtime);
|
|
75
|
-
|
|
76
|
-
jsi::Function dateCtor = runtime.global().getPropertyAsFunction(runtime, "Date");
|
|
77
|
-
return object.instanceOf(runtime, dateCtor);
|
|
75
|
+
return CommonGlobals::Date::isInstanceOf(runtime, object);
|
|
78
76
|
}
|
|
79
77
|
return false;
|
|
80
78
|
}
|
|
@@ -10,9 +10,10 @@ template <typename T, typename Enable>
|
|
|
10
10
|
struct JSIConverter;
|
|
11
11
|
} // namespace margelo::nitro
|
|
12
12
|
|
|
13
|
+
#include "CommonGlobals.hpp"
|
|
13
14
|
#include "JSIConverter.hpp"
|
|
14
|
-
|
|
15
15
|
#include "NitroTypeInfo.hpp"
|
|
16
|
+
#include "PropNameIDCache.hpp"
|
|
16
17
|
#include <exception>
|
|
17
18
|
#include <jsi/jsi.h>
|
|
18
19
|
|
|
@@ -25,8 +26,8 @@ template <>
|
|
|
25
26
|
struct JSIConverter<std::exception_ptr> final {
|
|
26
27
|
static inline std::exception_ptr fromJSI(jsi::Runtime& runtime, const jsi::Value& error) {
|
|
27
28
|
jsi::Object object = error.asObject(runtime);
|
|
28
|
-
std::string name = object.getProperty(runtime, "name").asString(runtime).utf8(runtime);
|
|
29
|
-
std::string message = object.getProperty(runtime, "message").asString(runtime).utf8(runtime);
|
|
29
|
+
std::string name = object.getProperty(runtime, PropNameIDCache::get(runtime, "name")).asString(runtime).utf8(runtime);
|
|
30
|
+
std::string message = object.getProperty(runtime, PropNameIDCache::get(runtime, "message")).asString(runtime).utf8(runtime);
|
|
30
31
|
return std::make_exception_ptr(std::runtime_error(name + ": " + message));
|
|
31
32
|
}
|
|
32
33
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const std::exception_ptr& exception) {
|
|
@@ -51,8 +52,7 @@ struct JSIConverter<std::exception_ptr> final {
|
|
|
51
52
|
return false;
|
|
52
53
|
}
|
|
53
54
|
jsi::Object object = value.getObject(runtime);
|
|
54
|
-
|
|
55
|
-
return object.instanceOf(runtime, errorCtor);
|
|
55
|
+
return CommonGlobals::Error::isInstanceOf(runtime, object);
|
|
56
56
|
}
|
|
57
57
|
};
|
|
58
58
|
|
|
@@ -16,6 +16,7 @@ struct JSIConverter;
|
|
|
16
16
|
#include "JSCallback.hpp"
|
|
17
17
|
#include "JSICache.hpp"
|
|
18
18
|
#include "PromiseType.hpp"
|
|
19
|
+
#include "PropNameIDCache.hpp"
|
|
19
20
|
#include <jsi/jsi.h>
|
|
20
21
|
|
|
21
22
|
namespace margelo::nitro {
|
|
@@ -56,7 +57,9 @@ struct JSIConverter<std::function<R(Args...)>> final {
|
|
|
56
57
|
}
|
|
57
58
|
return callHybridFunction(function, runtime, args, std::index_sequence_for<Args...>{});
|
|
58
59
|
};
|
|
59
|
-
return jsi::Function::createFromHostFunction(runtime,
|
|
60
|
+
return jsi::Function::createFromHostFunction(runtime, //
|
|
61
|
+
PropNameIDCache::get(runtime, "hostFunction"), //
|
|
62
|
+
sizeof...(Args), //
|
|
60
63
|
std::move(jsFunction));
|
|
61
64
|
}
|
|
62
65
|
|
|
@@ -11,10 +11,12 @@ template <typename T, typename Enable>
|
|
|
11
11
|
struct JSIConverter;
|
|
12
12
|
} // namespace margelo::nitro
|
|
13
13
|
|
|
14
|
+
#include "CommonGlobals.hpp"
|
|
14
15
|
#include "JSIConverter.hpp"
|
|
15
16
|
#include "NitroTypeInfo.hpp"
|
|
16
17
|
#include "Null.hpp"
|
|
17
18
|
#include "Promise.hpp"
|
|
19
|
+
#include "PropNameIDCache.hpp"
|
|
18
20
|
#include <exception>
|
|
19
21
|
#include <jsi/jsi.h>
|
|
20
22
|
#include <memory>
|
|
@@ -44,7 +46,7 @@ struct JSIConverter<std::shared_ptr<Promise<TResult>>> final {
|
|
|
44
46
|
|
|
45
47
|
// Chain .then listeners on JS Promise (onResolved and onRejected)
|
|
46
48
|
jsi::Object jsPromise = value.asObject(runtime);
|
|
47
|
-
jsi::Function thenFn = jsPromise.
|
|
49
|
+
jsi::Function thenFn = jsPromise.getProperty(runtime, PropNameIDCache::get(runtime, "then")).asObject(runtime).getFunction(runtime);
|
|
48
50
|
thenFn.callWithThis(runtime, jsPromise, thenCallback, catchCallback);
|
|
49
51
|
|
|
50
52
|
return promise;
|
|
@@ -53,7 +55,6 @@ struct JSIConverter<std::shared_ptr<Promise<TResult>>> final {
|
|
|
53
55
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const std::shared_ptr<Promise<TResult>>& promise) {
|
|
54
56
|
if (promise->isPending()) {
|
|
55
57
|
// Get Promise ctor from global
|
|
56
|
-
jsi::Function promiseCtor = runtime.global().getPropertyAsFunction(runtime, "Promise");
|
|
57
58
|
jsi::HostFunctionType executor = [promise](jsi::Runtime& runtime, const jsi::Value&, const jsi::Value* arguments,
|
|
58
59
|
size_t) -> jsi::Value {
|
|
59
60
|
// Add resolver listener
|
|
@@ -72,27 +73,21 @@ struct JSIConverter<std::shared_ptr<Promise<TResult>>> final {
|
|
|
72
73
|
|
|
73
74
|
return jsi::Value::undefined();
|
|
74
75
|
};
|
|
75
|
-
|
|
76
|
-
return promiseCtor.callAsConstructor(
|
|
77
|
-
runtime, jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "executor"), 2, executor));
|
|
76
|
+
return CommonGlobals::Promise::callConstructor(runtime, std::move(executor));
|
|
78
77
|
} else if (promise->isResolved()) {
|
|
79
78
|
// Promise is already resolved - just return immediately
|
|
80
|
-
jsi::Object promiseObject = runtime.global().getPropertyAsObject(runtime, "Promise");
|
|
81
|
-
jsi::Function createResolvedPromise = promiseObject.getPropertyAsFunction(runtime, "resolve");
|
|
82
79
|
if constexpr (std::is_void_v<TResult>) {
|
|
83
80
|
// It's resolving to void.
|
|
84
|
-
return
|
|
81
|
+
return CommonGlobals::Promise::resolved(runtime);
|
|
85
82
|
} else {
|
|
86
83
|
// It's resolving to a type.
|
|
87
84
|
jsi::Value result = JSIConverter<TResult>::toJSI(runtime, promise->getResult());
|
|
88
|
-
return
|
|
85
|
+
return CommonGlobals::Promise::resolved(runtime, std::move(result));
|
|
89
86
|
}
|
|
90
87
|
} else if (promise->isRejected()) {
|
|
91
88
|
// Promise is already rejected - just return immediately
|
|
92
|
-
jsi::Object promiseObject = runtime.global().getPropertyAsObject(runtime, "Promise");
|
|
93
|
-
jsi::Function createRejectedPromise = promiseObject.getPropertyAsFunction(runtime, "reject");
|
|
94
89
|
jsi::Value error = JSIConverter<std::exception_ptr>::toJSI(runtime, promise->getError());
|
|
95
|
-
return
|
|
90
|
+
return CommonGlobals::Promise::rejected(runtime, std::move(error));
|
|
96
91
|
} else {
|
|
97
92
|
std::string typeName = TypeInfo::getFriendlyTypename<TResult>(true);
|
|
98
93
|
throw std::runtime_error("Promise<" + typeName + "> has invalid state!");
|
|
@@ -104,8 +99,7 @@ struct JSIConverter<std::shared_ptr<Promise<TResult>>> final {
|
|
|
104
99
|
return false;
|
|
105
100
|
}
|
|
106
101
|
jsi::Object object = value.getObject(runtime);
|
|
107
|
-
|
|
108
|
-
return object.instanceOf(runtime, promiseCtor);
|
|
102
|
+
return CommonGlobals::Promise::isInstanceOf(runtime, object);
|
|
109
103
|
}
|
|
110
104
|
};
|
|
111
105
|
|
|
@@ -14,6 +14,7 @@ struct JSIConverter;
|
|
|
14
14
|
|
|
15
15
|
#include "AnyMap.hpp"
|
|
16
16
|
#include "JSIHelpers.hpp"
|
|
17
|
+
#include "PropNameIDCache.hpp"
|
|
17
18
|
#include <jsi/jsi.h>
|
|
18
19
|
#include <unordered_map>
|
|
19
20
|
|
|
@@ -33,7 +34,7 @@ struct JSIConverter<std::unordered_map<std::string, ValueType>> final {
|
|
|
33
34
|
map.reserve(length);
|
|
34
35
|
for (size_t i = 0; i < length; ++i) {
|
|
35
36
|
std::string key = propertyNames.getValueAtIndex(runtime, i).asString(runtime).utf8(runtime);
|
|
36
|
-
jsi::Value value = object.getProperty(runtime, key
|
|
37
|
+
jsi::Value value = object.getProperty(runtime, PropNameIDCache::get(runtime, key));
|
|
37
38
|
map.emplace(key, JSIConverter<ValueType>::fromJSI(runtime, value));
|
|
38
39
|
}
|
|
39
40
|
return map;
|
package/cpp/jsi/JSIHelpers.hpp
CHANGED
|
@@ -42,7 +42,7 @@ static inline bool isPlainObject(jsi::Runtime& runtime, const jsi::Object& objec
|
|
|
42
42
|
* Get an ID for the given Runtime.
|
|
43
43
|
*
|
|
44
44
|
* The ID usually consists of a Runtime description (e.g. "HermesRuntime"),
|
|
45
|
-
* and
|
|
45
|
+
* and its Thread's name (e.g. "com.facebook.react.runtime.JavaScript")
|
|
46
46
|
*/
|
|
47
47
|
static inline std::string getRuntimeId(jsi::Runtime& runtime) {
|
|
48
48
|
std::string threadName = ThreadUtils::getThreadName();
|