react-native-nitro-modules 0.9.2 → 0.11.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 +2 -0
- package/README.md +4 -4
- package/android/CMakeLists.txt +3 -0
- package/android/build.gradle +26 -2
- package/android/src/main/cpp/JNIOnLoad.cpp +5 -5
- package/android/src/main/cpp/turbomodule/JNitroModules.cpp +39 -0
- package/android/src/main/cpp/turbomodule/JNitroModules.hpp +37 -0
- package/android/src/main/java/com/margelo/nitro/NitroModules.kt +69 -0
- package/android/src/main/java/com/margelo/nitro/NitroModulesPackage.kt +34 -0
- package/android/src/main/java/com/margelo/nitro/core/HybridObject.kt +6 -2
- package/android/src/newarch/NitroModulesSpec.kt +6 -0
- package/android/src/oldarch/NitroModulesSpec.kt +9 -0
- package/cpp/core/BoxedHybridObject.cpp +29 -0
- package/cpp/core/BoxedHybridObject.hpp +36 -0
- package/cpp/core/HybridFunction.hpp +12 -3
- package/cpp/entrypoint/HybridNitroModulesProxy.cpp +55 -0
- package/cpp/entrypoint/HybridNitroModulesProxy.hpp +48 -0
- package/cpp/entrypoint/InstallNitro.cpp +28 -0
- package/cpp/entrypoint/InstallNitro.hpp +41 -0
- package/cpp/jsi/JSIConverter+HostObject.hpp +73 -0
- package/cpp/jsi/JSIConverter+HybridObject.hpp +1 -1
- package/cpp/jsi/JSIConverter.hpp +1 -0
- package/cpp/templates/FutureType.hpp +1 -1
- package/cpp/templates/TypeIndex.hpp +29 -0
- package/cpp/utils/NitroDefines.hpp +5 -0
- package/ios/core/AnyMapHolder.hpp +8 -0
- package/ios/core/AnyMapHolder.swift +65 -39
- package/ios/core/HybridObjectSpec.swift +1 -1
- package/ios/platform/NitroLogger.mm +0 -1
- package/ios/turbomodule/NativeNitroModules+NewArch.mm +67 -0
- package/ios/turbomodule/NativeNitroModules+OldArch.mm +68 -0
- package/ios/turbomodule/NativeNitroModules.h +22 -0
- package/lib/BoxedHybridObject.d.ts +12 -0
- package/lib/BoxedHybridObject.js +1 -0
- package/lib/ModuleNotFoundError.js +3 -13
- package/lib/NitroModules.d.ts +1 -48
- package/lib/NitroModules.js +2 -67
- package/lib/NitroModulesProxy.d.ts +58 -0
- package/lib/NitroModulesProxy.js +1 -0
- package/lib/commonjs/BoxedHybridObject.js +6 -0
- package/lib/commonjs/BoxedHybridObject.js.map +1 -0
- package/lib/commonjs/ModuleNotFoundError.js +3 -15
- package/lib/commonjs/ModuleNotFoundError.js.map +1 -1
- package/lib/commonjs/NitroModules.js +11 -72
- package/lib/commonjs/NitroModules.js.map +1 -1
- package/lib/commonjs/NitroModulesProxy.js +6 -0
- package/lib/commonjs/NitroModulesProxy.js.map +1 -0
- package/lib/commonjs/turbomodule/NativeNitroModules.js +36 -0
- package/lib/commonjs/turbomodule/NativeNitroModules.js.map +1 -0
- package/lib/commonjs/turbomodule/NativeNitroModules.web.js +17 -0
- package/lib/commonjs/turbomodule/NativeNitroModules.web.js.map +1 -0
- package/lib/module/BoxedHybridObject.js +4 -0
- package/lib/module/BoxedHybridObject.js.map +1 -0
- package/lib/module/ModuleNotFoundError.js +3 -15
- package/lib/module/ModuleNotFoundError.js.map +1 -1
- package/lib/module/NitroModules.js +2 -72
- package/lib/module/NitroModules.js.map +1 -1
- package/lib/module/NitroModulesProxy.js +4 -0
- package/lib/module/NitroModulesProxy.js.map +1 -0
- package/lib/module/turbomodule/NativeNitroModules.js +31 -0
- package/lib/module/turbomodule/NativeNitroModules.js.map +1 -0
- package/lib/{NitroModulesTurboModule.web.js → module/turbomodule/NativeNitroModules.web.js} +9 -1
- package/lib/module/turbomodule/NativeNitroModules.web.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/turbomodule/NativeNitroModules.d.ts +7 -0
- package/lib/turbomodule/NativeNitroModules.js +27 -0
- package/lib/turbomodule/NativeNitroModules.web.d.ts +2 -0
- package/lib/turbomodule/NativeNitroModules.web.js +9 -0
- package/lib/typescript/AnyMap.d.ts +20 -0
- package/lib/typescript/BoxedHybridObject.d.ts +13 -0
- package/lib/typescript/BoxedHybridObject.d.ts.map +1 -0
- package/lib/typescript/HybridObject.d.ts +99 -0
- package/lib/typescript/ModuleNotFoundError.d.ts +7 -0
- package/lib/typescript/ModuleNotFoundError.d.ts.map +1 -1
- package/lib/typescript/NitroModules.d.ts +2 -0
- package/lib/typescript/NitroModules.d.ts.map +1 -1
- package/lib/typescript/NitroModulesProxy.d.ts +59 -0
- package/lib/typescript/NitroModulesProxy.d.ts.map +1 -0
- package/lib/typescript/__tests__/index.test.d.ts +1 -0
- package/lib/typescript/index.d.ts +4 -0
- package/lib/typescript/turbomodule/NativeNitroModules.d.ts +8 -0
- package/lib/typescript/turbomodule/NativeNitroModules.d.ts.map +1 -0
- package/lib/typescript/turbomodule/NativeNitroModules.web.d.ts +3 -0
- package/lib/typescript/turbomodule/NativeNitroModules.web.d.ts.map +1 -0
- package/package.json +9 -1
- package/src/BoxedHybridObject.ts +13 -0
- package/src/ModuleNotFoundError.ts +3 -19
- package/src/NitroModules.ts +2 -76
- package/src/NitroModulesProxy.ts +61 -0
- package/src/turbomodule/NativeNitroModules.ts +48 -0
- package/src/turbomodule/NativeNitroModules.web.ts +16 -0
- package/android/src/main/java/com/margelo/nitro/NitroModulesPackage.java +0 -30
- package/cpp/turbomodule/NativeNitroModules.cpp +0 -131
- package/cpp/turbomodule/NativeNitroModules.h +0 -8
- package/cpp/turbomodule/NativeNitroModules.hpp +0 -39
- package/cpp/turbomodule/RegisterNativeNitroModules.cpp +0 -33
- package/cpp/turbomodule/RegisterNativeNitroModules.hpp +0 -21
- package/ios/turbomodule/NitroModuleOnLoad.mm +0 -32
- package/lib/NativeNitroModules.d.ts +0 -17
- package/lib/NativeNitroModules.js +0 -22
- package/lib/NativeNitroModules.web.d.ts +0 -4
- package/lib/NativeNitroModules.web.js +0 -3
- package/lib/NitroModulesTurboModule.d.ts +0 -17
- package/lib/NitroModulesTurboModule.js +0 -23
- package/lib/NitroModulesTurboModule.web.d.ts +0 -1
- package/lib/commonjs/NitroModulesTurboModule.js +0 -34
- package/lib/commonjs/NitroModulesTurboModule.js.map +0 -1
- package/lib/commonjs/NitroModulesTurboModule.web.js +0 -11
- package/lib/commonjs/NitroModulesTurboModule.web.js.map +0 -1
- package/lib/module/NitroModulesTurboModule.js +0 -30
- package/lib/module/NitroModulesTurboModule.js.map +0 -1
- package/lib/module/NitroModulesTurboModule.web.js +0 -7
- package/lib/module/NitroModulesTurboModule.web.js.map +0 -1
- package/lib/typescript/NitroModulesTurboModule.d.ts +0 -18
- package/lib/typescript/NitroModulesTurboModule.d.ts.map +0 -1
- package/lib/typescript/NitroModulesTurboModule.web.d.ts +0 -2
- package/lib/typescript/NitroModulesTurboModule.web.d.ts.map +0 -1
- package/src/NitroModulesTurboModule.ts +0 -49
- package/src/NitroModulesTurboModule.web.ts +0 -7
package/NitroModules.podspec
CHANGED
|
@@ -31,6 +31,8 @@ Pod::Spec.new do |s|
|
|
|
31
31
|
"cpp/core/AnyMap.hpp",
|
|
32
32
|
"cpp/core/ArrayBuffer.hpp",
|
|
33
33
|
"cpp/core/HybridObject.hpp",
|
|
34
|
+
"cpp/entrypoint/HybridNitroModulesProxy.hpp",
|
|
35
|
+
"cpp/entrypoint/InstallNitro.hpp",
|
|
34
36
|
"cpp/registry/HybridObjectRegistry.hpp",
|
|
35
37
|
"cpp/jsi/JSIConverter.hpp",
|
|
36
38
|
"cpp/threading/Dispatcher.hpp",
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<a href="https://margelo.
|
|
1
|
+
<a href="https://margelo.com">
|
|
2
2
|
<picture>
|
|
3
3
|
<source media="(prefers-color-scheme: dark)" srcset="../../docs/static/img/banner-react-native-nitro-modules-dark.png" />
|
|
4
4
|
<source media="(prefers-color-scheme: light)" srcset="../../docs/static/img/banner-react-native-nitro-modules-light.png" />
|
|
@@ -154,8 +154,8 @@ The following C++ / JS types are supported out of the box:
|
|
|
154
154
|
<tr>
|
|
155
155
|
<td><code>A | B | C | ...</code></td>
|
|
156
156
|
<td><code>std::variant<A, B, C, ...></code></td>
|
|
157
|
-
<td><code>Variant_A_B_C</code
|
|
158
|
-
<td
|
|
157
|
+
<td><code>Variant_A_B_C</code></td>
|
|
158
|
+
<td><code>Variant_A_B_C</code></td>
|
|
159
159
|
</tr>
|
|
160
160
|
<tr>
|
|
161
161
|
<td><code>Record<string, T></code></td>
|
|
@@ -190,7 +190,7 @@ The following C++ / JS types are supported out of the box:
|
|
|
190
190
|
<tr>
|
|
191
191
|
<td><code>{ ... }</code></td>
|
|
192
192
|
<td><code>std::shared_ptr<<a href="./cpp/core/AnyMap.hpp">AnyMap</a>></code></td>
|
|
193
|
-
<td><code><a href="./ios/core/AnyMapHolder.swift">AnyMapHolder</a></code
|
|
193
|
+
<td><code><a href="./ios/core/AnyMapHolder.swift">AnyMapHolder</a></code></td>
|
|
194
194
|
<td><code><a href="./android/src/main/java/com/margelo/nitro/core/AnyMap.kt">AnyMap</a></code></td>
|
|
195
195
|
</tr>
|
|
196
196
|
<tr>
|
package/android/CMakeLists.txt
CHANGED
|
@@ -22,6 +22,7 @@ add_library(NitroModules SHARED
|
|
|
22
22
|
include_directories(
|
|
23
23
|
# Shared C++ includes
|
|
24
24
|
../cpp/core
|
|
25
|
+
../cpp/entrypoint
|
|
25
26
|
../cpp/jsi
|
|
26
27
|
../cpp/platform
|
|
27
28
|
../cpp/registry
|
|
@@ -34,6 +35,7 @@ include_directories(
|
|
|
34
35
|
# Android-specific C++ includes
|
|
35
36
|
src/main/cpp/core
|
|
36
37
|
src/main/cpp/registry
|
|
38
|
+
src/main/cpp/turbomodule
|
|
37
39
|
src/main/cpp/platform
|
|
38
40
|
src/main/cpp/utils
|
|
39
41
|
)
|
|
@@ -51,4 +53,5 @@ target_link_libraries(
|
|
|
51
53
|
fbjni::fbjni # <-- Facebook C++ JNI helpers
|
|
52
54
|
ReactAndroid::jsi # <-- RN: JSI
|
|
53
55
|
ReactAndroid::react_nativemodule_core # <-- RN: TurboModules Core
|
|
56
|
+
ReactAndroid::turbomodulejsijni # <-- RN: TurboModules utils (e.g. CallInvokerHolder)
|
|
54
57
|
)
|
package/android/build.gradle
CHANGED
|
@@ -33,6 +33,8 @@ def getExtOrIntegerDefault(name) {
|
|
|
33
33
|
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["Nitro_" + name]).toInteger()
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
logger.info("[NitroModules] Your app is boosted by nitro modules! 🔥")
|
|
37
|
+
|
|
36
38
|
android {
|
|
37
39
|
namespace "com.margelo.nitro"
|
|
38
40
|
|
|
@@ -65,6 +67,26 @@ android {
|
|
|
65
67
|
prefabPublishing true
|
|
66
68
|
}
|
|
67
69
|
|
|
70
|
+
packagingOptions {
|
|
71
|
+
excludes = [
|
|
72
|
+
"META-INF",
|
|
73
|
+
"META-INF/**",
|
|
74
|
+
"**/libc++_shared.so",
|
|
75
|
+
"**/libfbjni.so",
|
|
76
|
+
"**/libjsi.so",
|
|
77
|
+
"**/libfolly_json.so",
|
|
78
|
+
"**/libfolly_runtime.so",
|
|
79
|
+
"**/libglog.so",
|
|
80
|
+
"**/libhermes.so",
|
|
81
|
+
"**/libhermes-executor-debug.so",
|
|
82
|
+
"**/libhermes_executor.so",
|
|
83
|
+
"**/libreactnativejni.so",
|
|
84
|
+
"**/libturbomodulejsijni.so",
|
|
85
|
+
"**/libreact_nativemodule_core.so",
|
|
86
|
+
"**/libjscexecutor.so"
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
|
|
68
90
|
prefab {
|
|
69
91
|
NitroModules {
|
|
70
92
|
headers "${project.buildDir}/headers/nitromodules/"
|
|
@@ -91,8 +113,11 @@ android {
|
|
|
91
113
|
if (isNewArchitectureEnabled()) {
|
|
92
114
|
java.srcDirs += [
|
|
93
115
|
// React Codegen files
|
|
94
|
-
"${project.buildDir}/generated/source/codegen/java"
|
|
116
|
+
"${project.buildDir}/generated/source/codegen/java",
|
|
117
|
+
"src/newarch"
|
|
95
118
|
]
|
|
119
|
+
} else {
|
|
120
|
+
java.srcDirs += ["src/oldarch"]
|
|
96
121
|
}
|
|
97
122
|
}
|
|
98
123
|
}
|
|
@@ -119,7 +144,6 @@ if (isNewArchitectureEnabled()) {
|
|
|
119
144
|
}
|
|
120
145
|
}
|
|
121
146
|
|
|
122
|
-
|
|
123
147
|
task prepareHeaders(type: Copy) {
|
|
124
148
|
from fileTree('./src/main/cpp').filter { it.isFile() }
|
|
125
149
|
from fileTree('../cpp/').filter { it.isFile() }
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
#include "JAnyValue.hpp"
|
|
5
5
|
#include "JArrayBuffer.hpp"
|
|
6
6
|
#include "JHybridObjectRegistry.hpp"
|
|
7
|
+
#include "JNitroModules.hpp"
|
|
7
8
|
#include "JPromise.hpp"
|
|
8
|
-
#include "RegisterNativeNitroModules.hpp"
|
|
9
9
|
#include <fbjni/fbjni.h>
|
|
10
10
|
#include <jni.h>
|
|
11
11
|
|
|
@@ -13,14 +13,14 @@ using namespace margelo::nitro;
|
|
|
13
13
|
|
|
14
14
|
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
|
|
15
15
|
return facebook::jni::initialize(vm, [] {
|
|
16
|
-
// 1. Initialize
|
|
17
|
-
RegisterNativeNitroModules::registerNativeNitroModules();
|
|
18
|
-
|
|
19
|
-
// 2. Initialize all Java bindings
|
|
16
|
+
// 1. Initialize all core Nitro Java bindings
|
|
20
17
|
JHybridObjectRegistry::registerNatives();
|
|
21
18
|
JArrayBuffer::registerNatives();
|
|
22
19
|
JAnyMap::registerNatives();
|
|
23
20
|
JAnyValue::registerNatives();
|
|
24
21
|
JPromise::registerNatives();
|
|
22
|
+
|
|
23
|
+
// 2. Initialize the React Native TurboModule C++ part
|
|
24
|
+
JNitroModules::registerNatives();
|
|
25
25
|
});
|
|
26
26
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Marc Rousavy on 07.10.24.
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
#include "JNitroModules.hpp"
|
|
6
|
+
#include "CallInvokerDispatcher.hpp"
|
|
7
|
+
#include "InstallNitro.hpp"
|
|
8
|
+
|
|
9
|
+
namespace margelo::nitro {
|
|
10
|
+
|
|
11
|
+
JNitroModules::JNitroModules() = default;
|
|
12
|
+
|
|
13
|
+
jni::local_ref<JNitroModules::jhybriddata> JNitroModules::initHybrid(jni::alias_ref<JNitroModules::jhybridobject>) {
|
|
14
|
+
return makeCxxInstance();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
void JNitroModules::install(jlong runtimePointer, jni::alias_ref<react::CallInvokerHolder::javaobject> callInvokerHolder) {
|
|
18
|
+
auto runtime = reinterpret_cast<jsi::Runtime*>(runtimePointer);
|
|
19
|
+
if (runtime == nullptr) {
|
|
20
|
+
throw std::runtime_error("jsi::Runtime was null!");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (callInvokerHolder == nullptr) {
|
|
24
|
+
throw std::runtime_error("CallInvokerHolder was null!");
|
|
25
|
+
}
|
|
26
|
+
auto callInvoker = callInvokerHolder->cthis()->getCallInvoker();
|
|
27
|
+
if (callInvoker == nullptr) {
|
|
28
|
+
throw std::runtime_error("CallInvoker was null!");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
auto dispatcher = std::make_shared<CallInvokerDispatcher>(callInvoker);
|
|
32
|
+
margelo::nitro::install(*runtime, dispatcher);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
void JNitroModules::registerNatives() {
|
|
36
|
+
registerHybrid({makeNativeMethod("initHybrid", JNitroModules::initHybrid), makeNativeMethod("install", JNitroModules::install)});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
} // namespace margelo::nitro
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Marc Rousavy on 07.10.24.
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
#pragma once
|
|
6
|
+
|
|
7
|
+
#include <ReactCommon/CallInvoker.h>
|
|
8
|
+
#include <ReactCommon/CallInvokerHolder.h>
|
|
9
|
+
#include <fbjni/fbjni.h>
|
|
10
|
+
#include <jsi/jsi.h>
|
|
11
|
+
|
|
12
|
+
namespace margelo::nitro {
|
|
13
|
+
|
|
14
|
+
using namespace facebook;
|
|
15
|
+
|
|
16
|
+
class JNitroModules final : public jni::HybridClass<JNitroModules> {
|
|
17
|
+
public:
|
|
18
|
+
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/NitroModules;";
|
|
19
|
+
|
|
20
|
+
private:
|
|
21
|
+
explicit JNitroModules();
|
|
22
|
+
|
|
23
|
+
private:
|
|
24
|
+
// JNI Methods
|
|
25
|
+
static jni::local_ref<JNitroModules::jhybriddata> initHybrid(jni::alias_ref<jhybridobject> javaThis);
|
|
26
|
+
void install(jlong runtimePointer, jni::alias_ref<react::CallInvokerHolder::javaobject> callInvokerHolder);
|
|
27
|
+
|
|
28
|
+
private:
|
|
29
|
+
static auto constexpr TAG = "NitroModules";
|
|
30
|
+
using HybridBase::HybridBase;
|
|
31
|
+
friend HybridBase;
|
|
32
|
+
|
|
33
|
+
public:
|
|
34
|
+
static void registerNatives();
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
} // namespace margelo::nitro
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
package com.margelo.nitro
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.Keep
|
|
4
|
+
import com.facebook.jni.HybridData
|
|
5
|
+
import com.facebook.proguard.annotations.DoNotStrip
|
|
6
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
7
|
+
import com.facebook.react.bridge.ReactMethod
|
|
8
|
+
import com.facebook.react.common.annotations.FrameworkAPI
|
|
9
|
+
import com.facebook.react.turbomodule.core.CallInvokerHolderImpl
|
|
10
|
+
import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder
|
|
11
|
+
|
|
12
|
+
@DoNotStrip
|
|
13
|
+
@Keep
|
|
14
|
+
@OptIn(FrameworkAPI::class)
|
|
15
|
+
@Suppress("KotlinJniMissingFunction")
|
|
16
|
+
class NitroModules internal constructor(val context: ReactApplicationContext) : NitroModulesSpec(context) {
|
|
17
|
+
private val mHybridData: HybridData
|
|
18
|
+
|
|
19
|
+
init {
|
|
20
|
+
mHybridData = initHybrid()
|
|
21
|
+
applicationContext = context
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
override fun getName(): String {
|
|
25
|
+
return NAME
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
29
|
+
override fun install(): String? {
|
|
30
|
+
try {
|
|
31
|
+
// 1. Get jsi::Runtime pointer
|
|
32
|
+
val jsContext = context.javaScriptContextHolder
|
|
33
|
+
?: return "ReactApplicationContext.javaScriptContextHolder is null!"
|
|
34
|
+
|
|
35
|
+
// 2. Get CallInvokerHolder
|
|
36
|
+
val callInvokerHolder = context.jsCallInvokerHolder as? CallInvokerHolderImpl
|
|
37
|
+
?: return "ReactApplicationContext.jsCallInvokerHolder is null!"
|
|
38
|
+
|
|
39
|
+
// 3. Install Nitro
|
|
40
|
+
install(jsContext.get(), callInvokerHolder)
|
|
41
|
+
|
|
42
|
+
return null
|
|
43
|
+
} catch (e: Throwable) {
|
|
44
|
+
// ?. Something went wrong! Maybe a JNI error?
|
|
45
|
+
return e.message
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private external fun initHybrid(): HybridData
|
|
50
|
+
private external fun install(jsRuntimePointer: Long, callInvokerHolder: CallInvokerHolderImpl)
|
|
51
|
+
|
|
52
|
+
companion object {
|
|
53
|
+
/**
|
|
54
|
+
* The TurboModule's name.
|
|
55
|
+
*/
|
|
56
|
+
const val NAME = "NitroModules"
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Get the current `ReactApplicationContext`, or `null` if none is available.
|
|
60
|
+
*/
|
|
61
|
+
@JvmStatic
|
|
62
|
+
var applicationContext: ReactApplicationContext? = null
|
|
63
|
+
|
|
64
|
+
init {
|
|
65
|
+
// Make sure Nitro's C++ library is loaded
|
|
66
|
+
JNIOnLoad.initializeNativeNitro()
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
package com.margelo.nitro
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.TurboReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.module.model.ReactModuleInfo
|
|
7
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
8
|
+
|
|
9
|
+
class NitroModulesPackage : TurboReactPackage() {
|
|
10
|
+
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
|
|
11
|
+
return if (name == NitroModules.NAME) {
|
|
12
|
+
NitroModules(reactContext)
|
|
13
|
+
} else {
|
|
14
|
+
null
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
|
|
19
|
+
return ReactModuleInfoProvider {
|
|
20
|
+
val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
|
|
21
|
+
val isTurboModule: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
|
|
22
|
+
moduleInfos[NitroModules.NAME] = ReactModuleInfo(
|
|
23
|
+
NitroModules.NAME,
|
|
24
|
+
NitroModules.NAME,
|
|
25
|
+
canOverrideExistingModule = false,
|
|
26
|
+
needsEagerInit = false,
|
|
27
|
+
hasConstants = false,
|
|
28
|
+
isCxxModule = false,
|
|
29
|
+
isTurboModule = isTurboModule
|
|
30
|
+
)
|
|
31
|
+
moduleInfos
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -4,12 +4,16 @@ import androidx.annotation.Keep
|
|
|
4
4
|
import com.facebook.jni.HybridData
|
|
5
5
|
import com.facebook.proguard.annotations.DoNotStrip
|
|
6
6
|
|
|
7
|
+
interface ExtendableHybridClass {
|
|
8
|
+
fun updateNative(hybridData: HybridData)
|
|
9
|
+
}
|
|
10
|
+
|
|
7
11
|
/**
|
|
8
12
|
* A base class for all Kotlin-based HybridObjects.
|
|
9
13
|
*/
|
|
10
14
|
@Keep
|
|
11
15
|
@DoNotStrip
|
|
12
|
-
abstract class HybridObject {
|
|
16
|
+
abstract class HybridObject: ExtendableHybridClass {
|
|
13
17
|
/**
|
|
14
18
|
* Get the memory size of the Kotlin instance (plus any external heap allocations),
|
|
15
19
|
* in bytes.
|
|
@@ -41,7 +45,7 @@ abstract class HybridObject {
|
|
|
41
45
|
* Must be called in the constructor of a subclass of `HybridObject`, to initialize the C++
|
|
42
46
|
* `JHybridObject` with a subclass of it.
|
|
43
47
|
*/
|
|
44
|
-
|
|
48
|
+
override fun updateNative(hybridData: HybridData) {
|
|
45
49
|
mHybridData = hybridData
|
|
46
50
|
}
|
|
47
51
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
package com.margelo.nitro
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
4
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
5
|
+
import com.facebook.react.bridge.Promise
|
|
6
|
+
|
|
7
|
+
abstract class NitroModulesSpec internal constructor(context: ReactApplicationContext) : ReactContextBaseJavaModule(context) {
|
|
8
|
+
abstract fun install(): String?
|
|
9
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//
|
|
2
|
+
// BoxedHybridObject.cpp
|
|
3
|
+
// NitroModules
|
|
4
|
+
//
|
|
5
|
+
// Created by Marc Rousavy on 17.09.24.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#include "BoxedHybridObject.hpp"
|
|
9
|
+
|
|
10
|
+
namespace margelo::nitro {
|
|
11
|
+
|
|
12
|
+
std::vector<jsi::PropNameID> BoxedHybridObject::getPropertyNames(facebook::jsi::Runtime& runtime) {
|
|
13
|
+
return jsi::PropNameID::names(runtime, "unbox");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
jsi::Value BoxedHybridObject::get(jsi::Runtime& runtime, const jsi::PropNameID& propName) {
|
|
17
|
+
std::string name = propName.utf8(runtime);
|
|
18
|
+
|
|
19
|
+
if (name == "unbox") {
|
|
20
|
+
return jsi::Function::createFromHostFunction(
|
|
21
|
+
runtime, jsi::PropNameID::forUtf8(runtime, "unbox"), 0,
|
|
22
|
+
[hybridObject = _hybridObject](jsi::Runtime& runtime, const jsi::Value& thisArg, const jsi::Value* args,
|
|
23
|
+
size_t count) -> jsi::Value { return hybridObject->toObject(runtime); });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return jsi::Value::undefined();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
} // namespace margelo::nitro
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Marc Rousavy on 21.02.24.
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
#pragma once
|
|
6
|
+
|
|
7
|
+
#include "HybridObject.hpp"
|
|
8
|
+
#include <jsi/jsi.h>
|
|
9
|
+
#include <memory>
|
|
10
|
+
|
|
11
|
+
namespace margelo::nitro {
|
|
12
|
+
|
|
13
|
+
using namespace facebook;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Represents a `HybridObject` that has been boxed into a `jsi::HostObject`.
|
|
17
|
+
*
|
|
18
|
+
* While `HybridObject`s are runtime agnostic, some threading/worklet libraries do not support copying over objects
|
|
19
|
+
* with `jsi::NativeState` and a prototype chain (which is what a `HybridObject` is), so Nitro offers support for
|
|
20
|
+
* boxing those `HybridObject`s into a type that those libraries support - which is a `jsi::HostObject`.
|
|
21
|
+
*
|
|
22
|
+
* Simply call `unbox()` on this `jsi::HostObject` from the new Runtime/context to get the `HybridObject` again.
|
|
23
|
+
*/
|
|
24
|
+
class BoxedHybridObject : public jsi::HostObject {
|
|
25
|
+
public:
|
|
26
|
+
explicit BoxedHybridObject(const std::shared_ptr<HybridObject>& hybridObject) : _hybridObject(hybridObject) {}
|
|
27
|
+
|
|
28
|
+
public:
|
|
29
|
+
jsi::Value get(jsi::Runtime& runtime, const jsi::PropNameID& propName) override;
|
|
30
|
+
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& runtime) override;
|
|
31
|
+
|
|
32
|
+
private:
|
|
33
|
+
std::shared_ptr<HybridObject> _hybridObject;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
} // namespace margelo::nitro
|
|
@@ -173,7 +173,14 @@ private:
|
|
|
173
173
|
// 1. Convert jsi::Value to jsi::Object
|
|
174
174
|
#ifdef NITRO_DEBUG
|
|
175
175
|
if (!value.isObject()) [[unlikely]] {
|
|
176
|
-
throw jsi::JSError(runtime, "Cannot " + getHybridFuncDebugInfo<THybrid>(funcKind, funcName) +
|
|
176
|
+
throw jsi::JSError(runtime, "Cannot " + getHybridFuncDebugInfo<THybrid>(funcKind, funcName) +
|
|
177
|
+
" - `this` is not bound! Suggestions:\n"
|
|
178
|
+
"- Did you accidentally destructure the `HybridObject`? (`const { " +
|
|
179
|
+
funcName +
|
|
180
|
+
" } = ...`)\n"
|
|
181
|
+
"- Did you call `dispose()` on the `HybridObject` before?"
|
|
182
|
+
"- Did you accidentally call `" +
|
|
183
|
+
funcName + "` on the prototype directly?");
|
|
177
184
|
}
|
|
178
185
|
#endif
|
|
179
186
|
jsi::Object object = value.getObject(runtime);
|
|
@@ -183,10 +190,12 @@ private:
|
|
|
183
190
|
if (!object.hasNativeState(runtime)) [[unlikely]] {
|
|
184
191
|
throw jsi::JSError(runtime, "Cannot " + getHybridFuncDebugInfo<THybrid>(funcKind, funcName) +
|
|
185
192
|
" - `this` does not have a NativeState! Suggestions:\n"
|
|
186
|
-
"- Did you accidentally destructure the `HybridObject`
|
|
193
|
+
"- Did you accidentally destructure the `HybridObject`? (`const { " +
|
|
194
|
+
funcName +
|
|
195
|
+
" } = ...`)\n"
|
|
187
196
|
"- Did you call `dispose()` on the `HybridObject` before?"
|
|
188
197
|
"- Did you accidentally call `" +
|
|
189
|
-
funcName + "` on the prototype directly
|
|
198
|
+
funcName + "` on the prototype directly?");
|
|
190
199
|
}
|
|
191
200
|
#endif
|
|
192
201
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
//
|
|
2
|
+
// HybridNitroModulesProxy.hpp
|
|
3
|
+
// NitroModules
|
|
4
|
+
//
|
|
5
|
+
// Created by Marc Rousavy on 05.10.24
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#include "HybridNitroModulesProxy.hpp"
|
|
9
|
+
#include "HybridObjectRegistry.hpp"
|
|
10
|
+
#include "NitroDefines.hpp"
|
|
11
|
+
|
|
12
|
+
namespace margelo::nitro {
|
|
13
|
+
|
|
14
|
+
void HybridNitroModulesProxy::loadHybridMethods() {
|
|
15
|
+
HybridObject::loadHybridMethods();
|
|
16
|
+
|
|
17
|
+
registerHybrids(this, [](Prototype& prototype) {
|
|
18
|
+
prototype.registerHybridMethod("createHybridObject", &HybridNitroModulesProxy::createHybridObject);
|
|
19
|
+
prototype.registerHybridMethod("hasHybridObject", &HybridNitroModulesProxy::hasHybridObject);
|
|
20
|
+
prototype.registerHybridMethod("getAllHybridObjectNames", &HybridNitroModulesProxy::getAllHybridObjectNames);
|
|
21
|
+
|
|
22
|
+
prototype.registerHybridMethod("box", &HybridNitroModulesProxy::box);
|
|
23
|
+
|
|
24
|
+
prototype.registerHybridGetter("buildType", &HybridNitroModulesProxy::getBuildType);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Hybrid Object Registry
|
|
29
|
+
std::shared_ptr<HybridObject> HybridNitroModulesProxy::createHybridObject(const std::string& name) {
|
|
30
|
+
return HybridObjectRegistry::createHybridObject(name);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
bool HybridNitroModulesProxy::hasHybridObject(const std::string& name) {
|
|
34
|
+
return HybridObjectRegistry::hasHybridObject(name);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
std::vector<std::string> HybridNitroModulesProxy::getAllHybridObjectNames() {
|
|
38
|
+
return HybridObjectRegistry::getAllHybridObjectNames();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Helpers
|
|
42
|
+
std::shared_ptr<BoxedHybridObject> HybridNitroModulesProxy::box(const std::shared_ptr<HybridObject>& hybridObject) {
|
|
43
|
+
return std::make_shared<BoxedHybridObject>(hybridObject);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Build Info
|
|
47
|
+
std::string HybridNitroModulesProxy::getBuildType() {
|
|
48
|
+
#ifdef NITRO_DEBUG
|
|
49
|
+
return "debug";
|
|
50
|
+
#else
|
|
51
|
+
return "release";
|
|
52
|
+
#endif
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
} // namespace margelo::nitro
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//
|
|
2
|
+
// HybridNitroModulesProxy.hpp
|
|
3
|
+
// NitroModules
|
|
4
|
+
//
|
|
5
|
+
// Created by Marc Rousavy on 05.10.24
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include "BoxedHybridObject.hpp"
|
|
11
|
+
#include "HybridObject.hpp"
|
|
12
|
+
#include <memory>
|
|
13
|
+
#include <string>
|
|
14
|
+
|
|
15
|
+
namespace margelo::nitro {
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Represents the entry point for all other HybridObjects.
|
|
19
|
+
* The flow is as following:
|
|
20
|
+
* 1. (optional) Install a Dispatcher in `jsi::Runtime` to use async/callbacks.
|
|
21
|
+
* 2. Create an instance of `HybridNitroModulesProxy`
|
|
22
|
+
* 3. Pass the object from `.toObject()` it to JS (either install in global, or return somehow)
|
|
23
|
+
* 4. From JS, you can access methods on this HybridObject to create all other HybridObjects.
|
|
24
|
+
*/
|
|
25
|
+
class HybridNitroModulesProxy : public HybridObject {
|
|
26
|
+
public:
|
|
27
|
+
explicit HybridNitroModulesProxy() : HybridObject(TAG) {}
|
|
28
|
+
|
|
29
|
+
public:
|
|
30
|
+
void loadHybridMethods() override;
|
|
31
|
+
|
|
32
|
+
public:
|
|
33
|
+
// Hybrid Object Registry
|
|
34
|
+
std::shared_ptr<HybridObject> createHybridObject(const std::string& name);
|
|
35
|
+
bool hasHybridObject(const std::string& name);
|
|
36
|
+
std::vector<std::string> getAllHybridObjectNames();
|
|
37
|
+
|
|
38
|
+
// Helpers
|
|
39
|
+
std::shared_ptr<BoxedHybridObject> box(const std::shared_ptr<HybridObject>& hybridObject);
|
|
40
|
+
|
|
41
|
+
// Build Info
|
|
42
|
+
std::string getBuildType();
|
|
43
|
+
|
|
44
|
+
private:
|
|
45
|
+
static constexpr auto TAG = "NitroModulesProxy";
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
} // namespace margelo::nitro
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//
|
|
2
|
+
// InstallNitro.cpp
|
|
3
|
+
// NitroModules
|
|
4
|
+
//
|
|
5
|
+
// Created by Marc Rousavy on 05.10.24
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#include "InstallNitro.hpp"
|
|
9
|
+
#include "HybridNitroModulesProxy.hpp"
|
|
10
|
+
|
|
11
|
+
namespace margelo::nitro {
|
|
12
|
+
|
|
13
|
+
void install(jsi::Runtime& runtime, std::shared_ptr<Dispatcher> dispatcher) {
|
|
14
|
+
// Registers a Dispatcher for Nitro to call back into the JS Runtime.
|
|
15
|
+
// This allows creating Promises and calling back to JS.
|
|
16
|
+
Dispatcher::installRuntimeGlobalDispatcher(runtime, dispatcher);
|
|
17
|
+
|
|
18
|
+
// Installs NitroModulesProxy itself into the Runtime's global.
|
|
19
|
+
install(runtime);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
void install(jsi::Runtime& runtime) {
|
|
23
|
+
// Installs global.NitroModulesProxy
|
|
24
|
+
auto proxy = std::make_shared<HybridNitroModulesProxy>();
|
|
25
|
+
runtime.global().setProperty(runtime, "NitroModulesProxy", proxy->toObject(runtime));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
} // namespace margelo::nitro
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//
|
|
2
|
+
// InstallNitro.hpp
|
|
3
|
+
// NitroModules
|
|
4
|
+
//
|
|
5
|
+
// Created by Marc Rousavy on 05.10.24
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include "Dispatcher.hpp"
|
|
11
|
+
#include <jsi/jsi.h>
|
|
12
|
+
#include <memory>
|
|
13
|
+
|
|
14
|
+
namespace margelo::nitro {
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Installs Nitro into the given JS `runtime`.
|
|
18
|
+
* This will create `global.NitroModulesProxy`, Nitro's entry-point,
|
|
19
|
+
* which can be used to create all registered HybridObjects from JS.
|
|
20
|
+
*
|
|
21
|
+
* Also registers the given `dispatcher` which allows using callbacks,
|
|
22
|
+
* and async code (Promises).
|
|
23
|
+
* The `dispatcher` needs to implement `runAsync`/`runSync` to run
|
|
24
|
+
* methods on whatever Thread can safely access `runtime`.
|
|
25
|
+
* In a non-thread-safe Runtime, it needs to be a single Thread (e.g.
|
|
26
|
+
* React's `CallInvoker`), but in a thread-safe Runtime it might just be
|
|
27
|
+
* an implementation that runs the method directly.
|
|
28
|
+
*/
|
|
29
|
+
void install(jsi::Runtime& runtime, std::shared_ptr<Dispatcher> dispatcher);
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Installs Nitro into the given JS `runtime`.
|
|
33
|
+
* This will create `global.NitroModulesProxy`, Nitro's entry-point,
|
|
34
|
+
* which can be used to create all registered HybridObjects from JS.
|
|
35
|
+
*
|
|
36
|
+
* No `Dispatcher` will be installed, meaning Nitro can only use synchronous
|
|
37
|
+
* methods.
|
|
38
|
+
*/
|
|
39
|
+
void install(jsi::Runtime& runtime);
|
|
40
|
+
|
|
41
|
+
} // namespace margelo::nitro
|