expo-modules-core 0.9.0 → 0.10.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/CHANGELOG.md +25 -0
- package/android/CMakeLists.txt +154 -0
- package/android/build.gradle +293 -5
- package/android/src/main/cpp/Exceptions.cpp +22 -0
- package/android/src/main/cpp/Exceptions.h +38 -0
- package/android/src/main/cpp/ExpoModulesHostObject.cpp +47 -0
- package/android/src/main/cpp/ExpoModulesHostObject.h +32 -0
- package/android/src/main/cpp/JNIFunctionBody.cpp +29 -0
- package/android/src/main/cpp/JNIFunctionBody.h +50 -0
- package/android/src/main/cpp/JNIInjector.cpp +19 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +122 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.h +96 -0
- package/android/src/main/cpp/JSIObjectWrapper.h +33 -0
- package/android/src/main/cpp/JSITypeConverter.h +84 -0
- package/android/src/main/cpp/JavaScriptModuleObject.cpp +138 -0
- package/android/src/main/cpp/JavaScriptModuleObject.h +122 -0
- package/android/src/main/cpp/JavaScriptObject.cpp +125 -0
- package/android/src/main/cpp/JavaScriptObject.h +131 -0
- package/android/src/main/cpp/JavaScriptRuntime.cpp +127 -0
- package/android/src/main/cpp/JavaScriptRuntime.h +87 -0
- package/android/src/main/cpp/JavaScriptValue.cpp +172 -0
- package/android/src/main/cpp/JavaScriptValue.h +78 -0
- package/android/src/main/cpp/MethodMetadata.cpp +230 -0
- package/android/src/main/cpp/MethodMetadata.h +92 -0
- package/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java +2 -0
- package/android/src/main/java/expo/modules/core/errors/ContextDestroyedException.kt +7 -0
- package/android/src/main/java/expo/modules/interfaces/permissions/Permissions.java +30 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +49 -1
- package/android/src/main/java/expo/modules/kotlin/ConcatIterator.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +15 -12
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +39 -3
- package/android/src/main/java/expo/modules/kotlin/defaultmodules/ErrorManagerModule.kt +2 -2
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +13 -0
- package/android/src/main/java/expo/modules/kotlin/exception/ExceptionDecorator.kt +2 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +19 -14
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +29 -7
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +13 -13
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +56 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +28 -0
- package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JNIFunctionBody.kt +39 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +89 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +44 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +113 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +35 -0
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +15 -5
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +65 -111
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +35 -2
- package/android/src/main/java/expo/modules/kotlin/providers/AppContextProvider.kt +14 -0
- package/android/src/main/java/expo/modules/kotlin/providers/CurrentActivityProvider.kt +22 -0
- package/android/src/main/java/expo/modules/kotlin/records/RecordTypeConverter.kt +19 -2
- package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/types/ArrayTypeConverter.kt +7 -2
- package/android/src/main/java/expo/modules/kotlin/types/BasicTypeConverters.kt +68 -20
- package/android/src/main/java/expo/modules/kotlin/types/EnumTypeConverter.kt +50 -22
- package/android/src/main/java/expo/modules/kotlin/types/ListTypeConverter.kt +18 -2
- package/android/src/main/java/expo/modules/kotlin/types/MapTypeConverter.kt +18 -2
- package/android/src/main/java/expo/modules/kotlin/types/PairTypeConverter.kt +17 -2
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +43 -3
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +5 -0
- package/build/NativeModulesProxy.native.d.ts.map +1 -1
- package/build/NativeModulesProxy.native.js +9 -3
- package/build/NativeModulesProxy.native.js.map +1 -1
- package/ios/AppDelegates/EXAppDelegatesLoader.m +1 -2
- package/ios/ExpoModulesCore.podspec +1 -1
- package/ios/JSI/EXJSIConversions.mm +6 -0
- package/ios/JSI/EXJSIInstaller.h +15 -21
- package/ios/JSI/EXJSIInstaller.mm +39 -3
- package/ios/JSI/EXJSIUtils.h +47 -3
- package/ios/JSI/EXJSIUtils.mm +88 -4
- package/ios/JSI/EXJavaScriptObject.h +11 -18
- package/ios/JSI/EXJavaScriptObject.mm +37 -18
- package/ios/JSI/EXJavaScriptRuntime.h +43 -9
- package/ios/JSI/EXJavaScriptRuntime.mm +70 -27
- package/ios/JSI/EXJavaScriptTypedArray.h +30 -0
- package/ios/JSI/EXJavaScriptTypedArray.mm +29 -0
- package/ios/JSI/EXJavaScriptValue.h +3 -2
- package/ios/JSI/EXJavaScriptValue.mm +17 -20
- package/ios/JSI/EXJavaScriptWeakObject.h +23 -0
- package/ios/JSI/EXJavaScriptWeakObject.mm +53 -0
- package/ios/JSI/EXObjectDeallocator.h +27 -0
- package/ios/JSI/ExpoModulesHostObject.h +3 -3
- package/ios/JSI/ExpoModulesHostObject.mm +4 -4
- package/ios/JSI/JavaScriptRuntime.swift +38 -1
- package/ios/JSI/JavaScriptValue.swift +7 -0
- package/ios/JSI/TypedArray.cpp +67 -0
- package/ios/JSI/TypedArray.h +46 -0
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -11
- package/ios/NativeModulesProxy/EXNativeModulesProxy.h +17 -10
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +88 -77
- package/ios/NativeModulesProxy/NativeModulesProxyModule.swift +17 -0
- package/ios/Services/EXReactNativeEventEmitter.h +2 -2
- package/ios/Services/EXReactNativeEventEmitter.m +11 -6
- package/ios/Swift/AppContext.swift +208 -28
- package/ios/Swift/Arguments/AnyArgument.swift +18 -0
- package/ios/Swift/Arguments/{Types/EnumArgumentType.swift → EnumArgument.swift} +2 -17
- package/ios/Swift/Classes/ClassComponent.swift +95 -0
- package/ios/Swift/Classes/ClassComponentElement.swift +33 -0
- package/ios/Swift/Classes/ClassComponentElementsBuilder.swift +34 -0
- package/ios/Swift/Classes/ClassComponentFactories.swift +96 -0
- package/ios/Swift/DynamicTypes/AnyDynamicType.swift +44 -0
- package/ios/Swift/DynamicTypes/DynamicArrayType.swift +56 -0
- package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicEnumType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +63 -0
- package/ios/Swift/DynamicTypes/DynamicRawType.swift +33 -0
- package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +37 -0
- package/ios/Swift/DynamicTypes/DynamicType.swift +39 -0
- package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +46 -0
- package/ios/Swift/Exceptions/CodedError.swift +1 -1
- package/ios/Swift/Exceptions/Exception.swift +8 -6
- package/ios/Swift/Exceptions/UnexpectedException.swift +2 -1
- package/ios/Swift/ExpoBridgeModule.m +5 -0
- package/ios/Swift/ExpoBridgeModule.swift +65 -0
- package/ios/Swift/Functions/AnyFunction.swift +33 -31
- package/ios/Swift/Functions/AsyncFunctionComponent.swift +196 -59
- package/ios/Swift/Functions/SyncFunctionComponent.swift +142 -58
- package/ios/Swift/JavaScriptUtils.swift +32 -57
- package/ios/Swift/Logging/LogHandlers.swift +39 -0
- package/ios/Swift/Logging/LogType.swift +62 -0
- package/ios/Swift/Logging/Logger.swift +198 -0
- package/ios/Swift/ModuleHolder.swift +19 -54
- package/ios/Swift/ModuleRegistry.swift +7 -1
- package/ios/Swift/Modules/AnyModule.swift +3 -3
- package/ios/Swift/ModulesProvider.swift +2 -0
- package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +37 -0
- package/ios/Swift/Objects/ObjectDefinition.swift +74 -1
- package/ios/Swift/Objects/ObjectDefinitionComponents.swift +77 -68
- package/ios/Swift/Objects/PropertyComponent.swift +147 -0
- package/ios/Swift/Promise.swift +12 -3
- package/ios/Swift/Records/Field.swift +2 -2
- package/ios/Swift/SharedObjects/SharedObject.swift +20 -0
- package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +129 -0
- package/ios/Swift/TypedArrays/AnyTypedArray.swift +11 -0
- package/ios/Swift/TypedArrays/ConcreteTypedArrays.swift +56 -0
- package/ios/Swift/TypedArrays/GenericTypedArray.swift +49 -0
- package/ios/Swift/TypedArrays/TypedArray.swift +80 -0
- package/ios/Swift/Utilities.swift +28 -0
- package/ios/Swift/Views/ConcreteViewProp.swift +3 -3
- package/ios/Swift/Views/ViewManagerDefinitionComponents.swift +2 -2
- package/ios/Tests/ClassComponentSpec.swift +210 -0
- package/ios/Tests/DynamicTypeSpec.swift +336 -0
- package/ios/Tests/EnumArgumentSpec.swift +48 -0
- package/ios/Tests/ExpoModulesSpec.swift +17 -3
- package/ios/Tests/FunctionSpec.swift +167 -118
- package/ios/Tests/Mocks/ModuleMocks.swift +1 -1
- package/ios/Tests/PropertyComponentSpec.swift +95 -0
- package/ios/Tests/SharedObjectRegistrySpec.swift +109 -0
- package/ios/Tests/TypedArraysSpec.swift +136 -0
- package/package.json +2 -2
- package/src/NativeModulesProxy.native.ts +13 -3
- package/src/ts-declarations/ExpoModules.d.ts +7 -0
- package/tsconfig.json +1 -1
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromise.kt +0 -15
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncSuspendFunction.kt +0 -36
- package/ios/Swift/Arguments/AnyArgumentType.swift +0 -13
- package/ios/Swift/Arguments/ArgumentType.swift +0 -28
- package/ios/Swift/Arguments/Types/ArrayArgumentType.swift +0 -42
- package/ios/Swift/Arguments/Types/ConvertibleArgumentType.swift +0 -16
- package/ios/Swift/Arguments/Types/OptionalArgumentType.swift +0 -49
- package/ios/Swift/Arguments/Types/PromiseArgumentType.swift +0 -15
- package/ios/Swift/Arguments/Types/RawArgumentType.swift +0 -25
- package/ios/Swift/Functions/ConcreteFunction.swift +0 -103
- package/ios/Swift/SwiftInteropBridge.swift +0 -155
- package/ios/Tests/ArgumentTypeSpec.swift +0 -143
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Copyright © 2021-present 650 Industries, Inc. (aka Expo)
|
|
2
|
+
|
|
3
|
+
#include "JNIFunctionBody.h"
|
|
4
|
+
|
|
5
|
+
namespace jni = facebook::jni;
|
|
6
|
+
namespace react = facebook::react;
|
|
7
|
+
|
|
8
|
+
namespace expo {
|
|
9
|
+
jni::local_ref<react::ReadableNativeArray::javaobject>
|
|
10
|
+
JNIFunctionBody::invoke(react::ReadableNativeArray::javaobject &&args) {
|
|
11
|
+
static const auto method = getClass()->getMethod<
|
|
12
|
+
react::ReadableNativeArray::javaobject(react::ReadableNativeArray::javaobject)
|
|
13
|
+
>(
|
|
14
|
+
"invoke"
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
return method(this->self(), args);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
void JNIAsyncFunctionBody::invoke(react::ReadableNativeArray::javaobject &&args, jobject promise) {
|
|
21
|
+
static const auto method = getClass()->getMethod<
|
|
22
|
+
void(react::ReadableNativeArray::javaobject, jobject)
|
|
23
|
+
>(
|
|
24
|
+
"invoke"
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
method(this->self(), args, promise);
|
|
28
|
+
}
|
|
29
|
+
} // namespace expo
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Copyright © 2021-present 650 Industries, Inc. (aka Expo)
|
|
2
|
+
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#include <fbjni/fbjni.h>
|
|
6
|
+
#include <react/jni/ReadableNativeArray.h>
|
|
7
|
+
|
|
8
|
+
namespace jni = facebook::jni;
|
|
9
|
+
namespace react = facebook::react;
|
|
10
|
+
|
|
11
|
+
namespace expo {
|
|
12
|
+
/**
|
|
13
|
+
* A CPP part of the expo.modules.kotlin.jni.JNIFunctionBody class.
|
|
14
|
+
* It represents the Kotlin's promise-less function.
|
|
15
|
+
*/
|
|
16
|
+
class JNIFunctionBody : public jni::JavaClass<JNIFunctionBody> {
|
|
17
|
+
public:
|
|
18
|
+
static auto constexpr kJavaDescriptor = "Lexpo/modules/kotlin/jni/JNIFunctionBody;";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Invokes a Kotlin's implementation of this function.
|
|
22
|
+
*
|
|
23
|
+
* @param args
|
|
24
|
+
* @return result of the Kotlin function
|
|
25
|
+
*/
|
|
26
|
+
jni::local_ref<react::ReadableNativeArray::javaobject> invoke(
|
|
27
|
+
react::ReadableNativeArray::javaobject &&args
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A CPP part of the expo.modules.kotlin.jni.JNIAsyncFunctionBody class.
|
|
33
|
+
* It represents the Kotlin's promise function.
|
|
34
|
+
*/
|
|
35
|
+
class JNIAsyncFunctionBody : public jni::JavaClass<JNIAsyncFunctionBody> {
|
|
36
|
+
public:
|
|
37
|
+
static auto constexpr kJavaDescriptor = "Lexpo/modules/kotlin/jni/JNIAsyncFunctionBody;";
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Invokes a Kotlin's implementation of this async function.
|
|
41
|
+
*
|
|
42
|
+
* @param args
|
|
43
|
+
* @param promise that will be resolve or rejected in the Kotlin's implementation
|
|
44
|
+
*/
|
|
45
|
+
void invoke(
|
|
46
|
+
react::ReadableNativeArray::javaobject &&args,
|
|
47
|
+
jobject promise
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
} // namespace expo
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Copyright © 2021-present 650 Industries, Inc. (aka Expo)
|
|
2
|
+
|
|
3
|
+
#include "JSIInteropModuleRegistry.h"
|
|
4
|
+
#include "JavaScriptModuleObject.h"
|
|
5
|
+
#include "JavaScriptValue.h"
|
|
6
|
+
#include "JavaScriptObject.h"
|
|
7
|
+
|
|
8
|
+
#include <jni.h>
|
|
9
|
+
#include <fbjni/fbjni.h>
|
|
10
|
+
|
|
11
|
+
// Install all jni bindings
|
|
12
|
+
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
|
13
|
+
return facebook::jni::initialize(vm, [] {
|
|
14
|
+
expo::JSIInteropModuleRegistry::registerNatives();
|
|
15
|
+
expo::JavaScriptModuleObject::registerNatives();
|
|
16
|
+
expo::JavaScriptValue::registerNatives();
|
|
17
|
+
expo::JavaScriptObject::registerNatives();
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// Copyright © 2021-present 650 Industries, Inc. (aka Expo)
|
|
2
|
+
|
|
3
|
+
#include "JSIInteropModuleRegistry.h"
|
|
4
|
+
#include "ExpoModulesHostObject.h"
|
|
5
|
+
|
|
6
|
+
#include <fbjni/detail/Meta.h>
|
|
7
|
+
#include <fbjni/fbjni.h>
|
|
8
|
+
|
|
9
|
+
#include <memory>
|
|
10
|
+
|
|
11
|
+
namespace jni = facebook::jni;
|
|
12
|
+
namespace jsi = facebook::jsi;
|
|
13
|
+
|
|
14
|
+
namespace expo {
|
|
15
|
+
jni::local_ref<JSIInteropModuleRegistry::jhybriddata>
|
|
16
|
+
JSIInteropModuleRegistry::initHybrid(jni::alias_ref<jhybridobject> jThis) {
|
|
17
|
+
return makeCxxInstance(jThis);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
void JSIInteropModuleRegistry::registerNatives() {
|
|
21
|
+
registerHybrid({
|
|
22
|
+
makeNativeMethod("initHybrid", JSIInteropModuleRegistry::initHybrid),
|
|
23
|
+
makeNativeMethod("installJSI", JSIInteropModuleRegistry::installJSI),
|
|
24
|
+
makeNativeMethod("installJSIForTests",
|
|
25
|
+
JSIInteropModuleRegistry::installJSIForTests),
|
|
26
|
+
makeNativeMethod("evaluateScript", JSIInteropModuleRegistry::evaluateScript),
|
|
27
|
+
makeNativeMethod("global", JSIInteropModuleRegistry::global),
|
|
28
|
+
makeNativeMethod("createObject", JSIInteropModuleRegistry::createObject),
|
|
29
|
+
makeNativeMethod("drainJSEventLoop", JSIInteropModuleRegistry::drainJSEventLoop),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
JSIInteropModuleRegistry::JSIInteropModuleRegistry(jni::alias_ref<jhybridobject> jThis)
|
|
34
|
+
: javaPart_(jni::make_global(jThis)) {}
|
|
35
|
+
|
|
36
|
+
void JSIInteropModuleRegistry::installJSI(
|
|
37
|
+
jlong jsRuntimePointer,
|
|
38
|
+
jni::alias_ref<react::CallInvokerHolder::javaobject> jsInvokerHolder,
|
|
39
|
+
jni::alias_ref<react::CallInvokerHolder::javaobject> nativeInvokerHolder
|
|
40
|
+
) {
|
|
41
|
+
auto runtime = reinterpret_cast<jsi::Runtime *>(jsRuntimePointer);
|
|
42
|
+
runtimeHolder = std::make_shared<JavaScriptRuntime>(
|
|
43
|
+
runtime,
|
|
44
|
+
jsInvokerHolder->cthis()->getCallInvoker(),
|
|
45
|
+
nativeInvokerHolder->cthis()->getCallInvoker()
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
auto expoModules = std::make_shared<ExpoModulesHostObject>(this);
|
|
49
|
+
auto expoModulesObject = jsi::Object::createFromHostObject(*runtime, expoModules);
|
|
50
|
+
|
|
51
|
+
runtime
|
|
52
|
+
->global()
|
|
53
|
+
.setProperty(
|
|
54
|
+
*runtime,
|
|
55
|
+
"ExpoModules",
|
|
56
|
+
std::move(expoModulesObject)
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
void JSIInteropModuleRegistry::installJSIForTests() {
|
|
61
|
+
runtimeHolder = std::make_shared<JavaScriptRuntime>();
|
|
62
|
+
jsi::Runtime &jsiRuntime = *runtimeHolder->get();
|
|
63
|
+
|
|
64
|
+
auto expoModules = std::make_shared<ExpoModulesHostObject>(this);
|
|
65
|
+
auto expoModulesObject = jsi::Object::createFromHostObject(jsiRuntime, expoModules);
|
|
66
|
+
|
|
67
|
+
jsiRuntime
|
|
68
|
+
.global()
|
|
69
|
+
.setProperty(
|
|
70
|
+
jsiRuntime,
|
|
71
|
+
"ExpoModules",
|
|
72
|
+
std::move(expoModulesObject)
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
jni::local_ref<JavaScriptModuleObject::javaobject>
|
|
77
|
+
JSIInteropModuleRegistry::callGetJavaScriptModuleObjectMethod(const std::string &moduleName) const {
|
|
78
|
+
const static auto method = expo::JSIInteropModuleRegistry::javaClassLocal()
|
|
79
|
+
->getMethod<jni::local_ref<JavaScriptModuleObject::javaobject>(
|
|
80
|
+
std::string)>(
|
|
81
|
+
"getJavaScriptModuleObject"
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
return method(javaPart_, moduleName);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
jni::local_ref<jni::JArrayClass<jni::JString>>
|
|
88
|
+
JSIInteropModuleRegistry::callGetJavaScriptModulesNames() const {
|
|
89
|
+
const static auto method = expo::JSIInteropModuleRegistry::javaClassLocal()
|
|
90
|
+
->getMethod<jni::local_ref<jni::JArrayClass<jni::JString>>()>(
|
|
91
|
+
"getJavaScriptModulesName"
|
|
92
|
+
);
|
|
93
|
+
return method(javaPart_);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
jni::local_ref<JavaScriptModuleObject::javaobject>
|
|
97
|
+
JSIInteropModuleRegistry::getModule(const std::string &moduleName) const {
|
|
98
|
+
return callGetJavaScriptModuleObjectMethod(moduleName);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
jni::local_ref<jni::JArrayClass<jni::JString>> JSIInteropModuleRegistry::getModulesName() const {
|
|
102
|
+
return callGetJavaScriptModulesNames();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
jni::local_ref<JavaScriptValue::javaobject> JSIInteropModuleRegistry::evaluateScript(
|
|
106
|
+
jni::JString script
|
|
107
|
+
) {
|
|
108
|
+
return runtimeHolder->evaluateScript(script.toStdString());
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
jni::local_ref<JavaScriptObject::javaobject> JSIInteropModuleRegistry::global() {
|
|
112
|
+
return runtimeHolder->global();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
jni::local_ref<JavaScriptObject::javaobject> JSIInteropModuleRegistry::createObject() {
|
|
116
|
+
return runtimeHolder->createObject();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
void JSIInteropModuleRegistry::drainJSEventLoop() {
|
|
120
|
+
runtimeHolder->drainJSEventLoop();
|
|
121
|
+
}
|
|
122
|
+
} // namespace expo
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// Copyright © 2021-present 650 Industries, Inc. (aka Expo)
|
|
2
|
+
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#include "JavaScriptRuntime.h"
|
|
6
|
+
#include "JavaScriptModuleObject.h"
|
|
7
|
+
#include "JavaScriptValue.h"
|
|
8
|
+
#include "JavaScriptObject.h"
|
|
9
|
+
|
|
10
|
+
#include <fbjni/fbjni.h>
|
|
11
|
+
#include <jsi/jsi.h>
|
|
12
|
+
#include <ReactCommon/CallInvokerHolder.h>
|
|
13
|
+
#include <ReactCommon/CallInvoker.h>
|
|
14
|
+
|
|
15
|
+
#include <memory>
|
|
16
|
+
|
|
17
|
+
namespace jni = facebook::jni;
|
|
18
|
+
namespace jsi = facebook::jsi;
|
|
19
|
+
namespace react = facebook::react;
|
|
20
|
+
|
|
21
|
+
namespace expo {
|
|
22
|
+
/**
|
|
23
|
+
* A JNI wrapper to initialize CPP part of modules and access all data from the module registry.
|
|
24
|
+
*/
|
|
25
|
+
class JSIInteropModuleRegistry : public jni::HybridClass<JSIInteropModuleRegistry> {
|
|
26
|
+
public:
|
|
27
|
+
static auto constexpr
|
|
28
|
+
kJavaDescriptor = "Lexpo/modules/kotlin/jni/JSIInteropModuleRegistry;";
|
|
29
|
+
static auto constexpr TAG = "JSIInteropModuleRegistry";
|
|
30
|
+
|
|
31
|
+
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
|
|
32
|
+
|
|
33
|
+
static void registerNatives();
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Initializes the `ExpoModulesHostObject` and adds it to the global object.
|
|
37
|
+
*/
|
|
38
|
+
void installJSI(
|
|
39
|
+
jlong jsRuntimePointer,
|
|
40
|
+
jni::alias_ref<react::CallInvokerHolder::javaobject> jsInvokerHolder,
|
|
41
|
+
jni::alias_ref<react::CallInvokerHolder::javaobject> nativeInvokerHolder
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Initializes the test runtime. Shouldn't be used in the production.
|
|
46
|
+
*/
|
|
47
|
+
void installJSIForTests();
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Gets a module for a given name. It will throw an exception if the module doesn't exist.
|
|
51
|
+
*
|
|
52
|
+
* @param moduleName
|
|
53
|
+
* @return An instance of `JavaScriptModuleObject`
|
|
54
|
+
*/
|
|
55
|
+
jni::local_ref<JavaScriptModuleObject::javaobject> getModule(const std::string &moduleName) const;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Gets names of all available modules.
|
|
59
|
+
*/
|
|
60
|
+
jni::local_ref<jni::JArrayClass<jni::JString>> getModulesName() const;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Exposes a `JavaScriptRuntime::evaluateScript` function to Kotlin
|
|
64
|
+
*/
|
|
65
|
+
jni::local_ref<JavaScriptValue::javaobject> evaluateScript(jni::JString script);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Exposes a `JavaScriptRuntime::global` function to Kotlin
|
|
69
|
+
*/
|
|
70
|
+
jni::local_ref<JavaScriptObject::javaobject> global();
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Exposes a `JavaScriptRuntime::createObject` function to Kotlin
|
|
74
|
+
*/
|
|
75
|
+
jni::local_ref<JavaScriptObject::javaobject> createObject();
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Exposes a `JavaScriptRuntime::drainJSEventLoop` function to Kotlin
|
|
79
|
+
*/
|
|
80
|
+
void drainJSEventLoop();
|
|
81
|
+
|
|
82
|
+
std::shared_ptr<react::CallInvoker> jsInvoker;
|
|
83
|
+
std::shared_ptr<react::CallInvoker> nativeInvoker;
|
|
84
|
+
std::shared_ptr<JavaScriptRuntime> runtimeHolder;
|
|
85
|
+
private:
|
|
86
|
+
friend HybridBase;
|
|
87
|
+
jni::global_ref<JSIInteropModuleRegistry::javaobject> javaPart_;
|
|
88
|
+
|
|
89
|
+
explicit JSIInteropModuleRegistry(jni::alias_ref<jhybridobject> jThis);
|
|
90
|
+
|
|
91
|
+
inline jni::local_ref<JavaScriptModuleObject::javaobject>
|
|
92
|
+
callGetJavaScriptModuleObjectMethod(const std::string &moduleName) const;
|
|
93
|
+
|
|
94
|
+
inline jni::local_ref<jni::JArrayClass<jni::JString>> callGetJavaScriptModulesNames() const;
|
|
95
|
+
};
|
|
96
|
+
} // namespace expo
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Copyright © 2021-present 650 Industries, Inc. (aka Expo)
|
|
2
|
+
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#include <jsi/jsi.h>
|
|
6
|
+
|
|
7
|
+
#include <memory>
|
|
8
|
+
|
|
9
|
+
namespace jsi = facebook::jsi;
|
|
10
|
+
|
|
11
|
+
namespace expo {
|
|
12
|
+
/**
|
|
13
|
+
* An interface for classes which wrap jsi::Object.
|
|
14
|
+
*/
|
|
15
|
+
class JSIObjectWrapper {
|
|
16
|
+
public:
|
|
17
|
+
/**
|
|
18
|
+
* @return a pointer to the underlying jsi::Object.
|
|
19
|
+
*/
|
|
20
|
+
virtual std::shared_ptr<jsi::Object> get() = 0;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* An interface for classes which wrap jsi::Value.
|
|
25
|
+
*/
|
|
26
|
+
class JSIValueWrapper {
|
|
27
|
+
public:
|
|
28
|
+
/**
|
|
29
|
+
* @return a pointer to the underlying jsi::Value.
|
|
30
|
+
*/
|
|
31
|
+
virtual std::shared_ptr<jsi::Value> get() = 0;
|
|
32
|
+
};
|
|
33
|
+
} // namespace expo
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Copyright © 2021-present 650 Industries, Inc. (aka Expo)
|
|
2
|
+
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#include "JSIObjectWrapper.h"
|
|
6
|
+
|
|
7
|
+
#include <fbjni/fbjni.h>
|
|
8
|
+
#include <jsi/jsi.h>
|
|
9
|
+
|
|
10
|
+
#include <type_traits>
|
|
11
|
+
|
|
12
|
+
namespace jni = facebook::jni;
|
|
13
|
+
namespace jsi = facebook::jsi;
|
|
14
|
+
|
|
15
|
+
namespace expo {
|
|
16
|
+
/**
|
|
17
|
+
* A base template of the jni to jsi types converter.
|
|
18
|
+
* To make this conversion as fast and easy as possible we used the type trait technic.
|
|
19
|
+
*/
|
|
20
|
+
template<class T, typename = void>
|
|
21
|
+
struct jsi_type_converter {
|
|
22
|
+
static const bool isDefined = false;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Conversion from jni::alias_ref<T::javaobject> to jsi::Value where T extends JSIValueWrapper or JSIObjectWrapper.
|
|
27
|
+
*/
|
|
28
|
+
template<class T>
|
|
29
|
+
struct jsi_type_converter<
|
|
30
|
+
jni::alias_ref<T>,
|
|
31
|
+
std::enable_if_t<
|
|
32
|
+
// jni::ReprType<T>::HybridType>::value if T looks like `R::javaobject`, it will return R
|
|
33
|
+
std::is_base_of<JSIValueWrapper, typename jni::ReprType<T>::HybridType>::value ||
|
|
34
|
+
std::is_base_of<JSIObjectWrapper, typename jni::ReprType<T>::HybridType>::value
|
|
35
|
+
>
|
|
36
|
+
> {
|
|
37
|
+
static const bool isDefined = true;
|
|
38
|
+
|
|
39
|
+
inline static jsi::Value convert(
|
|
40
|
+
jsi::Runtime &runtime,
|
|
41
|
+
jni::alias_ref<T> &value) {
|
|
42
|
+
if (value == nullptr) {
|
|
43
|
+
return jsi::Value::undefined();
|
|
44
|
+
}
|
|
45
|
+
return jsi::Value(runtime, *value->cthis()->get());
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Conversion from primitive types from which jsi::Value can be constructed (like bool, double) to jsi::Value.
|
|
51
|
+
*/
|
|
52
|
+
template<class T>
|
|
53
|
+
struct jsi_type_converter<
|
|
54
|
+
T,
|
|
55
|
+
std::enable_if_t<std::is_fundamental_v<T> && std::is_constructible_v<jsi::Value, T>>
|
|
56
|
+
> {
|
|
57
|
+
static const bool isDefined = true;
|
|
58
|
+
|
|
59
|
+
inline static jsi::Value convert(jsi::Runtime &runtime, T value) {
|
|
60
|
+
return jsi::Value(value);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Conversion from jni::alias_ref<jstring> to jsi::Value.
|
|
66
|
+
*/
|
|
67
|
+
template<>
|
|
68
|
+
struct jsi_type_converter<jni::alias_ref<jstring>> {
|
|
69
|
+
static const bool isDefined = true;
|
|
70
|
+
|
|
71
|
+
inline static jsi::Value convert(jsi::Runtime &runtime, jni::alias_ref<jstring> &value) {
|
|
72
|
+
if (value == nullptr) {
|
|
73
|
+
return jsi::Value::undefined();
|
|
74
|
+
}
|
|
75
|
+
return jsi::Value(jsi::String::createFromUtf8(runtime, value->toStdString()));
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Helper that checks if the type converter was defined for the given type.
|
|
81
|
+
*/
|
|
82
|
+
template<class T>
|
|
83
|
+
inline constexpr bool is_jsi_type_converter_defined = jsi_type_converter<T>::isDefined;
|
|
84
|
+
} // namespace expo
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Copyright © 2021-present 650 Industries, Inc. (aka Expo)
|
|
2
|
+
|
|
3
|
+
#include "JavaScriptModuleObject.h"
|
|
4
|
+
#include "JSIInteropModuleRegistry.h"
|
|
5
|
+
|
|
6
|
+
#include <folly/dynamic.h>
|
|
7
|
+
#include <jsi/JSIDynamic.h>
|
|
8
|
+
#include <react/jni/ReadableNativeArray.h>
|
|
9
|
+
#include <fbjni/detail/Hybrid.h>
|
|
10
|
+
#include <ReactCommon/TurboModuleUtils.h>
|
|
11
|
+
#include <jni/JCallback.h>
|
|
12
|
+
#include <jsi/JSIDynamic.h>
|
|
13
|
+
#include <fbjni/fbjni.h>
|
|
14
|
+
#include <jsi/jsi.h>
|
|
15
|
+
|
|
16
|
+
#include <utility>
|
|
17
|
+
#include <tuple>
|
|
18
|
+
#include <algorithm>
|
|
19
|
+
|
|
20
|
+
namespace jni = facebook::jni;
|
|
21
|
+
namespace jsi = facebook::jsi;
|
|
22
|
+
namespace react = facebook::react;
|
|
23
|
+
|
|
24
|
+
namespace expo {
|
|
25
|
+
|
|
26
|
+
jni::local_ref<jni::HybridClass<JavaScriptModuleObject>::jhybriddata>
|
|
27
|
+
JavaScriptModuleObject::initHybrid(jni::alias_ref<jhybridobject> jThis) {
|
|
28
|
+
return makeCxxInstance(jThis);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
void JavaScriptModuleObject::registerNatives() {
|
|
32
|
+
registerHybrid({
|
|
33
|
+
makeNativeMethod("initHybrid", JavaScriptModuleObject::initHybrid),
|
|
34
|
+
makeNativeMethod("exportConstants", JavaScriptModuleObject::exportConstants),
|
|
35
|
+
makeNativeMethod("registerSyncFunction",
|
|
36
|
+
JavaScriptModuleObject::registerSyncFunction),
|
|
37
|
+
makeNativeMethod("registerAsyncFunction",
|
|
38
|
+
JavaScriptModuleObject::registerAsyncFunction),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
std::shared_ptr<jsi::Object> JavaScriptModuleObject::getJSIObject(jsi::Runtime &runtime) {
|
|
43
|
+
if (jsiObject == nullptr) {
|
|
44
|
+
auto hostObject = std::make_shared<JavaScriptModuleObject::HostObject>(this);
|
|
45
|
+
jsiObject = std::make_shared<jsi::Object>(
|
|
46
|
+
jsi::Object::createFromHostObject(runtime, hostObject));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return jsiObject;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
void JavaScriptModuleObject::exportConstants(jni::alias_ref<react::NativeMap::javaobject>
|
|
53
|
+
constants) {
|
|
54
|
+
auto dynamic = constants->cthis()->consume();
|
|
55
|
+
assert(dynamic.isObject());
|
|
56
|
+
|
|
57
|
+
for (const auto &[key, value]: dynamic.items()) {
|
|
58
|
+
this->constants[key.asString()] = value;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
void JavaScriptModuleObject::registerSyncFunction(
|
|
63
|
+
jni::alias_ref<jstring> name,
|
|
64
|
+
jint args,
|
|
65
|
+
jni::alias_ref<JNIFunctionBody::javaobject> body
|
|
66
|
+
) {
|
|
67
|
+
auto cName = name->toStdString();
|
|
68
|
+
methodsMetadata.try_emplace(cName, cName, args, false, jni::make_global(body));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
void JavaScriptModuleObject::registerAsyncFunction(
|
|
72
|
+
jni::alias_ref<jstring> name,
|
|
73
|
+
jint args,
|
|
74
|
+
jni::alias_ref<JNIAsyncFunctionBody::javaobject> body
|
|
75
|
+
) {
|
|
76
|
+
auto cName = name->toStdString();
|
|
77
|
+
methodsMetadata.try_emplace(cName, cName, args, true, jni::make_global(body));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
JavaScriptModuleObject::HostObject::HostObject(
|
|
81
|
+
JavaScriptModuleObject *jsModule) : jsModule(jsModule) {}
|
|
82
|
+
|
|
83
|
+
jsi::Value JavaScriptModuleObject::HostObject::get(jsi::Runtime &runtime,
|
|
84
|
+
const jsi::PropNameID &name) {
|
|
85
|
+
auto cName = name.utf8(runtime);
|
|
86
|
+
|
|
87
|
+
auto constantsRecord = jsModule->constants.find(cName);
|
|
88
|
+
if (constantsRecord != jsModule->constants.end()) {
|
|
89
|
+
auto dynamic = constantsRecord->second;
|
|
90
|
+
return jsi::valueFromDynamic(runtime, dynamic);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
auto metadataRecord = jsModule->methodsMetadata.find(cName);
|
|
94
|
+
if (metadataRecord == jsModule->methodsMetadata.end()) {
|
|
95
|
+
return jsi::Value::undefined();
|
|
96
|
+
}
|
|
97
|
+
auto &metadata = metadataRecord->second;
|
|
98
|
+
return jsi::Value(runtime, *metadata.toJSFunction(runtime, jsModule->jsiInteropModuleRegistry));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
void JavaScriptModuleObject::HostObject::set(
|
|
102
|
+
jsi::Runtime &runtime,
|
|
103
|
+
const jsi::PropNameID &name,
|
|
104
|
+
const jsi::Value &value
|
|
105
|
+
) {
|
|
106
|
+
throw jsi::JSError(
|
|
107
|
+
runtime,
|
|
108
|
+
"RuntimeError: Cannot override the host object for expo module '" + name.utf8(runtime) + "'"
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
std::vector<jsi::PropNameID> JavaScriptModuleObject::HostObject::getPropertyNames(
|
|
113
|
+
jsi::Runtime &rt
|
|
114
|
+
) {
|
|
115
|
+
auto &metadata = jsModule->methodsMetadata;
|
|
116
|
+
std::vector<jsi::PropNameID> result;
|
|
117
|
+
std::transform(
|
|
118
|
+
metadata.begin(),
|
|
119
|
+
metadata.end(),
|
|
120
|
+
std::back_inserter(result),
|
|
121
|
+
[&rt](const auto &kv) {
|
|
122
|
+
return jsi::PropNameID::forUtf8(rt, kv.first);
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
auto &constants = jsModule->constants;
|
|
127
|
+
std::transform(
|
|
128
|
+
constants.begin(),
|
|
129
|
+
constants.end(),
|
|
130
|
+
std::back_inserter(result),
|
|
131
|
+
[&rt](const auto &kv) {
|
|
132
|
+
return jsi::PropNameID::forUtf8(rt, kv.first);
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
} // namespace expo
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// Copyright © 2021-present 650 Industries, Inc. (aka Expo)
|
|
2
|
+
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#include <fbjni/fbjni.h>
|
|
6
|
+
#include <jsi/jsi.h>
|
|
7
|
+
#include <react/jni/ReadableNativeArray.h>
|
|
8
|
+
#include <jni/JCallback.h>
|
|
9
|
+
|
|
10
|
+
#include <map>
|
|
11
|
+
|
|
12
|
+
#include "MethodMetadata.h"
|
|
13
|
+
#include "JNIFunctionBody.h"
|
|
14
|
+
|
|
15
|
+
namespace jni = facebook::jni;
|
|
16
|
+
namespace jsi = facebook::jsi;
|
|
17
|
+
namespace react = facebook::react;
|
|
18
|
+
|
|
19
|
+
namespace expo {
|
|
20
|
+
class JSIInteropModuleRegistry;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A CPP part of the module.
|
|
24
|
+
*
|
|
25
|
+
* Right now objects of this class are stored by the ModuleHolder to ensure they will live
|
|
26
|
+
* as long as the RN context.
|
|
27
|
+
*/
|
|
28
|
+
class JavaScriptModuleObject : public jni::HybridClass<JavaScriptModuleObject> {
|
|
29
|
+
public:
|
|
30
|
+
static auto constexpr
|
|
31
|
+
kJavaDescriptor = "Lexpo/modules/kotlin/jni/JavaScriptModuleObject;";
|
|
32
|
+
static auto constexpr TAG = "JavaScriptModuleObject";
|
|
33
|
+
|
|
34
|
+
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
|
|
35
|
+
|
|
36
|
+
static void registerNatives();
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Pointer to the module registry interop.
|
|
40
|
+
*/
|
|
41
|
+
JSIInteropModuleRegistry *jsiInteropModuleRegistry;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Returns a cached instance of jsi::Object representing this module.
|
|
45
|
+
* @param runtime
|
|
46
|
+
* @return Wrapped instance of JavaScriptModuleObject::HostObject
|
|
47
|
+
*/
|
|
48
|
+
std::shared_ptr<jsi::Object> getJSIObject(jsi::Runtime &runtime);
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Exports constants that will be assigned to the underlying HostObject.
|
|
52
|
+
*/
|
|
53
|
+
void exportConstants(jni::alias_ref<react::NativeMap::javaobject> constants);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Registers a sync function.
|
|
57
|
+
* That function can be called via the `JavaScriptModuleObject.callSyncMethod` method.
|
|
58
|
+
*/
|
|
59
|
+
void registerSyncFunction(
|
|
60
|
+
jni::alias_ref<jstring> name,
|
|
61
|
+
jint args,
|
|
62
|
+
jni::alias_ref<JNIFunctionBody::javaobject> JSIFunctionBody
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Registers a async function.
|
|
67
|
+
* That function can be called via the `JavaScriptModuleObject.callAsyncMethod` method.
|
|
68
|
+
*/
|
|
69
|
+
void registerAsyncFunction(
|
|
70
|
+
jni::alias_ref<jstring> name,
|
|
71
|
+
jint args,
|
|
72
|
+
jni::alias_ref<JNIAsyncFunctionBody::javaobject> JSIAsyncFunctionBody
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* An inner class of the `JavaScriptModuleObject` that is exported to the JS.
|
|
77
|
+
* It's an additional communication layer between JS and Kotlin.
|
|
78
|
+
* So the high-level view on accessing the exported function will look like this:
|
|
79
|
+
* `JS` --get function--> `JavaScriptModuleObject::HostObject` --access module metadata--> `JavaScriptModuleObject`
|
|
80
|
+
* --create JSI function--> `MethodMetadata`
|
|
81
|
+
*
|
|
82
|
+
* This abstraction wasn't necessary. However, it makes the management of ownership much easier -
|
|
83
|
+
* `JavaScriptModuleObject` is held by the ModuleHolder and `JavaScriptModuleObject::HostObject` is stored in the JS runtime.
|
|
84
|
+
* Without this distinction the `JavaScriptModuleObject` would have to turn into `HostObject` and `HybridObject` at the same time.
|
|
85
|
+
*/
|
|
86
|
+
class HostObject : public jsi::HostObject {
|
|
87
|
+
public:
|
|
88
|
+
HostObject(JavaScriptModuleObject *);
|
|
89
|
+
|
|
90
|
+
jsi::Value get(jsi::Runtime &, const jsi::PropNameID &name) override;
|
|
91
|
+
|
|
92
|
+
void set(jsi::Runtime &, const jsi::PropNameID &name, const jsi::Value &value) override;
|
|
93
|
+
|
|
94
|
+
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
|
|
95
|
+
|
|
96
|
+
private:
|
|
97
|
+
JavaScriptModuleObject *jsModule;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
private:
|
|
101
|
+
friend HybridBase;
|
|
102
|
+
/**
|
|
103
|
+
* A reference to the `JavaScriptModuleObject::HostObject`.
|
|
104
|
+
* Simple we cached that value to return the same object each time.
|
|
105
|
+
*/
|
|
106
|
+
std::shared_ptr<jsi::Object> jsiObject = nullptr;
|
|
107
|
+
jni::global_ref<JavaScriptModuleObject::javaobject> javaPart_;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Metadata map that stores information about all available methods on this module.
|
|
111
|
+
*/
|
|
112
|
+
std::map<std::string, MethodMetadata> methodsMetadata;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* A constants map.
|
|
116
|
+
*/
|
|
117
|
+
std::map<std::string, folly::dynamic> constants;
|
|
118
|
+
|
|
119
|
+
explicit JavaScriptModuleObject(jni::alias_ref<jhybridobject> jThis)
|
|
120
|
+
: javaPart_(jni::make_global(jThis)) {}
|
|
121
|
+
};
|
|
122
|
+
} // namespace expo
|