react-native-nitro-modules 0.1.3 → 0.1.5
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 +3 -1
- package/android/src/main/cpp/platform/ThreadUtils.cpp +5 -0
- package/cpp/core/AnyMap.hpp +2 -1
- package/cpp/core/ArrayBuffer.hpp +108 -16
- package/cpp/core/HybridObject.hpp +3 -4
- package/cpp/jsi/JSIConverter+AnyMap.hpp +64 -0
- package/cpp/jsi/JSIConverter+ArrayBuffer.hpp +50 -0
- package/cpp/jsi/JSIConverter+Function.hpp +124 -0
- package/cpp/jsi/JSIConverter+HybridObject.hpp +130 -0
- package/cpp/jsi/JSIConverter+Optional.hpp +41 -0
- package/cpp/jsi/JSIConverter+Promise.hpp +87 -0
- package/cpp/jsi/JSIConverter+Tuple.hpp +60 -0
- package/cpp/jsi/JSIConverter+UnorderedMap.hpp +50 -0
- package/cpp/jsi/JSIConverter+Variant.hpp +97 -0
- package/cpp/jsi/JSIConverter+Vector.hpp +48 -0
- package/cpp/jsi/JSIConverter.hpp +22 -498
- package/cpp/platform/ThreadUtils.hpp +6 -0
- package/cpp/templates/IsSharedPtrTo.hpp +28 -0
- package/cpp/threading/ThreadPool.cpp +84 -0
- package/cpp/threading/ThreadPool.hpp +53 -0
- package/ios/core/HybridContext.cpp +8 -0
- package/{cpp → ios}/core/HybridContext.hpp +6 -3
- package/ios/platform/ThreadUtils.cpp +4 -0
- package/lib/NativeNitroModules.d.ts +5 -0
- package/lib/NativeNitroModules.js +5 -0
- package/lib/NativeNitroModules.web.d.ts +4 -0
- package/lib/NativeNitroModules.web.js +3 -0
- package/lib/commonjs/NativeNitroModules.js +6 -0
- package/lib/commonjs/NativeNitroModules.js.map +1 -1
- package/lib/commonjs/NativeNitroModules.web.js +10 -0
- package/lib/commonjs/NativeNitroModules.web.js.map +1 -0
- package/lib/module/NativeNitroModules.js +5 -0
- package/lib/module/NativeNitroModules.js.map +1 -1
- package/lib/module/NativeNitroModules.web.js +4 -0
- package/lib/module/NativeNitroModules.web.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/NativeNitroModules.ts +11 -0
- package/src/NativeNitroModules.web.ts +9 -0
- package/cpp/templates/IsHostObject.hpp +0 -27
- package/cpp/templates/IsNativeState.hpp +0 -27
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Marc Rousavy on 21.02.24.
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
#pragma once
|
|
6
|
+
|
|
7
|
+
// Forward declare a few of the common types that might have cyclic includes.
|
|
8
|
+
namespace margelo::nitro {
|
|
9
|
+
class Dispatcher;
|
|
10
|
+
class Promise;
|
|
11
|
+
|
|
12
|
+
template <typename T, typename Enable>
|
|
13
|
+
struct JSIConverter;
|
|
14
|
+
} // namespace margelo::nitro
|
|
15
|
+
|
|
16
|
+
#include "JSIConverter.hpp"
|
|
17
|
+
|
|
18
|
+
#include "Dispatcher.hpp"
|
|
19
|
+
#include "Promise.hpp"
|
|
20
|
+
#include "ThreadPool.hpp"
|
|
21
|
+
#include "TypeInfo.hpp"
|
|
22
|
+
#include <future>
|
|
23
|
+
#include <jsi/jsi.h>
|
|
24
|
+
#include <memory>
|
|
25
|
+
|
|
26
|
+
namespace margelo::nitro {
|
|
27
|
+
|
|
28
|
+
using namespace facebook;
|
|
29
|
+
|
|
30
|
+
// std::future<T> <> Promise<T>
|
|
31
|
+
template <typename TResult>
|
|
32
|
+
struct JSIConverter<std::future<TResult>> {
|
|
33
|
+
static inline std::future<TResult> fromJSI(jsi::Runtime&, const jsi::Value&) {
|
|
34
|
+
throw std::runtime_error("Promise cannot be converted to a native type - it needs to be awaited first!");
|
|
35
|
+
}
|
|
36
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, std::future<TResult>&& arg) {
|
|
37
|
+
auto sharedFuture = std::make_shared<std::future<TResult>>(std::move(arg));
|
|
38
|
+
std::shared_ptr<Dispatcher> strongDispatcher = Dispatcher::getRuntimeGlobalDispatcher(runtime);
|
|
39
|
+
std::weak_ptr<Dispatcher> weakDispatcher = strongDispatcher;
|
|
40
|
+
|
|
41
|
+
return Promise::createPromise(runtime, [sharedFuture, weakDispatcher](jsi::Runtime& runtime, std::shared_ptr<Promise> promise) {
|
|
42
|
+
// Spawn new async thread to synchronously wait for the `future<T>` to complete
|
|
43
|
+
std::shared_ptr<ThreadPool> pool = ThreadPool::getSharedPool();
|
|
44
|
+
pool->run([promise, &runtime, weakDispatcher, sharedFuture]() {
|
|
45
|
+
// synchronously wait until the `future<T>` completes. we are running on a background task here.
|
|
46
|
+
sharedFuture->wait();
|
|
47
|
+
|
|
48
|
+
// the async function completed successfully, get a JS Dispatcher so we can resolve on JS Thread
|
|
49
|
+
std::shared_ptr<Dispatcher> dispatcher = weakDispatcher.lock();
|
|
50
|
+
if (!dispatcher) {
|
|
51
|
+
Logger::log("JSIConverter", "Tried resolving Promise on JS Thread, but the `Dispatcher` has already been destroyed.");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
dispatcher->runAsync([&runtime, promise, sharedFuture]() mutable {
|
|
56
|
+
try {
|
|
57
|
+
if constexpr (std::is_void_v<TResult>) {
|
|
58
|
+
// it's returning void, just return undefined to JS
|
|
59
|
+
sharedFuture->get();
|
|
60
|
+
promise->resolve(runtime, jsi::Value::undefined());
|
|
61
|
+
} else {
|
|
62
|
+
// it's returning a custom type, convert it to a jsi::Value
|
|
63
|
+
TResult result = sharedFuture->get();
|
|
64
|
+
jsi::Value jsResult = JSIConverter<TResult>::toJSI(runtime, result);
|
|
65
|
+
promise->resolve(runtime, std::move(jsResult));
|
|
66
|
+
}
|
|
67
|
+
} catch (const std::exception& exception) {
|
|
68
|
+
// the async function threw an error, reject the promise on JS Thread
|
|
69
|
+
std::string what = exception.what();
|
|
70
|
+
promise->reject(runtime, what);
|
|
71
|
+
} catch (...) {
|
|
72
|
+
// the async function threw a non-std error, try getting it
|
|
73
|
+
std::string name = TypeInfo::getCurrentExceptionName();
|
|
74
|
+
promise->reject(runtime, "Unknown non-std exception: " + name);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// This lambda owns the promise shared pointer, and we need to call its
|
|
78
|
+
// destructor on the correct thread here - otherwise it might be called
|
|
79
|
+
// from the waiterThread.
|
|
80
|
+
promise = nullptr;
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
} // namespace margelo::nitro
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Marc Rousavy on 21.02.24.
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
#pragma once
|
|
6
|
+
|
|
7
|
+
// Forward declare a few of the common types that might have cyclic includes.
|
|
8
|
+
namespace margelo::nitro {
|
|
9
|
+
template <typename T, typename Enable>
|
|
10
|
+
struct JSIConverter;
|
|
11
|
+
} // namespace margelo::nitro
|
|
12
|
+
|
|
13
|
+
#include "JSIConverter.hpp"
|
|
14
|
+
|
|
15
|
+
#include "TypeInfo.hpp"
|
|
16
|
+
#include <jsi/jsi.h>
|
|
17
|
+
#include <memory>
|
|
18
|
+
#include <tuple>
|
|
19
|
+
|
|
20
|
+
namespace margelo::nitro {
|
|
21
|
+
|
|
22
|
+
using namespace facebook;
|
|
23
|
+
|
|
24
|
+
// std::tuple<A, B, C> <> [A, B, C]
|
|
25
|
+
template <typename... Types>
|
|
26
|
+
struct JSIConverter<std::tuple<Types...>> {
|
|
27
|
+
static inline std::tuple<Types...> fromJSI(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
28
|
+
jsi::Object object = value.asObject(runtime);
|
|
29
|
+
jsi::Array array = object.asArray(runtime);
|
|
30
|
+
if (array.size(runtime) != sizeof...(Types)) [[unlikely]] {
|
|
31
|
+
std::string types = TypeInfo::getFriendlyTypenames<Types...>();
|
|
32
|
+
throw std::runtime_error("The given JS Array has " + std::to_string(array.size(runtime)) + " items, but std::tuple<" + types +
|
|
33
|
+
"> expects " + std::to_string(sizeof...(Types)) + " items.");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return copyArrayItemsToTuple(runtime, array, std::index_sequence_for<Types...>{});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const std::tuple<Types...>& tuple) {
|
|
40
|
+
jsi::Array array(runtime, sizeof...(Types));
|
|
41
|
+
copyTupleItemsToArray(runtime, array, tuple, std::index_sequence_for<Types...>{});
|
|
42
|
+
return array;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private:
|
|
46
|
+
template <std::size_t... Is>
|
|
47
|
+
static inline std::tuple<Types...> copyArrayItemsToTuple(jsi::Runtime& runtime, const jsi::Array& array, std::index_sequence<Is...>) {
|
|
48
|
+
return std::make_tuple(JSIConverter<Types>::fromJSI(runtime, array.getValueAtIndex(runtime, Is))...);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
template <std::size_t... Is>
|
|
52
|
+
static inline void copyTupleItemsToArray(jsi::Runtime& runtime, jsi::Array& array, const std::tuple<Types...>& tuple,
|
|
53
|
+
std::index_sequence<Is...>) {
|
|
54
|
+
((array.setValueAtIndex(runtime, Is,
|
|
55
|
+
JSIConverter<std::tuple_element_t<Is, std::tuple<Types...>>>::toJSI(runtime, std::get<Is>(tuple)))),
|
|
56
|
+
...);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
} // namespace margelo::nitro
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Marc Rousavy on 21.02.24.
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
#pragma once
|
|
6
|
+
|
|
7
|
+
// Forward declare a few of the common types that might have cyclic includes.
|
|
8
|
+
namespace margelo::nitro {
|
|
9
|
+
template <typename T, typename Enable>
|
|
10
|
+
struct JSIConverter;
|
|
11
|
+
} // namespace margelo::nitro
|
|
12
|
+
|
|
13
|
+
#include "JSIConverter.hpp"
|
|
14
|
+
|
|
15
|
+
#include "AnyMap.hpp"
|
|
16
|
+
#include <jsi/jsi.h>
|
|
17
|
+
#include <unordered_map>
|
|
18
|
+
|
|
19
|
+
namespace margelo::nitro {
|
|
20
|
+
|
|
21
|
+
using namespace facebook;
|
|
22
|
+
|
|
23
|
+
// std::unordered_map<std::string, T> <> Record<string, T>
|
|
24
|
+
template <typename ValueType>
|
|
25
|
+
struct JSIConverter<std::unordered_map<std::string, ValueType>> {
|
|
26
|
+
static inline std::unordered_map<std::string, ValueType> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
27
|
+
jsi::Object object = arg.asObject(runtime);
|
|
28
|
+
jsi::Array propertyNames = object.getPropertyNames(runtime);
|
|
29
|
+
size_t length = propertyNames.size(runtime);
|
|
30
|
+
|
|
31
|
+
std::unordered_map<std::string, ValueType> map;
|
|
32
|
+
map.reserve(length);
|
|
33
|
+
for (size_t i = 0; i < length; ++i) {
|
|
34
|
+
std::string key = propertyNames.getValueAtIndex(runtime, i).asString(runtime).utf8(runtime);
|
|
35
|
+
jsi::Value value = object.getProperty(runtime, key.c_str());
|
|
36
|
+
map.emplace(key, JSIConverter<ValueType>::fromJSI(runtime, value));
|
|
37
|
+
}
|
|
38
|
+
return map;
|
|
39
|
+
}
|
|
40
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const std::unordered_map<std::string, ValueType>& map) {
|
|
41
|
+
jsi::Object object(runtime);
|
|
42
|
+
for (const auto& pair : map) {
|
|
43
|
+
jsi::Value value = JSIConverter<ValueType>::toJSI(runtime, pair.second);
|
|
44
|
+
object.setProperty(runtime, pair.first.c_str(), std::move(value));
|
|
45
|
+
}
|
|
46
|
+
return object;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
} // namespace margelo::nitro
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Marc Rousavy on 21.02.24.
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
#pragma once
|
|
6
|
+
|
|
7
|
+
// Forward declare a few of the common types that might have cyclic includes.
|
|
8
|
+
namespace margelo::nitro {
|
|
9
|
+
struct AnyValue;
|
|
10
|
+
class AnyMap;
|
|
11
|
+
|
|
12
|
+
template <typename T, typename Enable>
|
|
13
|
+
struct JSIConverter;
|
|
14
|
+
} // namespace margelo::nitro
|
|
15
|
+
|
|
16
|
+
#include "JSIConverter+UnorderedMap.hpp"
|
|
17
|
+
#include "JSIConverter+Vector.hpp"
|
|
18
|
+
#include "JSIConverter.hpp"
|
|
19
|
+
|
|
20
|
+
#include "AnyMap.hpp"
|
|
21
|
+
#include "IsInPack.hpp"
|
|
22
|
+
#include "TypeInfo.hpp"
|
|
23
|
+
#include <jsi/jsi.h>
|
|
24
|
+
#include <memory>
|
|
25
|
+
#include <variant>
|
|
26
|
+
|
|
27
|
+
namespace margelo::nitro {
|
|
28
|
+
|
|
29
|
+
using namespace facebook;
|
|
30
|
+
|
|
31
|
+
// std::variant<A, B, C> <> A | B | C
|
|
32
|
+
template <typename... Types>
|
|
33
|
+
struct JSIConverter<std::variant<Types...>> {
|
|
34
|
+
static inline std::variant<Types...> fromJSI(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
35
|
+
if (value.isNull()) {
|
|
36
|
+
if constexpr (is_in_pack_v<std::monostate, Types...>) {
|
|
37
|
+
return std::monostate();
|
|
38
|
+
} else {
|
|
39
|
+
throw typeNotSupportedError("null");
|
|
40
|
+
}
|
|
41
|
+
} else if (value.isBool()) {
|
|
42
|
+
if constexpr (is_in_pack_v<bool, Types...>) {
|
|
43
|
+
return JSIConverter<bool>::fromJSI(runtime, value);
|
|
44
|
+
} else {
|
|
45
|
+
throw typeNotSupportedError("boolean");
|
|
46
|
+
}
|
|
47
|
+
} else if (value.isNumber()) {
|
|
48
|
+
if constexpr (is_in_pack_v<double, Types...>) {
|
|
49
|
+
return JSIConverter<double>::fromJSI(runtime, value);
|
|
50
|
+
} else {
|
|
51
|
+
throw typeNotSupportedError("number");
|
|
52
|
+
}
|
|
53
|
+
} else if (value.isString()) {
|
|
54
|
+
if constexpr (is_in_pack_v<std::string, Types...>) {
|
|
55
|
+
return JSIConverter<std::string>::fromJSI(runtime, value);
|
|
56
|
+
} else {
|
|
57
|
+
throw typeNotSupportedError("string");
|
|
58
|
+
}
|
|
59
|
+
} else if (value.isBigInt()) {
|
|
60
|
+
if constexpr (is_in_pack_v<int64_t, Types...>) {
|
|
61
|
+
return JSIConverter<int64_t>::fromJSI(runtime, value);
|
|
62
|
+
} else {
|
|
63
|
+
throw typeNotSupportedError("bigint");
|
|
64
|
+
}
|
|
65
|
+
} else if (value.isObject()) {
|
|
66
|
+
jsi::Object valueObj = value.getObject(runtime);
|
|
67
|
+
if (valueObj.isArray(runtime)) {
|
|
68
|
+
if constexpr (is_in_pack_v<std::vector<AnyValue>, Types...>) {
|
|
69
|
+
return JSIConverter<std::vector<AnyValue>>::fromJSI(runtime, value);
|
|
70
|
+
} else {
|
|
71
|
+
throw typeNotSupportedError("array[]");
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
if constexpr (is_in_pack_v<std::unordered_map<std::string, AnyValue>, Types...>) {
|
|
75
|
+
return JSIConverter<std::unordered_map<std::string, AnyValue>>::fromJSI(runtime, value);
|
|
76
|
+
} else {
|
|
77
|
+
throw typeNotSupportedError("object{}");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
std::string stringRepresentation = value.toString(runtime).utf8(runtime);
|
|
82
|
+
throw std::runtime_error("Cannot convert \"" + stringRepresentation + "\" to std::variant<...>!");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const std::variant<Types...>& variant) {
|
|
87
|
+
return std::visit([&runtime](const auto& val) { return JSIConverter<std::decay_t<decltype(val)>>::toJSI(runtime, val); }, variant);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private:
|
|
91
|
+
static inline std::runtime_error typeNotSupportedError(const std::string& type) {
|
|
92
|
+
std::string types = TypeInfo::getFriendlyTypenames<Types...>();
|
|
93
|
+
return std::runtime_error(type + " is not supported in variant<" + types + ">!");
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
} // namespace margelo::nitro
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Marc Rousavy on 21.02.24.
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
#pragma once
|
|
6
|
+
|
|
7
|
+
// Forward declare a few of the common types that might have cyclic includes.
|
|
8
|
+
namespace margelo::nitro {
|
|
9
|
+
template <typename T, typename Enable>
|
|
10
|
+
struct JSIConverter;
|
|
11
|
+
} // namespace margelo::nitro
|
|
12
|
+
|
|
13
|
+
#include "JSIConverter.hpp"
|
|
14
|
+
|
|
15
|
+
#include "AnyMap.hpp"
|
|
16
|
+
#include <jsi/jsi.h>
|
|
17
|
+
#include <vector>
|
|
18
|
+
|
|
19
|
+
namespace margelo::nitro {
|
|
20
|
+
|
|
21
|
+
using namespace facebook;
|
|
22
|
+
|
|
23
|
+
// std::vector<T> <> T[]
|
|
24
|
+
template <typename ElementType>
|
|
25
|
+
struct JSIConverter<std::vector<ElementType>> {
|
|
26
|
+
static inline std::vector<ElementType> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
27
|
+
jsi::Array array = arg.asObject(runtime).asArray(runtime);
|
|
28
|
+
size_t length = array.size(runtime);
|
|
29
|
+
|
|
30
|
+
std::vector<ElementType> vector;
|
|
31
|
+
vector.reserve(length);
|
|
32
|
+
for (size_t i = 0; i < length; ++i) {
|
|
33
|
+
jsi::Value elementValue = array.getValueAtIndex(runtime, i);
|
|
34
|
+
vector.emplace_back(JSIConverter<ElementType>::fromJSI(runtime, elementValue));
|
|
35
|
+
}
|
|
36
|
+
return vector;
|
|
37
|
+
}
|
|
38
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const std::vector<ElementType>& vector) {
|
|
39
|
+
jsi::Array array(runtime, vector.size());
|
|
40
|
+
for (size_t i = 0; i < vector.size(); i++) {
|
|
41
|
+
jsi::Value value = JSIConverter<ElementType>::toJSI(runtime, vector[i]);
|
|
42
|
+
array.setValueAtIndex(runtime, i, std::move(value));
|
|
43
|
+
}
|
|
44
|
+
return array;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
} // namespace margelo::nitro
|