react-native-nitro-modules 0.10.0 → 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 +1 -1
- 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/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/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 -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 +9 -1
- 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",
|
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" />
|
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
|
+
}
|
|
@@ -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
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Created by Marc Rousavy on 07.10.24.
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
#pragma once
|
|
6
|
+
|
|
7
|
+
#include "IsSharedPtrTo.hpp"
|
|
8
|
+
#include "NitroDefines.hpp"
|
|
9
|
+
#include "TypeInfo.hpp"
|
|
10
|
+
#include <jsi/jsi.h>
|
|
11
|
+
#include <type_traits>
|
|
12
|
+
|
|
13
|
+
namespace margelo::nitro {
|
|
14
|
+
|
|
15
|
+
using namespace facebook;
|
|
16
|
+
|
|
17
|
+
// jsi::HostObject <> {}
|
|
18
|
+
template <typename T>
|
|
19
|
+
struct JSIConverter<T, std::enable_if_t<is_shared_ptr_to_v<T, jsi::HostObject>>> final {
|
|
20
|
+
using TPointee = typename T::element_type;
|
|
21
|
+
|
|
22
|
+
static inline T fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
23
|
+
#ifdef NITRO_DEBUG
|
|
24
|
+
if (!arg.isObject()) [[unlikely]] {
|
|
25
|
+
if (arg.isUndefined()) [[unlikely]] {
|
|
26
|
+
throw jsi::JSError(runtime, invalidTypeErrorMessage("undefined", "It is undefined!"));
|
|
27
|
+
} else {
|
|
28
|
+
std::string stringRepresentation = arg.toString(runtime).utf8(runtime);
|
|
29
|
+
throw jsi::JSError(runtime, invalidTypeErrorMessage(stringRepresentation, "It is not an object!"));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
#endif
|
|
33
|
+
jsi::Object object = arg.asObject(runtime);
|
|
34
|
+
|
|
35
|
+
#ifdef NITRO_DEBUG
|
|
36
|
+
if (!object.isHostObject<TPointee>(runtime)) [[unlikely]] {
|
|
37
|
+
if (!object.isHostObject(runtime)) [[unlikely]] {
|
|
38
|
+
std::string stringRepresentation = arg.toString(runtime).utf8(runtime);
|
|
39
|
+
throw jsi::JSError(runtime, invalidTypeErrorMessage(stringRepresentation, "It is not a HostObject at all!"));
|
|
40
|
+
} else {
|
|
41
|
+
std::string stringRepresentation = arg.toString(runtime).utf8(runtime);
|
|
42
|
+
throw jsi::JSError(runtime, invalidTypeErrorMessage(stringRepresentation, "It is a different HostObject<T>!"));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
#endif
|
|
46
|
+
return object.getHostObject<TPointee>(runtime);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const T& arg) {
|
|
50
|
+
if (arg == nullptr) [[unlikely]] {
|
|
51
|
+
std::string typeName = TypeInfo::getFriendlyTypename<TPointee>();
|
|
52
|
+
throw jsi::JSError(runtime, "Cannot convert nullptr to HostObject<" + typeName + ">!");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return jsi::Object::createFromHostObject(runtime, arg);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
59
|
+
if (value.isObject()) {
|
|
60
|
+
jsi::Object object = value.getObject(runtime);
|
|
61
|
+
return object.isHostObject<TPointee>(runtime);
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private:
|
|
67
|
+
static std::string invalidTypeErrorMessage(const std::string& typeDescription, const std::string& reason) {
|
|
68
|
+
std::string typeName = TypeInfo::getFriendlyTypename<TPointee>();
|
|
69
|
+
return "Cannot convert \"" + typeDescription + "\" to HostObject<" + typeName + ">! " + reason;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
} // namespace margelo::nitro
|
|
@@ -78,7 +78,7 @@ struct JSIConverter<T, std::enable_if_t<is_shared_ptr_to_v<T, jsi::NativeState>>
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
private:
|
|
81
|
-
static
|
|
81
|
+
static std::string invalidTypeErrorMessage(const std::string& typeDescription, const std::string& reason) {
|
|
82
82
|
std::string typeName = TypeInfo::getFriendlyTypename<TPointee>();
|
|
83
83
|
return "Cannot convert \"" + typeDescription + "\" to NativeState<" + typeName + ">! " + reason;
|
|
84
84
|
}
|
package/cpp/jsi/JSIConverter.hpp
CHANGED
|
@@ -184,6 +184,7 @@ struct JSIConverter<std::string> final {
|
|
|
184
184
|
#include "JSIConverter+AnyMap.hpp"
|
|
185
185
|
#include "JSIConverter+ArrayBuffer.hpp"
|
|
186
186
|
#include "JSIConverter+Function.hpp"
|
|
187
|
+
#include "JSIConverter+HostObject.hpp"
|
|
187
188
|
#include "JSIConverter+HybridObject.hpp"
|
|
188
189
|
#include "JSIConverter+Optional.hpp"
|
|
189
190
|
#include "JSIConverter+Promise.hpp"
|
|
@@ -10,7 +10,7 @@ import Foundation
|
|
|
10
10
|
/**
|
|
11
11
|
* A base protocol for all Swift-based Hybrid Objects.
|
|
12
12
|
*/
|
|
13
|
-
public protocol HybridObjectSpec {
|
|
13
|
+
public protocol HybridObjectSpec: AnyObject {
|
|
14
14
|
/**
|
|
15
15
|
* Holds the C++ HybridObject and it's context.
|
|
16
16
|
* Use the default initializer in your implementation, C++ will set and get this value.
|