From 1e1ef2fe9aaf3d0a1ccfa4edc3de8b259b10f54c Mon Sep 17 00:00:00 2001 From: Kudo Chien Date: Wed, 12 Feb 2025 21:08:34 +0800 Subject: [PATCH 1/4] chore: add android implementations --- example/.gitignore => .gitignore | 0 android/.gitkeep | 0 android/CMakeLists.txt | 74 +++++++++ android/build.gradle.kts | 146 ++++++++++++++++++ android/src/main/AndroidManifest.xml | 2 + android/src/main/cpp/JSCExecutorFactory.cpp | 48 ++++++ android/src/main/cpp/JSCExecutorFactory.h | 41 +++++ android/src/main/cpp/JSCRuntimeFactory.h | 45 ++++++ android/src/main/cpp/OnLoad.cpp | 18 +++ .../javascriptcore/JSCExecutor.kt | 36 +++++ .../javascriptcore/JSCExecutorFactory.kt | 38 +++++ .../javascriptcore/JSCPackage.kt | 24 +++ .../javascriptcore/JSCRuntimeFactory.kt | 26 ++++ 13 files changed, 498 insertions(+) rename example/.gitignore => .gitignore (100%) delete mode 100644 android/.gitkeep create mode 100644 android/CMakeLists.txt create mode 100644 android/build.gradle.kts create mode 100644 android/src/main/AndroidManifest.xml create mode 100644 android/src/main/cpp/JSCExecutorFactory.cpp create mode 100644 android/src/main/cpp/JSCExecutorFactory.h create mode 100644 android/src/main/cpp/JSCRuntimeFactory.h create mode 100644 android/src/main/cpp/OnLoad.cpp create mode 100644 android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCExecutor.kt create mode 100644 android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCExecutorFactory.kt create mode 100644 android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt create mode 100644 android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCRuntimeFactory.kt diff --git a/example/.gitignore b/.gitignore similarity index 100% rename from example/.gitignore rename to .gitignore diff --git a/android/.gitkeep b/android/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/android/CMakeLists.txt b/android/CMakeLists.txt new file mode 100644 index 0000000..7b39f08 --- /dev/null +++ b/android/CMakeLists.txt @@ -0,0 +1,74 @@ +# +# Copyright (c) react-native-community +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. +# + +cmake_minimum_required(VERSION 3.13) +project(jscruntimefactory) + +set(CMAKE_VERBOSE_MAKEFILE ON) +set (CMAKE_CXX_STANDARD 20) + +string(APPEND CMAKE_CXX_FLAGS + " -fexceptions" + " -frtti" + " -O3" + " -Wno-unused-lambda-capture" + " -DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}" + " -DREACT_NATIVE_PATCH_VERSION=${REACT_NATIVE_PATCH_VERSION}" +) + +include("${REACT_NATIVE_DIR}/ReactAndroid/cmake-utils/folly-flags.cmake") +add_compile_options(${folly_FLAGS}) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "") + +set(PACKAGE_NAME "jscruntimefactory") +set(SRC_DIR "${CMAKE_SOURCE_DIR}/src/main/cpp") + +set(COMMON_DIR "${CMAKE_SOURCE_DIR}/../common") +file(GLOB COMMON_SOURCES "${COMMON_DIR}/*.cpp") + +add_library( + ${PACKAGE_NAME} + SHARED + ${COMMON_SOURCES} + "${SRC_DIR}/JSCExecutorFactory.cpp" + "${SRC_DIR}/OnLoad.cpp" +) + +# includes + +target_include_directories( + ${PACKAGE_NAME} + PRIVATE + "${COMMON_DIR}" + "${REACT_NATIVE_DIR}/ReactCommon" + "${REACT_NATIVE_DIR}/ReactCommon/jsiexecutor" + "${REACT_NATIVE_DIR}/ReactAndroid/src/main/jni" +) + +# find libraries + +find_library( + LOG_LIB + log +) +find_package(fbjni REQUIRED CONFIG) +find_package(jsc-android REQUIRED CONFIG) +find_package(ReactAndroid REQUIRED CONFIG) + +# link to shared libraries + +target_link_libraries( + ${PACKAGE_NAME} + ${LOG_LIB} + android + fbjni::fbjni + jsc-android::jsc + ReactAndroid::jsi + ReactAndroid::reactnative +) diff --git a/android/build.gradle.kts b/android/build.gradle.kts new file mode 100644 index 0000000..ad68469 --- /dev/null +++ b/android/build.gradle.kts @@ -0,0 +1,146 @@ +/* + * Copyright (c) react-native-community + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import com.android.build.gradle.internal.tasks.factory.dependsOn +import groovy.json.JsonSlurper +import org.apache.tools.ant.taskdefs.condition.Os +import java.util.Properties + +val reactNativeDir = findNodePackageDir("react-native") +val reactNativeManifest = file("${reactNativeDir}/package.json") +val reactNativeManifestAsJson = JsonSlurper().parseText(reactNativeManifest.readText()) as Map<*, *> +val reactNativeVersion = reactNativeManifestAsJson["version"] as String +val (major, minor, patch) = reactNativeVersion.split(".") +val rnMinorVersion = minor.toInt() +val rnPatchVersion = patch.toInt() +val prefabHeadersDir = file("${layout.buildDirectory.get()}/prefab-headers") + +if (findProperty("hermesEnabled") == "true") { + throw GradleException("Please disable Hermes because Hermes will transform the JavaScript bundle as bytecode bundle.\n") +} + +val reactProperties = Properties().apply { + file("${reactNativeDir}/ReactAndroid/gradle.properties").inputStream().use { load(it) } +} + +plugins { + id("com.android.library") + id("org.jetbrains.kotlin.android") +} + +android { + namespace = "io.github.reactnativecommunity.javascriptcore" + compileSdk = safeExtGet("compileSdkVersion", 35) + + if (rootProject.hasProperty("ndkPath")) { + ndkPath = rootProject.extra["ndkPath"].toString() + } + if (rootProject.hasProperty("ndkVersion")) { + ndkVersion = rootProject.extra["ndkVersion"].toString() + } + + defaultConfig { + minSdk = safeExtGet("minSdkVersion", 24) + + @Suppress("UnstableApiUsage") + externalNativeBuild.cmake { + arguments += listOf( + "-DANDROID_STL=c++_shared", + "-DREACT_NATIVE_DIR=${reactNativeDir.toPlatformString()}", + "-DREACT_NATIVE_MINOR_VERSION=${rnMinorVersion}", + "-DREACT_NATIVE_PATCH_VERSION=${rnPatchVersion}", + ) + targets("jscruntimefactory") + abiFilters(*reactNativeArchitectures().toTypedArray()) + } + } + + externalNativeBuild { + cmake { + path("CMakeLists.txt") + } + } + + lint { + abortOnError = false + targetSdk = safeExtGet("targetSdkVersion", 35) + } + + packaging { + // Uncomment to keep debug symbols + // doNotStrip.add("**/*.so") + + jniLibs { + excludes.add("**/libc++_shared.so") + excludes.add("**/libfbjni.so") + excludes.add("**/libjsi.so") + excludes.add("**/libreactnative.so") + pickFirsts.add("**/libjscruntimefactory.so") + } + } + + buildFeatures { + prefab = true + prefabPublishing = true + } + + prefab { + register("jscruntimefactory") { + headers = file(prefabHeadersDir).absolutePath + } + } +} + +dependencies { + implementation("com.facebook.yoga:proguard-annotations:1.19.0") + compileOnly("com.facebook.fbjni:fbjni:0.7.0") + implementation("com.facebook.react:react-android") + + //noinspection GradleDynamicVersion + implementation("io.github.react-native-community:jsc-android:2026004.+") +} + +val createPrefabHeadersDir by + tasks.registering { + prefabHeadersDir.mkdirs() + } + +tasks.named("preBuild").dependsOn(createPrefabHeadersDir) + +private fun findNodePackageDir(packageName: String, absolute: Boolean = true): File { + val nodeCommand = listOf("node", "--print", "require.resolve('${packageName}/package.json')") + val proc = ProcessBuilder(nodeCommand) + .directory(rootDir) + .start() + val error = proc.errorStream.bufferedReader().readText() + if (error.isNotEmpty()) { + val nodeCommandString = nodeCommand.joinToString(" ") + throw GradleException( + "findNodePackageDir() execution failed - nodeCommand[$nodeCommandString]\n$error" + ) + } + val dir = File(proc.inputStream.bufferedReader().readText().trim()).parentFile + return if (absolute) dir.absoluteFile else dir +} + +private fun File.toPlatformString(): String { + var result = path.toString() + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + result = result.replace(File.separatorChar, '/') + } + return result +} + +private fun reactNativeArchitectures(): List { + val value = findProperty("reactNativeArchitectures") + return value?.toString()?.split(",") ?: listOf("armeabi-v7a", "x86", "x86_64", "arm64-v8a") +} + +private fun safeExtGet(prop: String, fallback: T): T { + @Suppress("UNCHECKED_CAST") + return rootProject.extra[prop] as? T ?: fallback +} diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a2f47b6 --- /dev/null +++ b/android/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/android/src/main/cpp/JSCExecutorFactory.cpp b/android/src/main/cpp/JSCExecutorFactory.cpp new file mode 100644 index 0000000..045c36c --- /dev/null +++ b/android/src/main/cpp/JSCExecutorFactory.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "JSCExecutorFactory.h" + +#include +#include +#include + +namespace facebook::react { + +namespace { + +class JSCExecutorFactory : public JSExecutorFactory { +public: + std::unique_ptr + createJSExecutor(std::shared_ptr delegate, + std::shared_ptr jsQueue) override { + auto installBindings = [](jsi::Runtime &runtime) { + react::Logger androidLogger = + static_cast( + &reactAndroidLoggingHook); + react::bindNativeLogger(runtime, androidLogger); + }; + return std::make_unique(jsc::makeJSCRuntime(), delegate, + JSIExecutor::defaultTimeoutInvoker, + installBindings); + } +}; + +} // namespace + +// static +jni::local_ref +JSCExecutorHolder::initHybrid(jni::alias_ref, ReadableNativeMap *) { + // This is kind of a weird place for stuff, but there's no other + // good place for initialization which is specific to JSC on + // Android. + JReactMarker::setLogPerfMarkerIfNeeded(); + // TODO mhorowitz T28461666 fill in some missing nice to have glue + return makeCxxInstance(std::make_unique()); +} + +} // namespace facebook::react diff --git a/android/src/main/cpp/JSCExecutorFactory.h b/android/src/main/cpp/JSCExecutorFactory.h new file mode 100644 index 0000000..739ecc0 --- /dev/null +++ b/android/src/main/cpp/JSCExecutorFactory.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include + +#include "JSCRuntime.h" + +namespace facebook::react { + +// This is not like JSCJavaScriptExecutor, which calls JSC directly. This uses +// JSIExecutor with JSCRuntime. +class JSCExecutorHolder + : public jni::HybridClass { +public: + static constexpr auto kJavaDescriptor = + "Lio/github/reactnativecommunity/javascriptcore/JSCExecutor;"; + + static jni::local_ref initHybrid(jni::alias_ref, + ReadableNativeMap *); + + static void registerNatives() { + registerHybrid({ + makeNativeMethod("initHybrid", JSCExecutorHolder::initHybrid), + }); + } + +private: + friend HybridBase; + using HybridBase::HybridBase; +}; + +} // namespace facebook::react diff --git a/android/src/main/cpp/JSCRuntimeFactory.h b/android/src/main/cpp/JSCRuntimeFactory.h new file mode 100644 index 0000000..394fa47 --- /dev/null +++ b/android/src/main/cpp/JSCRuntimeFactory.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include + +#include "JSCRuntime.h" + +namespace facebook::react { + +class JSCRuntimeFactory + : public jni::HybridClass { +public: + static constexpr auto kJavaDescriptor = + "Lio/github/reactnativecommunity/javascriptcore/JSCRuntimeFactory;"; + + static jni::local_ref initHybrid(jni::alias_ref) { + return makeCxxInstance(); + } + + static void registerNatives() { + registerHybrid({ + makeNativeMethod("initHybrid", JSCRuntimeFactory::initHybrid), + }); + } + + std::unique_ptr + createJSRuntime(std::shared_ptr msgQueueThread) noexcept { + return std::make_unique(jsc::makeJSCRuntime()); + } + +private: + friend HybridBase; + using HybridBase::HybridBase; +}; + +} // namespace facebook::react diff --git a/android/src/main/cpp/OnLoad.cpp b/android/src/main/cpp/OnLoad.cpp new file mode 100644 index 0000000..9754852 --- /dev/null +++ b/android/src/main/cpp/OnLoad.cpp @@ -0,0 +1,18 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +#include "JSCExecutorFactory.h" +#include "JSCRuntimeFactory.h" + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { + return facebook::jni::initialize(vm, [] { + facebook::react::JSCExecutorHolder::registerNatives(); + facebook::react::JSCRuntimeFactory::registerNatives(); + }); +} diff --git a/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCExecutor.kt b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCExecutor.kt new file mode 100644 index 0000000..5a9ebe4 --- /dev/null +++ b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCExecutor.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package io.github.reactnativecommunity.javascriptcore + +import com.facebook.jni.HybridData +import com.facebook.proguard.annotations.DoNotStrip +import com.facebook.react.bridge.JavaScriptExecutor +import com.facebook.react.bridge.ReadableNativeMap +import com.facebook.soloader.SoLoader + +@DoNotStrip +internal class JSCExecutor(jscConfig: ReadableNativeMap) : + JavaScriptExecutor(initHybrid(jscConfig)) { + override fun getName(): String { + return "JSCExecutor" + } + + private companion object { + init { + loadLibrary() + } + + @JvmStatic + @Throws(UnsatisfiedLinkError::class) + fun loadLibrary() { + SoLoader.loadLibrary("jscruntimefactory") + } + + @JvmStatic private external fun initHybrid(jscConfig: ReadableNativeMap): HybridData + } +} diff --git a/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCExecutorFactory.kt b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCExecutorFactory.kt new file mode 100644 index 0000000..e3f5d32 --- /dev/null +++ b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCExecutorFactory.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package io.github.reactnativecommunity.javascriptcore + +import com.facebook.react.bridge.JavaScriptExecutor +import com.facebook.react.bridge.JavaScriptExecutorFactory +import com.facebook.react.bridge.WritableNativeMap + +@Suppress("Unused") +class JSCExecutorFactory(private val appName: String, private val deviceName: String) : + JavaScriptExecutorFactory { + + @Throws(Exception::class) + override fun create(): JavaScriptExecutor { + val jscConfig = + WritableNativeMap().apply { + putString("OwnerIdentity", "ReactNative") + putString("AppIdentity", appName) + putString("DeviceIdentity", deviceName) + } + return JSCExecutor(jscConfig) + } + + override fun startSamplingProfiler() { + throw UnsupportedOperationException("Starting sampling profiler not supported on ${toString()}") + } + + override fun stopSamplingProfiler(filename: String) { + throw UnsupportedOperationException("Stopping sampling profiler not supported on ${toString()}") + } + + override fun toString(): String = "JSIExecutor+JSCRuntime" +} diff --git a/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt new file mode 100644 index 0000000..92ce1b9 --- /dev/null +++ b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package io.github.reactnativecommunity.javascriptcore + +import com.facebook.react.ReactPackage +import com.facebook.react.bridge.NativeModule +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.uimanager.ViewManager + +@Suppress("Unused") +class JSCPackage : ReactPackage { + override fun createNativeModules(reactContext: ReactApplicationContext): List { + return emptyList() + } + + override fun createViewManagers(reactContext: ReactApplicationContext): List> { + return emptyList() + } +} diff --git a/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCRuntimeFactory.kt b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCRuntimeFactory.kt new file mode 100644 index 0000000..4956e6e --- /dev/null +++ b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCRuntimeFactory.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package io.github.reactnativecommunity.javascriptcore + +import com.facebook.jni.HybridData +import com.facebook.jni.annotations.DoNotStrip +import com.facebook.jni.annotations.DoNotStripAny +import com.facebook.react.runtime.JSRuntimeFactory +import com.facebook.soloader.SoLoader + +@Suppress("Unused") +@DoNotStripAny +class JSCRuntimeFactory : JSRuntimeFactory(initHybrid()) { + private companion object { + init { + SoLoader.loadLibrary("jscruntimefactory") + } + + @DoNotStrip @JvmStatic private external fun initHybrid(): HybridData + } +} From c4016e77a4ec9c4a22220740ed698880458d5f58 Mon Sep 17 00:00:00 2001 From: Kudo Chien Date: Thu, 13 Feb 2025 02:05:11 +0800 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Nicola Corti --- .../github/reactnativecommunity/javascriptcore/JSCExecutor.kt | 4 +--- .../github/reactnativecommunity/javascriptcore/JSCPackage.kt | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCExecutor.kt b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCExecutor.kt index 5a9ebe4..758533a 100644 --- a/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCExecutor.kt +++ b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCExecutor.kt @@ -16,9 +16,7 @@ import com.facebook.soloader.SoLoader @DoNotStrip internal class JSCExecutor(jscConfig: ReadableNativeMap) : JavaScriptExecutor(initHybrid(jscConfig)) { - override fun getName(): String { - return "JSCExecutor" - } + override fun getName(): String = "JSCExecutor" private companion object { init { diff --git a/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt index 92ce1b9..c7125fe 100644 --- a/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt +++ b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt @@ -14,7 +14,7 @@ import com.facebook.react.uimanager.ViewManager @Suppress("Unused") class JSCPackage : ReactPackage { - override fun createNativeModules(reactContext: ReactApplicationContext): List { + override fun createNativeModules(reactContext: ReactApplicationContext): List = emptyList() return emptyList() } From fece06d96a72865a325a576d8ad807271680f314 Mon Sep 17 00:00:00 2001 From: Kudo Chien Date: Thu, 13 Feb 2025 02:06:15 +0800 Subject: [PATCH 3/4] Apply suggestions from code review --- android/src/main/AndroidManifest.xml | 2 -- .../reactnativecommunity/javascriptcore/JSCPackage.kt | 6 +----- 2 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 android/src/main/AndroidManifest.xml diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml deleted file mode 100644 index a2f47b6..0000000 --- a/android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt index c7125fe..bf09812 100644 --- a/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt +++ b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt @@ -15,10 +15,6 @@ import com.facebook.react.uimanager.ViewManager @Suppress("Unused") class JSCPackage : ReactPackage { override fun createNativeModules(reactContext: ReactApplicationContext): List = emptyList() - return emptyList() - } - override fun createViewManagers(reactContext: ReactApplicationContext): List> { - return emptyList() - } + override fun createViewManagers(reactContext: ReactApplicationContext): List> = emptyList() } From 00ee80467375bf298d41a35787d12c8cb121c9f3 Mon Sep 17 00:00:00 2001 From: Kudo Chien Date: Thu, 13 Feb 2025 02:07:54 +0800 Subject: [PATCH 4/4] reformat code --- .../reactnativecommunity/javascriptcore/JSCPackage.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt index bf09812..43dd431 100644 --- a/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt +++ b/android/src/main/java/io/github/reactnativecommunity/javascriptcore/JSCPackage.kt @@ -14,7 +14,9 @@ import com.facebook.react.uimanager.ViewManager @Suppress("Unused") class JSCPackage : ReactPackage { - override fun createNativeModules(reactContext: ReactApplicationContext): List = emptyList() + override fun createNativeModules(reactContext: ReactApplicationContext): List = + emptyList() - override fun createViewManagers(reactContext: ReactApplicationContext): List> = emptyList() + override fun createViewManagers(reactContext: ReactApplicationContext): List> = + emptyList() }