react-native-nitro-modules 0.31.4 → 0.31.6

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.
@@ -35,6 +35,7 @@ Pod::Spec.new do |s|
35
35
  "cpp/core/AnyMap.hpp",
36
36
  "cpp/core/ArrayBuffer.hpp",
37
37
  "cpp/core/HybridObject.hpp",
38
+ "cpp/core/Null.hpp",
38
39
  "cpp/core/Promise.hpp",
39
40
  "cpp/entrypoint/HybridNitroModulesProxy.hpp",
40
41
  "cpp/entrypoint/InstallNitro.hpp",
package/README.md CHANGED
@@ -169,6 +169,12 @@ The following C++ / JS types are supported out of the box:
169
169
  <td><code>T?</code></td>
170
170
  <td><code>T?</code></td>
171
171
  </tr>
172
+ <tr>
173
+ <td><code>null</code></td>
174
+ <td><code>NullType</code></td>
175
+ <td><code>NullType</code></td>
176
+ <td><code>NullType</code></td>
177
+ </tr>
172
178
  <tr>
173
179
  <td><code>(T...) =&gt; void</code></td>
174
180
  <td><code>std::function&lt;void (T...)&gt;</code></td>
@@ -78,7 +78,7 @@ protected:
78
78
 
79
79
  private:
80
80
  // Java initializers
81
- explicit JAnyValue(/* null */) : _value(std::monostate()) {}
81
+ explicit JAnyValue(NullType null) : _value(null) {}
82
82
  explicit JAnyValue(double value) : _value(value) {}
83
83
  explicit JAnyValue(bool value) : _value(value) {}
84
84
  explicit JAnyValue(int64_t value) : _value(value) {}
@@ -91,7 +91,7 @@ private:
91
91
 
92
92
  protected:
93
93
  bool isNull() {
94
- return std::holds_alternative<std::monostate>(_value);
94
+ return std::holds_alternative<NullType>(_value);
95
95
  }
