react-native-nitro-modules 0.10.0 → 0.12.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 +4 -0
- package/README.md +2 -2
- package/android/CMakeLists.txt +3 -0
- package/android/build.gradle +27 -3
- package/android/src/main/cpp/JNIOnLoad.cpp +5 -5
- package/android/src/main/cpp/platform/NitroLogger.cpp +1 -1
- package/android/src/main/cpp/turbomodule/JNitroModules.cpp +41 -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/HybridFunction.hpp +13 -4
- 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+ArrayBuffer.hpp +6 -6
- package/cpp/jsi/JSIConverter+HostObject.hpp +73 -0
- package/cpp/jsi/JSIConverter+HybridObject.hpp +1 -1
- package/cpp/jsi/JSIConverter+Promise.hpp +1 -0
- package/cpp/jsi/JSIConverter+Tuple.hpp +2 -2
- package/cpp/jsi/JSIConverter.hpp +1 -0
- package/cpp/prototype/HybridObjectPrototype.cpp +4 -3
- package/cpp/threading/CallInvokerDispatcher.hpp +5 -0
- package/cpp/utils/NitroDefines.hpp +8 -0
- package/cpp/utils/TypeInfo.hpp +40 -20
- package/ios/core/ArrayBufferHolder.hpp +1 -1
- package/ios/core/HybridObjectSpec.swift +1 -1
- package/ios/platform/NitroLogger.mm +1 -2
- package/ios/turbomodule/NativeNitroModules+NewArch.mm +67 -0
- package/ios/turbomodule/NativeNitroModules+OldArch.mm +71 -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 -83
- package/lib/NitroModules.js +2 -94
- 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 -100
- 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 -100
- 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/ModuleNotFoundError.d.ts +7 -0
- package/lib/typescript/ModuleNotFoundError.d.ts.map +1 -1
- package/lib/typescript/NitroModules.d.ts +1 -83
- 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 +10 -3
- package/src/BoxedHybridObject.ts +13 -0
- package/src/ModuleNotFoundError.ts +3 -19
- package/src/NitroModules.ts +2 -108
- 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 -146
- package/cpp/turbomodule/NativeNitroModules.h +0 -8
- package/cpp/turbomodule/NativeNitroModules.hpp +0 -38
- 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 -16
- 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 -18
- 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 -19
- 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 -50
- 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",
|
|
@@ -49,6 +51,8 @@ Pod::Spec.new do |s|
|
|
|
49
51
|
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
|
|
50
52
|
# Enables C++ <-> Swift interop (by default it's only C)
|
|
51
53
|
"SWIFT_OBJC_INTEROP_MODE" => "objcxx",
|
|
54
|
+
# Enables stricter modular headers
|
|
55
|
+
"DEFINES_MODULE" => "YES",
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
install_modules_dependencies(s)
|
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" />
|
|
@@ -203,7 +203,7 @@ The following C++ / JS types are supported out of the box:
|
|
|
203
203
|
<td>..any <code><a href="./src/HybridObject.ts">HybridObject</a></code></td>
|
|
204
204
|
<td><code>std::shared_ptr<<a href="./cpp/core/HybridObject.hpp">HybridObject</a>></code></td>
|
|
205
205
|
<td><code><a href="./ios/core/HybridObjectSpec.swift">HybridObjectSpec</a></code></td>
|
|
206
|
-
<td><code><a href="./android/core/HybridObject.kt">HybridObject</a></code></td>
|
|
206
|
+
<td><code><a href="./android/src/main/java/com/margelo/nitro/core/HybridObject.kt">HybridObject</a></code></td>
|
|
207
207
|
</tr>
|
|
208
208
|
<tr>
|
|
209
209
|
<td>..any <code>interface</code></td>
|
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
|
@@ -5,7 +5,7 @@ buildscript {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
dependencies {
|
|
8
|
-
classpath "com.android.tools.build:gradle:7.
|
|
8
|
+
classpath "com.android.tools.build:gradle:8.7.1"
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -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.warn("[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,41 @@
|
|
|
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
|
+
#include <exception>
|
|
10
|
+
|
|
11
|
+
namespace margelo::nitro {
|
|
12
|
+
|
|
13
|
+
JNitroModules::JNitroModules() = default;
|
|
14
|
+
|
|
15
|
+
jni::local_ref<JNitroModules::jhybriddata> JNitroModules::initHybrid(jni::alias_ref<JNitroModules::jhybridobject>) {
|
|
16
|
+
return makeCxxInstance();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
void JNitroModules::install(jlong runtimePointer, jni::alias_ref<react::CallInvokerHolder::javaobject> callInvokerHolder) {
|
|
20
|
+
auto runtime = reinterpret_cast<jsi::Runtime*>(runtimePointer);
|
|
21
|
+
if (runtime == nullptr) {
|
|
22
|
+
throw std::invalid_argument("jsi::Runtime was null!");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (callInvokerHolder == nullptr) {
|
|
26
|
+
throw std::invalid_argument("CallInvokerHolder was null!");
|
|
27
|
+
}
|
|
28
|
+
auto callInvoker = callInvokerHolder->cthis()->getCallInvoker();
|
|
29
|
+
if (callInvoker == nullptr) {
|
|
30
|
+
throw std::invalid_argument("CallInvoker was null!");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
auto dispatcher = std::make_shared<CallInvokerDispatcher>(callInvoker);
|
|
34
|
+
margelo::nitro::install(*runtime, dispatcher);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
void JNitroModules::registerNatives() {
|
|
38
|
+
registerHybrid({makeNativeMethod("initHybrid", JNitroModules::initHybrid), makeNativeMethod("install", JNitroModules::install)});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
} // 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
|
+
}
|
|
@@ -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
|
|
|
@@ -215,7 +224,7 @@ private:
|
|
|
215
224
|
template <typename THybrid>
|
|
216
225
|
static inline std::string getHybridFuncFullName(FunctionKind kind, const std::string& registrationName,
|
|
217
226
|
THybrid* hybridInstance = nullptr) {
|
|
218
|
-
std::string typeName = hybridInstance != nullptr ? hybridInstance->getName() : TypeInfo::
|
|
227
|
+
std::string typeName = hybridInstance != nullptr ? hybridInstance->getName() : TypeInfo::getFriendlyTypename<THybrid>(true);
|
|
219
228
|
switch (kind) {
|
|
220
229
|
case FunctionKind::METHOD:
|
|
221
230
|
return typeName + "." + registrationName + "(...)";
|
|
@@ -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
|
|
@@ -33,18 +33,18 @@ struct JSIConverter<T, std::enable_if_t<is_shared_ptr_to_v<T, jsi::MutableBuffer
|
|
|
33
33
|
static inline std::shared_ptr<ArrayBuffer> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
34
34
|
#ifdef NITRO_DEBUG
|
|
35
35
|
if (!arg.isObject()) [[unlikely]] {
|
|
36
|
-
throw std::
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
throw std::invalid_argument("Value \"" + arg.toString(runtime).utf8(runtime) +
|
|
37
|
+
"\" is not an ArrayBuffer - "
|
|
38
|
+
"in fact, it's not even an object!");
|
|
39
39
|
}
|
|
40
40
|
#endif
|
|
41
41
|
|
|
42
42
|
jsi::Object object = arg.asObject(runtime);
|
|
43
43
|
#ifdef NITRO_DEBUG
|
|
44
44
|
if (!object.isArrayBuffer(runtime)) [[unlikely]] {
|
|
45
|
-
throw std::
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
throw std::invalid_argument("Object \"" + arg.toString(runtime).utf8(runtime) +
|
|
46
|
+
"\" is not an ArrayBuffer! "
|
|
47
|
+
"Are you maybe passing a TypedArray (e.g. Uint8Array)? Try to pass it's `.buffer` value.");
|
|
48
48
|
}
|
|
49
49
|
#endif
|
|
50
50
|
|