96
96
  bool isDouble() {
97
97
  return std::holds_alternative<double>(_value);
@@ -0,0 +1,33 @@
1
+ //
2
+ // JNull.hpp
3
+ // react-native-nitro
4
+ //
5
+ // Created by Marc Rousavy on 10.11.25
6
+ //
7
+
8
+ #pragma once
9
+
10
+ #include <fbjni/fbjni.h>
11
+
12
+ namespace margelo::nitro {
13
+
14
+ using namespace facebook;
15
+
16
+ /**
17
+ * Represents a `Null` from Kotlin.
18
+ */
19
+ struct JNull final : public jni::JavaClass<JNull> {
20
+ public:
21
+ static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/core/NullType;";
22
+
23
+ public:
24
+ static jni::global_ref<JNull> null() {
25
+ static const auto clazz = javaClassStatic();
26
+ static const auto nullField = clazz->getStaticField<JNull>("NULL");
27
+ static const auto nullValue = clazz->getStaticFieldValue(nullField);
28
+ static const auto globalNullValue = jni::make_global(nullValue);
29
+ return globalNullValue;
30
+ }
31
+ };
32
+
33
+ } // namespace margelo::nitro
@@ -10,6 +10,7 @@
10
10
  #include "Promise.hpp"
11
11
  #include <fbjni/fbjni.h>
12
12
  #include <mutex>
13
+ #include <variant>
13
14
 
14
15
  namespace margelo::nitro {
15
16
 
@@ -37,6 +38,8 @@ struct JOnRejectedCallback : public jni::JavaClass<JOnRejectedCallback> {
37
38
  class JPromise final : public jni::HybridClass<JPromise> {
38
39
  public:
39
40
  static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/core/Promise;";
41
+ using ResultType = jni::global_ref<jni::JObject>;
42
+ using ErrorType = jni::global_ref<jni::JThrowable>;
40
43
  using OnResolvedFunc = std::function<void(jni::alias_ref<jni::JObject>)>;
41
44
  using OnRejectedFunc = std::function<void(jni::alias_ref<jni::JThrowable>)>;
42
45
 
@@ -58,7 +61,7 @@ public:
58
61
 
59
62
  public:
60
63
  ~JPromise() override {
61
- if (_result == nullptr && _error == nullptr) [[unlikely]] {
64
+ if (isPending()) [[unlikely]] {
62
65
  jni::ThreadScope::WithClassLoader([&]() {
63
66
  std::runtime_error error("Timeouted: JPromise was destroyed!");
64
67
  this->reject(jni::getJavaExceptionForCppException(std::make_exception_ptr(error)));
@@ -69,25 +72,27 @@ public:
69
72
  public:
70
73
  void resolve(jni::alias_ref<jni::JObject> result) {
71
74
  std::unique_lock lock(_mutex);
72
- _result = jni::make_global(result);
75
+ jni::global_ref<jni::JObject> globalResult = jni::make_global(result);
76
+ _state = globalResult;
73
77
  for (const auto& onResolved : _onResolvedListeners) {
74
- onResolved(_result);
78
+ onResolved(result);
75
79
  }
76
80
  }
77
81
  void reject(jni::alias_ref<jni::JThrowable> error) {
78
82
  std::unique_lock lock(_mutex);
79
- _error = jni::make_global(error);
83
+ jni::global_ref<jni::JThrowable> globalError = jni::make_global(error);
84
+ _state = globalError;
80
85
  for (const auto& onRejected : _onRejectedListeners) {
81
- onRejected(_error);
86
+ onRejected(error);
82
87
  }
83
88
  }
84
89
 
85
90
  public:
86
91
  void addOnResolvedListener(OnResolvedFunc&& onResolved) {
87
92
  std::unique_lock lock(_mutex);
88
- if (_result != nullptr) {
93
+ if (auto result = std::get_if<ResultType>(&_state)) {
89
94
  // Promise is already resolved! Call the callback immediately
90
- onResolved(_result);
95
+ onResolved(*result);
91
96
  } else {
92
97
  // Promise is not yet resolved, put the listener in our queue.
93
98
  _onResolvedListeners.push_back(std::move(onResolved));
@@ -95,9 +100,9 @@ public:
95
100
  }
96
101
  void addOnRejectedListener(OnRejectedFunc&& onRejected) {
97
102
  std::unique_lock lock(_mutex);
98
- if (_error != nullptr) {
103
+ if (auto error = std::get_if<ErrorType>(&_state)) {
99
104
  // Promise is already rejected! Call the callback immediately
100
- onRejected(_error);
105
+ onRejected(*error);
101
106
  } else {
102
107
  // Promise is not yet rejected, put the listener in our queue.
103
108
  _onRejectedListeners.push_back(std::move(onRejected));
@@ -107,9 +112,9 @@ public:
107
112
  private:
108
113
  void addOnResolvedListenerJava(jni::alias_ref<JOnResolvedCallback> callback) {
109
114
  std::unique_lock lock(_mutex);
110
- if (_result != nullptr) {
115
+ if (auto result = std::get_if<ResultType>(&_state)) {
111
116
  // Promise is already resolved! Call the callback immediately
112
- callback->onResolved(_result);
117
+ callback->onResolved(*result);
113
118
  } else {
114
119
  // Promise is not yet resolved, put the listener in our queue.
115
120
  auto sharedCallback = jni::make_global(callback);
@@ -119,9 +124,9 @@ private:
119
124
  }
120
125
  void addOnRejectedListenerJava(jni::alias_ref<JOnRejectedCallback> callback) {
121
126
  std::unique_lock lock(_mutex);
122
- if (_error != nullptr) {
127
+ if (auto error = std::get_if<ErrorType>(&_state)) {
123
128
  // Promise is already rejected! Call the callback immediately
124
- callback->onRejected(_error);
129
+ callback->onRejected(*error);
125
130
  } else {
126
131
  // Promise is not yet rejected, put the listener in our queue.
127
132
  auto sharedCallback = jni::make_global(callback);
@@ -130,14 +135,19 @@ private:
130
135
  }
131
136
  }
132
137
 
138
+ private:
139
+ [[nodiscard]]
140
+ bool isPending() const noexcept {
141
+ return std::holds_alternative<std::monostate>(_state);
142
+ }
143
+
133
144
  private:
134
145
  JPromise() = default;
135
146
 
136
147
  private:
137
148
  friend HybridBase;
138
149
  using HybridBase::HybridBase;
139
- jni::global_ref<jni::JObject> _result;
140
- jni::global_ref<jni::JThrowable> _error;
150
+ std::variant<std::monostate, ResultType, ErrorType> _state;
141
151
  std::vector<OnResolvedFunc> _onResolvedListeners;
142
152
  std::vector<OnRejectedFunc> _onRejectedListeners;
143
153
  std::mutex _mutex;
@@ -0,0 +1,28 @@
1
+ package com.margelo.nitro.core
2
+
3
+ import androidx.annotation.Keep
4
+ import com.facebook.proguard.annotations.DoNotStrip
5
+ import com.margelo.nitro.core.NullType.Companion.NULL
6
+
7
+ @DoNotStrip
8
+ @Keep
9
+ class NullType private constructor() {
10
+ companion object {
11
+ /**
12
+ * Represents an explicit `null` from JS.
13
+ * This is a singleton.
14
+ */
15
+ @DoNotStrip
16
+ @Keep
17
+ @JvmField
18
+ val NULL = NullType()
19
+ }
20
+
21
+ override fun hashCode(): Int {
22
+ return 0
23
+ }
24
+
25
+ override fun equals(other: Any?): Boolean {
26
+ return other is NullType
27
+ }
28
+ }
@@ -48,7 +48,7 @@ class Promise<T> {
48
48
  * Any `onResolved` listeners will be invoked.
49
49
  */
50
50
  fun resolve(result: T) {
51
- nativeResolve(result as Any)
51
+ nativeResolve(result as Any?)
52
52
  }
53
53
 
54
54
  /**
@@ -95,7 +95,7 @@ class Promise<T> {
95
95
  }
96
96
 
97
97
  // C++ functions
98
- private external fun nativeResolve(result: Any)
98
+ private external fun nativeResolve(result: Any?)
99
99
 
100
100
  private external fun nativeReject(error: Throwable)
101
101
 
@@ -112,7 +112,7 @@ class Promise<T> {
112
112
  @Suppress("unused")
113
113
  @Keep
114
114
  @DoNotStrip
115
- fun onResolved(result: Any)
115
+ fun onResolved(result: Any?)
116
116
  }
117
117
 
118
118
  @Keep
@@ -187,3 +187,19 @@ class Promise<T> {
187
187
  }
188
188
  }
189
189
  }
190
+
191
+ /**
192
+ * Resolves this `Promise<Unit>`.
193
+ * @since void overload
194
+ */
195
+ fun Promise<Unit>.resolve() {
196
+ resolve(Unit)
197
+ }
198
+
199
+ /**
200
+ * Create an already resolved `Promise<Unit>`.
201
+ * @since void overload
202
+ */
203
+ fun Promise.Companion.resolved(): Promise<Unit> {
204
+ return Promise.resolved(Unit)
205
+ }
@@ -31,7 +31,7 @@ bool AnyMap::isNull(const std::string& key) const {
31
31
  if (found == _map.end()) {
32
32
  return false;
33
33
  }
34
- return std::holds_alternative<std::monostate>(found->second);
34
+ return std::holds_alternative<NullType>(found->second);
35
35
  }
36
36
  bool AnyMap::isDouble(const std::string& key) const {
37
37
  auto found = _map.find(key);
@@ -77,12 +77,12 @@ bool AnyMap::isObject(const std::string& key) const {
77
77
  }
78
78
 
79
79
  // Get
80
- std::monostate AnyMap::getNull(const std::string& key) const {
80
+ NullType AnyMap::getNull(const std::string& key) const {
81
81
  auto found = _map.find(key);
82
82
  if (found == _map.end()) {
83
83
  throw std::runtime_error("The key \"" + key + "\" does not exist in this Map!");
84
84
  }
85
- if (auto result = std::get_if<std::monostate>(&found->second)) {
85
+ if (auto result = std::get_if<NullType>(&found->second)) {
86
86
  return *result;
87
87
  } else {
88
88
  throw std::runtime_error("The value at key \"" + key + "\" is not a null!");
@@ -164,7 +164,7 @@ AnyValue AnyMap::getAny(const std::string& key) const {
164
164
 
165
165
  // Set
166
166
  void AnyMap::setNull(const std::string& key) {
167
- _map.emplace(key, std::monostate());
167
+ _map.emplace(key, nitro::null);
168
168
  }
169
169
  void AnyMap::setDouble(const std::string& key, double value) {
170
170
  _map.emplace(key, value);
@@ -5,6 +5,7 @@
5
5
  #pragma once
6
6
 
7
7
  #include "NitroDefines.hpp"
8
+ #include "Null.hpp"
8
9
  #include <map>
9
10
  #include <memory>
10
11
  #include <string>
@@ -18,7 +19,7 @@ struct AnyValue;
18
19
  using AnyArray = std::vector<AnyValue>;
19
20
  using AnyObject = std::unordered_map<std::string, AnyValue>;
20
21
 
21
- using VariantType = std::variant<std::monostate, bool, double, int64_t, std::string, AnyArray, AnyObject>;
22
+ using VariantType = std::variant<NullType, bool, double, int64_t, std::string, AnyArray, AnyObject>;
22
23
  struct AnyValue : VariantType {
23
24
  using VariantType::variant;
24
25
 
@@ -116,7 +117,7 @@ public:
116
117
  * Returns the null value at the given `key`.
117
118
  * If no `null` value exists at the given `key`, this method will throw.
118
119
  */
119
- std::monostate getNull(const std::string& key) const;
120
+ NullType getNull(const std::string& key) const;
120
121
  /**
121
122
  * Returns the double value at the given `key`.
122
123
  * If no `double` value exists at the given `key`, this method will throw.
@@ -0,0 +1,42 @@
1
+ //
2
+ // Created by Marc Rousavy on 30.07.24.
3
+ //
4
+
5
+ #pragma once
6
+
7
+ #include "NitroDefines.hpp"
8
+ #include <functional>
9
+ #include <type_traits>
10
+
11
+ namespace margelo::nitro {
12
+
13
+ /**
14
+ * Represents the type of `null` - which should always be a singleton.
15
+ */
16
+ enum class NullType { null };
17
+
18
+ /**
19
+ * Represents an explicit `null` from JS.
20
+ * This is a singleton.
21
+ */
22
+ inline constexpr NullType null = NullType::null;
23
+
24
+ // Equality and ordering: all instances are equal
25
+ constexpr bool operator==(NullType, NullType) noexcept {
26
+ return true;
27
+ }
28
+ constexpr bool operator!=(NullType, NullType) noexcept {
29
+ return false;
30
+ }
31
+
32
+ } // namespace margelo::nitro
33
+
34
+ // Makes nitro::Null hashable
35
+ namespace std {
36
+ template <>
37
+ struct hash<margelo::nitro::NullType> {
38
+ size_t operator()(margelo::nitro::NullType) const noexcept {
39
+ return 0;
40
+ }
41
+ };
42
+ } // namespace std
@@ -0,0 +1,38 @@
1
+ //
2
+ // Created by Marc Rousavy on 10.11.25.
3
+ //
4
+
5
+ #pragma once
6
+
7
+ // Forward declare JSIConverter to prevent 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
+ #include "Null.hpp"
15
+ #include <jsi/jsi.h>
16
+
17
+ namespace margelo::nitro {
18
+
19
+ using namespace facebook;
20
+
21
+ // NullType <> null
22
+ template <>
23
+ struct JSIConverter<NullType> final {
24
+ static inline NullType fromJSI(jsi::Runtime&, const jsi::Value& arg) {
25
+ if (!arg.isNull()) [[unlikely]] {
26
+ throw std::runtime_error("Cannot convert non-null value to NullType!");
27
+ }
28
+ return nitro::null;
29
+ }
30
+ static inline jsi::Value toJSI(jsi::Runtime&, const NullType&) {
31
+ return jsi::Value::null();
32
+ }
33
+ static inline bool canConvert(jsi::Runtime&, const jsi::Value& value) {
34
+ return value.isNull();
35
+ }
36
+ };
37
+
38
+ } // namespace margelo::nitro
@@ -23,7 +23,7 @@ using namespace facebook;
23
23
  template <typename TInner>
24
24
  struct JSIConverter<std::optional<TInner>> final {
25
25
  static inline std::optional<TInner> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
26
- if (arg.isUndefined() || arg.isNull()) {
26
+ if (arg.isUndefined()) {
27
27
  return std::nullopt;
28
28
  } else {
29
29
  return JSIConverter<TInner>::fromJSI(runtime, arg);
@@ -37,7 +37,7 @@ struct JSIConverter<std::optional<TInner>> final {
37
37
  }
38
38
  }
39
39
  static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
40
- if (value.isUndefined() || value.isNull()) {
40
+ if (value.isUndefined()) {
41
41
  return true;
42
42
  }
43
43
  if (JSIConverter<TInner>::canConvert(runtime, value)) {
@@ -13,6 +13,7 @@ struct JSIConverter;
13
13
 
14
14
  #include "JSIConverter.hpp"
15
15
  #include "NitroTypeInfo.hpp"
16
+ #include "Null.hpp"
16
17
  #include "Promise.hpp"
17
18
  #include <exception>
18
19
  #include <jsi/jsi.h>
@@ -31,6 +32,7 @@ struct JSIConverter<std::shared_ptr<Promise<TResult>>> final {
31
32
  auto thenCallback = [&]() {
32
33
  if constexpr (std::is_void_v<TResult>) {
33
34
  // void: resolve()
35
+ // std::monostate is used as a placeholder for the first argument
34
36
  return JSIConverter<std::function<void(std::monostate)>>::toJSI(runtime, [=](std::monostate) { promise->resolve(); });
35
37
  } else {
36
38
  // T: resolve(T)
@@ -73,20 +73,6 @@ struct JSIConverter<int> final {
73
73
  }
74
74
  };
75
75
 
76
- // std::monostate <> null
77
- template <>
78
- struct JSIConverter<std::monostate> final {
79
- static inline std::monostate fromJSI(jsi::Runtime&, const jsi::Value&) {
80
- return std::monostate();
81
- }
82
- static inline jsi::Value toJSI(jsi::Runtime&, std::monostate) {
83
- return jsi::Value::null();
84
- }
85
- static inline bool canConvert(jsi::Runtime&, const jsi::Value& value) {
86
- return value.isNull() || value.isUndefined();
87
- }
88
- };
89
-
90
76
  // double <> number
91
77
  template <>
92
78
  struct JSIConverter<double> final {
@@ -179,6 +165,20 @@ struct JSIConverter<std::string> final {
179
165
  }
180
166
  };
181
167
 
168
+ // std::monostate <> void/undefined
169
+ template <>
170
+ struct JSIConverter<std::monostate> final {
171
+ static inline std::monostate fromJSI(jsi::Runtime&, const jsi::Value&) {
172
+ return std::monostate{};
173
+ }
174
+ static inline jsi::Value toJSI(jsi::Runtime&, std::monostate) {
175
+ return jsi::Value();
176
+ }
177
+ static inline bool canConvert(jsi::Runtime&, const jsi::Value&) {
178
+ return true;
179
+ }
180
+ };
181
+
182
182
  } // namespace margelo::nitro
183
183
 
184
184
  #include "JSIConverter+AnyMap.hpp"
@@ -188,6 +188,7 @@ struct JSIConverter<std::string> final {
188
188
  #include "JSIConverter+Function.hpp"
189
189
  #include "JSIConverter+HostObject.hpp"
190
190
  #include "JSIConverter+NativeState.hpp"
191
+ #include "JSIConverter+Null.hpp"
191
192
  #include "JSIConverter+Optional.hpp"
192
193
  #include "JSIConverter+Promise.hpp"
193
194
  #include "JSIConverter+Tuple.hpp"
@@ -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.4"
12
+ #define NITRO_VERSION "0.31.6"
13
13
 
14
14
  // Sets whether to use debug or optimized production build flags
15
15
  #ifdef DEBUG
@@ -287,7 +287,7 @@ extension margelo.nitro.AnyValue {
287
287
  static func create(_ value: AnyValue) -> margelo.nitro.AnyValue {
288
288
  switch value {
289
289
  case .null:
290
- return create()
290
+ return create(NullType.null)
291
291
  case .bool(let bool):
292
292
  return create(bool)
293
293
  case .number(let number):
@@ -302,8 +302,8 @@ extension margelo.nitro.AnyValue {
302
302
  return create(object)
303
303
  }
304
304
  }
305
- static func create() -> margelo.nitro.AnyValue {
306
- return margelo.nitro.AnyMapUtils.create_AnyValue()
305
+ static func create(_ null: NullType) -> margelo.nitro.AnyValue {
306
+ return margelo.nitro.AnyMapUtils.create_AnyValue(margelo.nitro.NullType.null)
307
307
  }
308
308
  static func create(_ value: Bool) -> margelo.nitro.AnyValue {
309
309
  return margelo.nitro.AnyMapUtils.create_AnyValue(value)
@@ -0,0 +1,16 @@
1
+ //
2
+ // Null.swift
3
+ // NitroModules
4
+ //
5
+ // Created by Marc Rousavy on 10.11.25
6
+ //
7
+
8
+ import Foundation
9
+
10
+ @frozen
11
+ public enum NullType: Sendable, Equatable, Hashable {
12
+ /**
13
+ * Represents an explicit `null` from JS.
14
+ */
15
+ case null
16
+ }
@@ -108,6 +108,7 @@ extension Promise {
108
108
  /**
109
109
  * Create a new `Promise<T>` that runs the given `run` function on a parallel Thread/`DispatchQueue`.
110
110
  */
111
+ @preconcurrency
111
112
  public static func parallel(
112
113
  _ queue: DispatchQueue = .global(),
113
114
  _ run: @escaping @Sendable () throws -> T
@@ -125,6 +126,22 @@ extension Promise {
125
126
  }
126
127
  }
127
128
 
129
+ /// Void overloads to avoid typing out `()`
130
+ extension Promise where T == Void {
131
+ /**
132
+ * Resolves this `Promise<Void>`.
133
+ */
134
+ public func resolve() {
135
+ return self.resolve(withResult: ())
136
+ }
137
+ /**
138
+ * Create an already resolved `Promise<Void>`.
139
+ */
140
+ public static func resolved() -> Promise {
141
+ return Self.resolved(withResult: ())
142
+ }
143
+ }
144
+
128
145
  /// Extensions to support then/catch syntax.
129
146
  extension Promise {
130
147
  /**
@@ -19,8 +19,8 @@ using TSharedMap = SharedAnyMap;
19
19
 
20
20
  namespace AnyMapUtils {
21
21
 
22
- inline AnyValue create_AnyValue() {
23
- return AnyValue{std::monostate{}};
22
+ inline AnyValue create_AnyValue(NullType null) {
23
+ return AnyValue{null};
24
24
  }
25
25
  inline AnyValue create_AnyValue(bool boolValue) {
26
26
  return AnyValue{boolValue};
@@ -42,7 +42,7 @@ namespace AnyMapUtils {
42
42
  }
43
43
 
44
44
  inline bool is_AnyValue_null(const AnyValue& value) {
45
- return std::holds_alternative<std::monostate>(value);
45
+ return std::holds_alternative<NullType>(value);
46
46
  }
47
47
  inline bool is_AnyValue_bool(const AnyValue& value) {
48
48
  return std::holds_alternative<bool>(value);
@@ -63,8 +63,8 @@ namespace AnyMapUtils {
63
63
  return std::holds_alternative<AnyObject>(value);
64
64
  }
65
65
 
66
- inline std::monostate get_AnyValue_null(const AnyValue& value) {
67
- return std::get<std::monostate>(value);
66
+ inline NullType get_AnyValue_null(const AnyValue& value) {
67
+ return std::get<NullType>(value);
68
68
  }
69
69
  inline bool get_AnyValue_bool(const AnyValue& value) {
70
70
  return std::get<bool>(value);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-modules",
3
- "version": "0.31.4",
3
+ "version": "0.31.6",
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",