From 74f0af3925b3487871cbf13114810a871be4d594 Mon Sep 17 00:00:00 2001 From: Siddarth Kumar Date: Tue, 30 Sep 2025 16:56:24 +0530 Subject: [PATCH 1/6] chore: turbo module setup --- mobile-app/ios/Podfile | 24 ++++++ mobile-app/ios/Podfile.lock | 7 +- .../modules/nim-bridge/NimBridge.podspec | 7 +- .../modules/nim-bridge/android/build.gradle | 12 +++ .../java/com/nimbridge/NimBridgeModule.kt | 56 +++++++------- .../java/com/nimbridge/NimBridgePackage.kt | 35 ++++++--- mobile-app/modules/nim-bridge/ios/NimBridge.h | 28 ++++++- .../modules/nim-bridge/ios/NimBridge.mm | 74 ++++++++++++++++++- mobile-app/modules/nim-bridge/package.json | 8 ++ .../modules/nim-bridge/src/NativeNimBridge.ts | 23 ++++++ mobile-app/modules/nim-bridge/src/index.ts | 45 ++++------- mobile-app/package.json | 10 ++- 12 files changed, 251 insertions(+), 78 deletions(-) create mode 100644 mobile-app/modules/nim-bridge/src/NativeNimBridge.ts diff --git a/mobile-app/ios/Podfile b/mobile-app/ios/Podfile index 04dd271..99a753a 100644 --- a/mobile-app/ios/Podfile +++ b/mobile-app/ios/Podfile @@ -53,6 +53,30 @@ target 'nimrnmobileapp' do :ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true', ) + # Patch Folly source files to disable coroutines + folly_expected = File.join(installer.sandbox.root, 'RCT-Folly/folly/Expected.h') + folly_optional = File.join(installer.sandbox.root, 'RCT-Folly/folly/Optional.h') + + if File.exist?(folly_expected) + # Make file writable + system("chmod u+w \"#{folly_expected}\"") + contents = File.read(folly_expected) + # Replace #if FOLLY_HAS_COROUTINES with #if 0 to disable the coroutine sections + contents.gsub!(/#if FOLLY_HAS_COROUTINES/, '#if 0 // FOLLY_HAS_COROUTINES disabled by Podfile patch') + File.write(folly_expected, contents) + puts "✅ Patched #{folly_expected} to disable coroutines" + end + + if File.exist?(folly_optional) + # Make file writable + system("chmod u+w \"#{folly_optional}\"") + contents = File.read(folly_optional) + # Replace #if FOLLY_HAS_COROUTINES with #if 0 to disable the coroutine sections + contents.gsub!(/#if FOLLY_HAS_COROUTINES/, '#if 0 // FOLLY_HAS_COROUTINES disabled by Podfile patch') + File.write(folly_optional, contents) + puts "✅ Patched #{folly_optional} to disable coroutines" + end + # fix for Xcode 16 build issues installer.pods_project.targets.each do |target| target.build_configurations.each do |config| diff --git a/mobile-app/ios/Podfile.lock b/mobile-app/ios/Podfile.lock index 42a6e1a..3e613a8 100644 --- a/mobile-app/ios/Podfile.lock +++ b/mobile-app/ios/Podfile.lock @@ -296,6 +296,7 @@ PODS: - RCTTypeSafety - React-Codegen - React-Core + - React-NativeModulesApple - ReactCommon/turbomodule/core - RCT-Folly (2024.11.18.00): - boost @@ -2838,7 +2839,7 @@ SPEC CHECKSUMS: fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 hermes-engine: 35c763d57c9832d0eef764316ca1c4d043581394 - NimBridge: e3bf2fde48f7e6c5859d637c84b9e1c0d45cd781 + NimBridge: 70b6c653edd5f92ee764879f46a6b53ba51da94f RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669 RCTDeprecation: c0ed3249a97243002615517dff789bf4666cf585 RCTRequired: 58719f5124f9267b5f9649c08bf23d9aea845b23 @@ -2901,11 +2902,11 @@ SPEC CHECKSUMS: React-timing: 1e6a8acb66e2b7ac9d418956617fd1fdb19322fd React-utils: 52bbb03f130319ef82e4c3bc7a85eaacdb1fec87 ReactAppDependencyProvider: 433ddfb4536948630aadd5bd925aff8a632d2fe3 - ReactCodegen: 1d05923ad119796be9db37830d5e5dc76586aa00 + ReactCodegen: aded76e44f752489dfa4a3ec0d41df08dd3ac865 ReactCommon: 394c6b92765cf6d211c2c3f7f6bc601dffb316a6 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 Yoga: 922d794dce2af9c437f864bf4093abfa7a131adb -PODFILE CHECKSUM: 30222b370f2c6e2622deeb5e8d786e95202de871 +PODFILE CHECKSUM: 5548583703093faf0a61d6a070017162e1c2571a COCOAPODS: 1.16.2 diff --git a/mobile-app/modules/nim-bridge/NimBridge.podspec b/mobile-app/modules/nim-bridge/NimBridge.podspec index aa95040..14ac3eb 100644 --- a/mobile-app/modules/nim-bridge/NimBridge.podspec +++ b/mobile-app/modules/nim-bridge/NimBridge.podspec @@ -31,10 +31,10 @@ Pod::Spec.new do |s| # Don't install the dependencies when we run `pod install` in the old architecture. if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then - s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1" + s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1 -DFOLLY_HAS_COROUTINES=0" s.pod_target_xcconfig = { - "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"", - "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1", + "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_TARGET_SRCROOT)/../../build/generated/ios\" \"$(PODS_ROOT)/Headers/Public/React-NativeModulesApple\"", + "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_HAS_COROUTINES=0", "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" } s.dependency "React-Codegen" @@ -42,5 +42,6 @@ Pod::Spec.new do |s| s.dependency "RCTRequired" s.dependency "RCTTypeSafety" s.dependency "ReactCommon/turbomodule/core" + s.dependency "React-NativeModulesApple" end end \ No newline at end of file diff --git a/mobile-app/modules/nim-bridge/android/build.gradle b/mobile-app/modules/nim-bridge/android/build.gradle index 1545f50..bb57216 100644 --- a/mobile-app/modules/nim-bridge/android/build.gradle +++ b/mobile-app/modules/nim-bridge/android/build.gradle @@ -14,6 +14,7 @@ buildscript { apply plugin: 'com.android.library' apply plugin: 'kotlin-android' +apply plugin: 'com.facebook.react' def reactNativeArchitectures() { def value = project.getProperties().get("reactNativeArchitectures") @@ -21,6 +22,17 @@ def reactNativeArchitectures() { return value ? value.split(",") : ["x86_64", "arm64-v8a"] } +react { + // Point to the root project directory + root = file("../../../") + reactNativeDir = new File(["node", "--print", "require.resolve('react-native/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile() + codegenDir = new File(["node", "--print", "require.resolve('@react-native/codegen/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile() + + // Point to the module's src directory for codegen + libraryName = "NimBridge" + codegenJavaPackageName = "com.nimbridge" +} + android { compileSdkVersion 34 buildToolsVersion "34.0.0" diff --git a/mobile-app/modules/nim-bridge/android/src/main/java/com/nimbridge/NimBridgeModule.kt b/mobile-app/modules/nim-bridge/android/src/main/java/com/nimbridge/NimBridgeModule.kt index 675dcaa..9cef482 100644 --- a/mobile-app/modules/nim-bridge/android/src/main/java/com/nimbridge/NimBridgeModule.kt +++ b/mobile-app/modules/nim-bridge/android/src/main/java/com/nimbridge/NimBridgeModule.kt @@ -5,16 +5,15 @@ package com.nimbridge import com.facebook.react.bridge.ReactApplicationContext -import com.facebook.react.bridge.ReactContextBaseJavaModule -import com.facebook.react.bridge.ReactMethod import com.facebook.react.module.annotations.ReactModule +import com.nimbridge.NativeNimBridgeSpec @ReactModule(name = NimBridgeModule.NAME) -class NimBridgeModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { - +class NimBridgeModule(reactContext: ReactApplicationContext) : NativeNimBridgeSpec(reactContext) { + companion object { const val NAME = "NimBridge" - + init { try { System.loadLibrary("nim_functions") @@ -24,7 +23,7 @@ class NimBridgeModule(reactContext: ReactApplicationContext) : ReactContextBaseJ e.printStackTrace() } } - + @JvmStatic private external fun nativeHelloWorld(): String @JvmStatic @@ -44,75 +43,74 @@ class NimBridgeModule(reactContext: ReactApplicationContext) : ReactContextBaseJ @JvmStatic private external fun nativeGetNimCoreVersion(): String } - + override fun getName(): String = NAME - @ReactMethod(isBlockingSynchronousMethod = true) - fun helloWorld(): String { + override fun helloWorld(): String { return try { nativeHelloWorld() } catch (e: Exception) { "Error: ${e.message}" } } - @ReactMethod(isBlockingSynchronousMethod = true) - fun addNumbers(a: Double, b: Double): Double { + + override fun addNumbers(a: Double, b: Double): Double { return try { nativeAddNumbers(a.toInt(), b.toInt()).toDouble() } catch (e: Exception) { 0.0 } } - @ReactMethod(isBlockingSynchronousMethod = true) - fun getSystemInfo(): String { + + override fun getSystemInfo(): String { return try { nativeGetSystemInfo() } catch (e: Exception) { "Error: ${e.message}" } } - @ReactMethod(isBlockingSynchronousMethod = true) - fun mobileFibonacci(n: Double): Double { + + override fun fibonacci(n: Double): Double { return try { nativeMobileFibonacci(n.toInt()).toDouble() } catch (e: Exception) { 0.0 } } - @ReactMethod(isBlockingSynchronousMethod = true) - fun mobileIsPrime(n: Double): Double { + + override fun isPrime(n: Double): Boolean { return try { - nativeMobileIsPrime(n.toInt()).toDouble() + nativeMobileIsPrime(n.toInt()) != 0 } catch (e: Exception) { - 0.0 + false } } - @ReactMethod(isBlockingSynchronousMethod = true) - fun mobileFactorize(n: Double): String { + + override fun factorize(n: Double): String { return try { nativeMobileFactorize(n.toInt()) } catch (e: Exception) { "Error: ${e.message}" } } - @ReactMethod(isBlockingSynchronousMethod = true) - fun mobileCreateUser(id: Double, name: String, email: String): String { + + override fun createUser(id: Double, name: String, email: String): String { return try { nativeMobileCreateUser(id.toInt(), name, email) } catch (e: Exception) { "Error: ${e.message}" } } - @ReactMethod(isBlockingSynchronousMethod = true) - fun mobileValidateEmail(email: String): Double { + + override fun validateEmail(email: String): Boolean { return try { - nativeMobileValidateEmail(email).toDouble() + nativeMobileValidateEmail(email) != 0 } catch (e: Exception) { - 0.0 + false } } - @ReactMethod(isBlockingSynchronousMethod = true) - fun getNimCoreVersion(): String { + + override fun getVersion(): String { return try { nativeGetNimCoreVersion() } catch (e: Exception) { diff --git a/mobile-app/modules/nim-bridge/android/src/main/java/com/nimbridge/NimBridgePackage.kt b/mobile-app/modules/nim-bridge/android/src/main/java/com/nimbridge/NimBridgePackage.kt index 76ab8ed..43d53d9 100644 --- a/mobile-app/modules/nim-bridge/android/src/main/java/com/nimbridge/NimBridgePackage.kt +++ b/mobile-app/modules/nim-bridge/android/src/main/java/com/nimbridge/NimBridgePackage.kt @@ -4,18 +4,35 @@ package com.nimbridge -import com.facebook.react.ReactPackage +import com.facebook.react.TurboReactPackage import com.facebook.react.bridge.NativeModule import com.facebook.react.bridge.ReactApplicationContext -import com.facebook.react.uimanager.ViewManager +import com.facebook.react.module.model.ReactModuleInfo +import com.facebook.react.module.model.ReactModuleInfoProvider +import com.facebook.react.turbomodule.core.interfaces.TurboModule -class NimBridgePackage : ReactPackage { - - override fun createNativeModules(reactContext: ReactApplicationContext): List { - return listOf(NimBridgeModule(reactContext)) +class NimBridgePackage : TurboReactPackage() { + + override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? { + return if (name == NimBridgeModule.NAME) { + NimBridgeModule(reactContext) + } else { + null + } } - - override fun createViewManagers(reactContext: ReactApplicationContext): List> { - return emptyList() + + override fun getReactModuleInfoProvider(): ReactModuleInfoProvider { + return ReactModuleInfoProvider { + mapOf( + NimBridgeModule.NAME to ReactModuleInfo( + NimBridgeModule.NAME, + NimBridgeModule::class.java.name, + false, // canOverrideExistingModule + false, // needsEagerInit + true, // isCxxModule + true // isTurboModule + ) + ) + } } } \ No newline at end of file diff --git a/mobile-app/modules/nim-bridge/ios/NimBridge.h b/mobile-app/modules/nim-bridge/ios/NimBridge.h index 8d969a4..6217d56 100644 --- a/mobile-app/modules/nim-bridge/ios/NimBridge.h +++ b/mobile-app/modules/nim-bridge/ios/NimBridge.h @@ -4,6 +4,32 @@ #import -@interface NimBridge : NSObject +#ifdef RCT_NEW_ARCH_ENABLED +#include "NimBridgeSpecJSI.h" + +class NimBridgeImpl : public facebook::react::NativeNimBridgeCxxSpec { +public: + NimBridgeImpl(std::shared_ptr jsInvoker); + + // Core API + facebook::jsi::String helloWorld(facebook::jsi::Runtime &rt); + double addNumbers(facebook::jsi::Runtime &rt, double a, double b); + facebook::jsi::String getSystemInfo(facebook::jsi::Runtime &rt); + + // Math operations + double fibonacci(facebook::jsi::Runtime &rt, double n); + bool isPrime(facebook::jsi::Runtime &rt, double n); + facebook::jsi::String factorize(facebook::jsi::Runtime &rt, double n); + + // Data operations + facebook::jsi::String createUser(facebook::jsi::Runtime &rt, double id, facebook::jsi::String name, facebook::jsi::String email); + bool validateEmail(facebook::jsi::Runtime &rt, facebook::jsi::String email); + + // Version info + facebook::jsi::String getVersion(facebook::jsi::Runtime &rt); +}; +#endif + +@interface NimBridge : NSObject @end diff --git a/mobile-app/modules/nim-bridge/ios/NimBridge.mm b/mobile-app/modules/nim-bridge/ios/NimBridge.mm index a3b6778..fb2cc59 100644 --- a/mobile-app/modules/nim-bridge/ios/NimBridge.mm +++ b/mobile-app/modules/nim-bridge/ios/NimBridge.mm @@ -5,6 +5,69 @@ #import "NimBridge.h" #include "nim_functions.h" +#ifdef RCT_NEW_ARCH_ENABLED +#import + +NimBridgeImpl::NimBridgeImpl(std::shared_ptr jsInvoker) + : NativeNimBridgeCxxSpec(std::move(jsInvoker)) { + // Initialize Nim runtime + NimMain(); + mobileNimInit(); +} + +facebook::jsi::String NimBridgeImpl::helloWorld(facebook::jsi::Runtime &rt) { + NCSTRING result = ::helloWorld(); + std::string str = result ? std::string(result) : ""; + return facebook::jsi::String::createFromUtf8(rt, str); +} + +double NimBridgeImpl::addNumbers(facebook::jsi::Runtime &rt, double a, double b) { + return ::addNumbers(static_cast(a), static_cast(b)); +} + +facebook::jsi::String NimBridgeImpl::getSystemInfo(facebook::jsi::Runtime &rt) { + NCSTRING result = ::getSystemInfo(); + std::string str = result ? std::string(result) : ""; + if (result) freeString(result); + return facebook::jsi::String::createFromUtf8(rt, str); +} + +double NimBridgeImpl::fibonacci(facebook::jsi::Runtime &rt, double n) { + return static_cast(mobileFibonacci(static_cast(n))); +} + +bool NimBridgeImpl::isPrime(facebook::jsi::Runtime &rt, double n) { + return mobileIsPrime(static_cast(n)) != 0; +} + +facebook::jsi::String NimBridgeImpl::factorize(facebook::jsi::Runtime &rt, double n) { + NCSTRING result = mobileFactorize(static_cast(n)); + std::string str = result ? std::string(result) : ""; + if (result) freeString(result); + return facebook::jsi::String::createFromUtf8(rt, str); +} + +facebook::jsi::String NimBridgeImpl::createUser(facebook::jsi::Runtime &rt, double id, facebook::jsi::String name, facebook::jsi::String email) { + std::string nameStr = name.utf8(rt); + std::string emailStr = email.utf8(rt); + NCSTRING result = mobileCreateUser(static_cast(id), const_cast(nameStr.c_str()), const_cast(emailStr.c_str())); + std::string str = result ? std::string(result) : ""; + if (result) freeString(result); + return facebook::jsi::String::createFromUtf8(rt, str); +} + +bool NimBridgeImpl::validateEmail(facebook::jsi::Runtime &rt, facebook::jsi::String email) { + std::string emailStr = email.utf8(rt); + return mobileValidateEmail(const_cast(emailStr.c_str())) != 0; +} + +facebook::jsi::String NimBridgeImpl::getVersion(facebook::jsi::Runtime &rt) { + NCSTRING result = getNimCoreVersion(); + std::string str = result ? std::string(result) : ""; + return facebook::jsi::String::createFromUtf8(rt, str); +} +#endif + @implementation NimBridge RCT_EXPORT_MODULE() @@ -14,13 +77,22 @@ + (BOOL)requiresMainQueueSetup return NO; } +#ifdef RCT_NEW_ARCH_ENABLED +- (std::shared_ptr)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params +{ + return std::make_shared(params.jsInvoker); +} +#endif + - (instancetype)init { self = [super init]; if (self) { - // Initialize Nim runtime +#ifndef RCT_NEW_ARCH_ENABLED + // Initialize Nim runtime only for old arch NimMain(); mobileNimInit(); +#endif } return self; } diff --git a/mobile-app/modules/nim-bridge/package.json b/mobile-app/modules/nim-bridge/package.json index 040bae1..82e40b4 100644 --- a/mobile-app/modules/nim-bridge/package.json +++ b/mobile-app/modules/nim-bridge/package.json @@ -18,5 +18,13 @@ }, "peerDependencies": { "react-native": "*" + }, + "codegenConfig": { + "name": "NimBridgeSpec", + "type": "modules", + "jsSrcsDir": "src", + "android": { + "javaPackageName": "com.nimbridge" + } } } \ No newline at end of file diff --git a/mobile-app/modules/nim-bridge/src/NativeNimBridge.ts b/mobile-app/modules/nim-bridge/src/NativeNimBridge.ts new file mode 100644 index 0000000..de873c5 --- /dev/null +++ b/mobile-app/modules/nim-bridge/src/NativeNimBridge.ts @@ -0,0 +1,23 @@ +import type { TurboModule } from 'react-native'; +import { TurboModuleRegistry } from 'react-native'; + +export interface Spec extends TurboModule { + // Core API + readonly helloWorld: () => string; + readonly addNumbers: (a: number, b: number) => number; + readonly getSystemInfo: () => string; + + // Math operations + readonly fibonacci: (n: number) => number; + readonly isPrime: (n: number) => boolean; + readonly factorize: (n: number) => string; + + // Data operations + readonly createUser: (id: number, name: string, email: string) => string; + readonly validateEmail: (email: string) => boolean; + + // Version info + readonly getVersion: () => string; +} + +export default TurboModuleRegistry.getEnforcing('NimBridge'); \ No newline at end of file diff --git a/mobile-app/modules/nim-bridge/src/index.ts b/mobile-app/modules/nim-bridge/src/index.ts index 412a047..ae9a482 100644 --- a/mobile-app/modules/nim-bridge/src/index.ts +++ b/mobile-app/modules/nim-bridge/src/index.ts @@ -1,52 +1,35 @@ -import { NativeModules, Platform } from 'react-native'; - -const LINKING_ERROR = - `The package 'nim-bridge' doesn't seem to be linked. Make sure: \n\n` + - Platform.select({ ios: "- You have run 'cd ios && pod install'\n", default: '' }) + - '- You rebuilt the app after installing the package\n' + - '- You are not using Expo Go\n'; - -const NimBridge = NativeModules.NimBridge - ? NativeModules.NimBridge - : new Proxy( - {}, - { - get() { - throw new Error(LINKING_ERROR); - }, - } - ); +import NativeNimBridge from './NativeNimBridge'; export interface NimCore { // Core API helloWorld(): string; addNumbers(a: number, b: number): number; getSystemInfo(): string; - + // Math operations fibonacci(n: number): number; isPrime(n: number): boolean; factorize(n: number): string; - + // Data operations createUser(id: number, name: string, email: string): string; validateEmail(email: string): boolean; - + // Version info getVersion(): string; } export const NimCore: NimCore = { - helloWorld: () => NimBridge.helloWorld(), - addNumbers: (a: number, b: number) => NimBridge.addNumbers(a, b), - getSystemInfo: () => NimBridge.getSystemInfo(), - fibonacci: (n: number) => NimBridge.mobileFibonacci(n), - isPrime: (n: number) => Boolean(NimBridge.mobileIsPrime(n)), - factorize: (n: number) => NimBridge.mobileFactorize(n), - createUser: (id: number, name: string, email: string) => - NimBridge.mobileCreateUser(id, name, email), - validateEmail: (email: string) => Boolean(NimBridge.mobileValidateEmail(email)), - getVersion: () => NimBridge.getNimCoreVersion(), + helloWorld: () => NativeNimBridge.helloWorld(), + addNumbers: (a: number, b: number) => NativeNimBridge.addNumbers(a, b), + getSystemInfo: () => NativeNimBridge.getSystemInfo(), + fibonacci: (n: number) => NativeNimBridge.fibonacci(n), + isPrime: (n: number) => NativeNimBridge.isPrime(n), + factorize: (n: number) => NativeNimBridge.factorize(n), + createUser: (id: number, name: string, email: string) => + NativeNimBridge.createUser(id, name, email), + validateEmail: (email: string) => NativeNimBridge.validateEmail(email), + getVersion: () => NativeNimBridge.getVersion(), }; export default NimCore; \ No newline at end of file diff --git a/mobile-app/package.json b/mobile-app/package.json index 5c47923..7e1af4e 100644 --- a/mobile-app/package.json +++ b/mobile-app/package.json @@ -54,5 +54,13 @@ "cross-platform" ], "author": "Nim-RN Team", - "license": "MIT" + "license": "MIT", + "codegenConfig": { + "name": "NimBridgeSpec", + "type": "modules", + "jsSrcsDir": "modules/nim-bridge/src", + "android": { + "javaPackageName": "com.nimbridge" + } + } } From 52508b70092f0f7fd5ab28ffc0161d8f32d0d43f Mon Sep 17 00:00:00 2001 From: Siddarth Kumar Date: Tue, 30 Sep 2025 17:46:31 +0530 Subject: [PATCH 2/6] generators: modify for turbo modules --- .../java/com/nimbridge/NimBridgeModule.kt | 3 +- mobile-app/modules/nim-bridge/ios/NimBridge.h | 3 - .../modules/nim-bridge/ios/NimBridge.mm | 80 +----- .../modules/nim-bridge/ios/nim_functions.h | 4 +- .../tools/bindings/generators/android.py | 75 ++++-- mobile-app/tools/bindings/generators/ios.py | 250 +++++++++++++----- .../tools/bindings/generators/typescript.py | 54 +++- mobile-app/tools/bindings/models.py | 19 +- mobile-app/tools/bindings/orchestrator.py | 25 +- mobile-app/tools/generator_config.json | 27 +- 10 files changed, 314 insertions(+), 226 deletions(-) diff --git a/mobile-app/modules/nim-bridge/android/src/main/java/com/nimbridge/NimBridgeModule.kt b/mobile-app/modules/nim-bridge/android/src/main/java/com/nimbridge/NimBridgeModule.kt index 9cef482..2cd58b6 100644 --- a/mobile-app/modules/nim-bridge/android/src/main/java/com/nimbridge/NimBridgeModule.kt +++ b/mobile-app/modules/nim-bridge/android/src/main/java/com/nimbridge/NimBridgeModule.kt @@ -43,9 +43,10 @@ class NimBridgeModule(reactContext: ReactApplicationContext) : NativeNimBridgeSp @JvmStatic private external fun nativeGetNimCoreVersion(): String } - + override fun getName(): String = NAME + override fun helloWorld(): String { return try { nativeHelloWorld() diff --git a/mobile-app/modules/nim-bridge/ios/NimBridge.h b/mobile-app/modules/nim-bridge/ios/NimBridge.h index 6217d56..ee4c2f0 100644 --- a/mobile-app/modules/nim-bridge/ios/NimBridge.h +++ b/mobile-app/modules/nim-bridge/ios/NimBridge.h @@ -3,8 +3,6 @@ // This file will be overwritten when bindings are regenerated #import - -#ifdef RCT_NEW_ARCH_ENABLED #include "NimBridgeSpecJSI.h" class NimBridgeImpl : public facebook::react::NativeNimBridgeCxxSpec { @@ -28,7 +26,6 @@ class NimBridgeImpl : public facebook::react::NativeNimBridgeCxxSpec diff --git a/mobile-app/modules/nim-bridge/ios/NimBridge.mm b/mobile-app/modules/nim-bridge/ios/NimBridge.mm index fb2cc59..b6571ae 100644 --- a/mobile-app/modules/nim-bridge/ios/NimBridge.mm +++ b/mobile-app/modules/nim-bridge/ios/NimBridge.mm @@ -4,8 +4,6 @@ #import "NimBridge.h" #include "nim_functions.h" - -#ifdef RCT_NEW_ARCH_ENABLED #import NimBridgeImpl::NimBridgeImpl(std::shared_ptr jsInvoker) @@ -66,7 +64,7 @@ std::string str = result ? std::string(result) : ""; return facebook::jsi::String::createFromUtf8(rt, str); } -#endif + @implementation NimBridge @@ -77,90 +75,14 @@ + (BOOL)requiresMainQueueSetup return NO; } -#ifdef RCT_NEW_ARCH_ENABLED - (std::shared_ptr)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params { return std::make_shared(params.jsInvoker); } -#endif - -- (instancetype)init -{ - self = [super init]; - if (self) { -#ifndef RCT_NEW_ARCH_ENABLED - // Initialize Nim runtime only for old arch - NimMain(); - mobileNimInit(); -#endif - } - return self; -} - (void)dealloc { mobileNimShutdown(); } -// Generated method exports -RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, helloWorld) -{ - NCSTRING result = helloWorld(); - return result ? [NSString stringWithUTF8String:result] : @""; -} - -RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, addNumbers:(nonnull NSNumber *)a withB:(nonnull NSNumber *)b) -{ - int result = addNumbers([a intValue], [b intValue]); - return @(result); -} - -RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, getSystemInfo) -{ - NCSTRING result = getSystemInfo(); - NSString *objcString = result ? [NSString stringWithUTF8String:result] : @""; - if (result) freeString(result); - return objcString; -} - -RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, mobileFibonacci:(nonnull NSNumber *)n) -{ - long long result = mobileFibonacci([n intValue]); - return @(result); -} - -RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, mobileIsPrime:(nonnull NSNumber *)n) -{ - int result = mobileIsPrime([n intValue]); - return @(result); -} - -RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, mobileFactorize:(nonnull NSNumber *)n) -{ - NCSTRING result = mobileFactorize([n intValue]); - NSString *objcString = result ? [NSString stringWithUTF8String:result] : @""; - if (result) freeString(result); - return objcString; -} - -RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, mobileCreateUser:(nonnull NSNumber *)id withName:(nonnull NSString *)name withEmail:(nonnull NSString *)email) -{ - NCSTRING result = mobileCreateUser([id intValue], (NCSTRING)[name UTF8String], (NCSTRING)[email UTF8String]); - NSString *objcString = result ? [NSString stringWithUTF8String:result] : @""; - if (result) freeString(result); - return objcString; -} - -RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, mobileValidateEmail:(nonnull NSString *)email) -{ - int result = mobileValidateEmail((NCSTRING)[email UTF8String]); - return @(result); -} - -RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, getNimCoreVersion) -{ - NCSTRING result = getNimCoreVersion(); - return result ? [NSString stringWithUTF8String:result] : @""; -} - @end diff --git a/mobile-app/modules/nim-bridge/ios/nim_functions.h b/mobile-app/modules/nim-bridge/ios/nim_functions.h index 3d243bc..58ba38b 100644 --- a/mobile-app/modules/nim-bridge/ios/nim_functions.h +++ b/mobile-app/modules/nim-bridge/ios/nim_functions.h @@ -7,12 +7,12 @@ extern "C" { typedef char* NCSTRING; - + // Nim runtime void NimMain(void); void mobileNimInit(void); void mobileNimShutdown(void); - + // Generated function declarations NCSTRING helloWorld(); int addNumbers(int a, int b); diff --git a/mobile-app/tools/bindings/generators/android.py b/mobile-app/tools/bindings/generators/android.py index 84c1caa..9908ad4 100644 --- a/mobile-app/tools/bindings/generators/android.py +++ b/mobile-app/tools/bindings/generators/android.py @@ -24,21 +24,20 @@ def generate(self) -> str: return code def _generate_kotlin_header(self) -> str: - """Generate the Kotlin module header.""" + """Generate the Kotlin module header with TurboModule support.""" header = self._generate_header("Kotlin module for Nim bridge") return f"""{header}package {self.config.package_name} import com.facebook.react.bridge.ReactApplicationContext -import com.facebook.react.bridge.ReactContextBaseJavaModule -import com.facebook.react.bridge.ReactMethod import com.facebook.react.module.annotations.ReactModule +import {self.config.package_name}.Native{self.config.module_name}Spec @ReactModule(name = {self.config.module_name}Module.NAME) -class {self.config.module_name}Module(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {{ - +class {self.config.module_name}Module(reactContext: ReactApplicationContext) : Native{self.config.module_name}Spec(reactContext) {{ + companion object {{ const val NAME = "{self.config.module_name}" - + init {{ try {{ System.loadLibrary("{self.config.library_name}") @@ -48,7 +47,7 @@ class {self.config.module_name}Module(reactContext: ReactApplicationContext) : R e.printStackTrace() }} }} - + """ def _generate_native_declarations(self) -> str: @@ -63,20 +62,29 @@ def _generate_native_declarations(self) -> str: return declarations def _generate_kotlin_methods(self) -> str: - """Generate Kotlin React methods.""" + """Generate Kotlin TurboModule override methods.""" methods = "" for func in self.functions: + js_name = func.js_name or func.name params_str = self._build_kotlin_method_params(func) - ret_type = "String" if func.return_type in ['cstring', 'string'] else "Double" + ret_type = self._get_kotlin_return_type(func.return_type) - methods += f" @ReactMethod(isBlockingSynchronousMethod = true)\n" - methods += f" fun {func.name}({params_str}): {ret_type} {{\n" + methods += f"\n override fun {js_name}({params_str}): {ret_type} {{\n" methods += f" return try {{\n" methods += self._generate_kotlin_method_call(func) methods += self._generate_kotlin_error_handling(func) methods += f" }}\n" return methods + def _get_kotlin_return_type(self, nim_type: str) -> str: + """Get Kotlin return type for TurboModule spec.""" + if nim_type in ['cstring', 'string']: + return "String" + elif nim_type == 'bool': + return "Boolean" + else: + return "Double" + @staticmethod def _get_kotlin_native_return_type(nim_type: str) -> str: """Get the native return type for Kotlin.""" @@ -123,7 +131,11 @@ def _generate_kotlin_method_call(self, func: NimFunction) -> str: args_str = ', '.join(args) method_name = f"native{func.name[0].upper() + func.name[1:]}" - if func.return_type in ['cstring', 'string']: + + # Generate return based on return type + if func.return_type == 'bool': + return f" {method_name}({args_str}) != 0\n" + elif func.return_type in ['cstring', 'string']: return f" {method_name}({args_str})\n" else: return f" {method_name}({args_str}).toDouble()\n" @@ -131,7 +143,9 @@ def _generate_kotlin_method_call(self, func: NimFunction) -> str: def _generate_kotlin_error_handling(self, func: NimFunction) -> str: """Generate error handling for Kotlin method.""" error_code = " } catch (e: Exception) {\n" - if func.return_type in ['cstring', 'string']: + if func.return_type == 'bool': + error_code += " false\n" + elif func.return_type in ['cstring', 'string']: error_code += ' "Error: ${e.message}"\n' else: error_code += " 0.0\n" @@ -150,19 +164,36 @@ def generate(self) -> str: header = CodeGenerator._generate_header("Kotlin package for Nim bridge") return f"""{header}package {self.config.package_name} -import com.facebook.react.ReactPackage +import com.facebook.react.TurboReactPackage import com.facebook.react.bridge.NativeModule import com.facebook.react.bridge.ReactApplicationContext -import com.facebook.react.uimanager.ViewManager +import com.facebook.react.module.model.ReactModuleInfo +import com.facebook.react.module.model.ReactModuleInfoProvider +import com.facebook.react.turbomodule.core.interfaces.TurboModule + +class {self.config.module_name}Package : TurboReactPackage() {{ -class {self.config.module_name}Package : ReactPackage {{ - - override fun createNativeModules(reactContext: ReactApplicationContext): List {{ - return listOf({self.config.module_name}Module(reactContext)) + override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {{ + return if (name == {self.config.module_name}Module.NAME) {{ + {self.config.module_name}Module(reactContext) + }} else {{ + null + }} }} - - override fun createViewManagers(reactContext: ReactApplicationContext): List> {{ - return emptyList() + + override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {{ + return ReactModuleInfoProvider {{ + mapOf( + {self.config.module_name}Module.NAME to ReactModuleInfo( + {self.config.module_name}Module.NAME, + {self.config.module_name}Module::class.java.name, + false, // canOverrideExistingModule + false, // needsEagerInit + true, // isCxxModule + true // isTurboModule + ) + ) + }} }} }}""" diff --git a/mobile-app/tools/bindings/generators/ios.py b/mobile-app/tools/bindings/generators/ios.py index 4908cfd..7dbdd42 100644 --- a/mobile-app/tools/bindings/generators/ios.py +++ b/mobile-app/tools/bindings/generators/ios.py @@ -1,5 +1,5 @@ """ -iOS platform generators for Nim bridge (Objective-C++). +iOS platform generators for Nim bridge with TurboModule/JSI support. """ from .base import CodeGenerator @@ -17,20 +17,24 @@ def generate(self) -> str: extern "C" { typedef char* NCSTRING; - + // Nim runtime void NimMain(void); void mobileNimInit(void); void mobileNimShutdown(void); - + // Generated function declarations """ # Add function declarations for func in self.functions: ret_type = self.type_mapper.nim_to_cpp_type(func.return_type) - params_str = ', '.join([f"{self.type_mapper.nim_to_cpp_type(ptype)} {name}" - for name, ptype in func.params]) + params_str = ", ".join( + [ + f"{self.type_mapper.nim_to_cpp_type(ptype)} {name}" + for name, ptype in func.params + ] + ) code += f" {ret_type} {func.name}({params_str});\n" code += " \n // Memory management\n" @@ -41,30 +45,118 @@ def generate(self) -> str: class ObjcHeaderGenerator(CodeGenerator): - """Generates Objective-C header file.""" + """Generates Objective-C header file with TurboModule/JSI support.""" def generate(self) -> str: - """Generate Objective-C header file.""" + """Generate Objective-C header file for New Architecture.""" code = CodeGenerator._generate_header("Objective-C++ bridge header") + code += """#import +#include "NimBridgeSpecJSI.h" -@interface NimBridge : NSObject +class NimBridgeImpl : public facebook::react::NativeNimBridgeCxxSpec { +public: + NimBridgeImpl(std::shared_ptr jsInvoker); -@end """ + + # Group functions for comments + core_funcs = [] + math_funcs = [] + data_funcs = [] + version_funcs = [] + + for func in self.functions: + js_name = func.js_name or func.name + if js_name in ["helloWorld", "addNumbers", "getSystemInfo"]: + core_funcs.append(func) + elif js_name in ["fibonacci", "isPrime", "factorize"]: + math_funcs.append(func) + elif js_name in ["createUser", "validateEmail"]: + data_funcs.append(func) + elif js_name in ["getVersion"]: + version_funcs.append(func) + + def generate_declarations(funcs, comment=None): + result = "" + if comment: + result += f" // {comment}\n" + for func in funcs: + js_name = func.js_name or func.name + jsi_ret_type = self._get_jsi_return_type(func.return_type) + jsi_params = self._build_jsi_params(func) + result += f" {jsi_ret_type} {js_name}(facebook::jsi::Runtime &rt{', ' + jsi_params if jsi_params else ''});\n" + return result + + code += generate_declarations(core_funcs, "Core API") + if math_funcs: + code += "\n" + code += generate_declarations(math_funcs, "Math operations") + if data_funcs: + code += "\n" + code += generate_declarations(data_funcs, "Data operations") + if version_funcs: + code += "\n" + code += generate_declarations(version_funcs, "Version info") + + code += """};\n\n""" + code += f"""@interface {self.config.module_name} : NSObject \n\n@end\n""" return code + def _get_jsi_return_type(self, nim_type: str) -> str: + """Get JSI return type for a Nim type.""" + if nim_type in ["cstring", "string"]: + return "facebook::jsi::String" + elif nim_type == "bool": + return "bool" + elif nim_type in ["cint", "int", "int64"]: + return "double" + else: + return "double" + + def _build_jsi_params(self, func: NimFunction) -> str: + """Build JSI parameter list.""" + params = [] + for name, ptype in func.params: + if ptype in ["cstring", "string"]: + params.append(f"facebook::jsi::String {name}") + elif ptype == "bool": + params.append(f"bool {name}") + else: + params.append(f"double {name}") + return ", ".join(params) + class ObjcBridgeGenerator(CodeGenerator): - """Generates Objective-C++ bridge code.""" + """Generates Objective-C++ bridge code with TurboModule/JSI support.""" def generate(self) -> str: - """Generate Objective-C++ bridge code.""" + """Generate Objective-C++ bridge code for New Architecture.""" code = CodeGenerator._generate_header("Objective-C++ bridge") - code += """#import "NimBridge.h" -#include "nim_functions.h" + code += f"""#import "{self.config.module_name}.h" +#include "{self.config.library_name}.h" +#import -@implementation NimBridge +{self.config.module_name}Impl::{self.config.module_name}Impl(std::shared_ptr jsInvoker) + : Native{self.config.module_name}CxxSpec(std::move(jsInvoker)) {{ + // Initialize Nim runtime + NimMain(); + mobileNimInit(); +}} + +""" + + # Generate JSI method implementations + for i, func in enumerate(self.functions): + code += self._generate_jsi_method( + func, is_last=(i == len(self.functions) - 1) + ) + + code += ( + """ +@implementation """ + + self.config.module_name + + """ RCT_EXPORT_MODULE() @@ -73,15 +165,11 @@ def generate(self) -> str: return NO; } -- (instancetype)init +- (std::shared_ptr)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params { - self = [super init]; - if (self) { - // Initialize Nim runtime - NimMain(); - mobileNimInit(); - } - return self; + return std::make_shared<""" + + self.config.module_name + + """Impl>(params.jsInvoker); } - (void)dealloc @@ -89,69 +177,85 @@ def generate(self) -> str: mobileNimShutdown(); } -// Generated method exports +@end """ - - for func in self.functions: - code += self._generate_objc_method(func) - - code += "@end\n" + ) return code - def _generate_objc_method(self, func: NimFunction) -> str: - """Generate a single Objective-C method.""" - ret_type = self.type_mapper.nim_to_objc_type(func.return_type) + def _generate_jsi_method(self, func: NimFunction, is_last: bool = False) -> str: + """Generate JSI method implementation for New Architecture.""" + js_name = func.js_name or func.name + ret_type = self._get_jsi_return_type(func.return_type) + params_str = self._build_jsi_params(func) - # Build method signature - if not func.params: - method_sig = func.name - else: - parts = [] - for i, (name, ptype) in enumerate(func.params): - objc_type = self.type_mapper.nim_to_objc_type(ptype) - if i == 0: - parts.append(f"{func.name}:(nonnull {objc_type}){name}") - else: - parts.append(f"with{name.capitalize()}:(nonnull {objc_type}){name}") - method_sig = ' '.join(parts) - - method_code = f"RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD({ret_type}, {method_sig})\n" - method_code += "{\n" - method_code += self._generate_objc_method_body(func) - method_code += "}\n\n" + method_code = f"{ret_type} {self.config.module_name}Impl::{js_name}(facebook::jsi::Runtime &rt" + if params_str: + method_code += f", {params_str}" + method_code += ") {\n" + + # Generate method body + method_code += self._generate_jsi_method_body(func, js_name) + # Last method gets one blank line, others get two + method_code += "}\n\n" if not is_last else "}\n\n" return method_code - def _generate_objc_method_body(self, func: NimFunction) -> str: - """Generate the body of an Objective-C method.""" - args = self._build_objc_args(func) + def _generate_jsi_method_body(self, func: NimFunction, js_name: str) -> str: + """Generate the body of a JSI method.""" + body = "" - if func.return_type in ['cstring', 'string']: - body = f" NCSTRING result = {func.name}({args});\n" - if func.memory_type == 'allocated': - body += f" NSString *objcString = result ? [NSString stringWithUTF8String:result] : @\"\";\n" - body += f" if (result) freeString(result);\n" - body += f" return objcString;\n" + # Convert JSI parameters to C types and build arguments + args = [] + for name, ptype in func.params: + if ptype in ["cstring", "string"]: + body += f" std::string {name}Str = {name}.utf8(rt);\n" + args.append(f"const_cast({name}Str.c_str())") + elif ptype in ["cint", "int", "int64"]: + args.append(f"static_cast({name})") else: - body += f" return result ? [NSString stringWithUTF8String:result] : @\"\";\n" - elif func.return_type == 'int64': - body = f" long long result = {func.name}({args});\n" - body += f" return @(result);\n" + args.append(name) + + args_str = ", ".join(args) + + # Generate return statement based on return type + # Use :: prefix only when Nim name == JS name to avoid ambiguity + prefix = "::" if func.name == js_name else "" + + if func.return_type in ["cstring", "string"]: + body += f" NCSTRING result = {prefix}{func.name}({args_str});\n" + body += f' std::string str = result ? std::string(result) : "";\n' + if func.memory_type == "allocated": + body += f" if (result) freeString(result);\n" + body += f" return facebook::jsi::String::createFromUtf8(rt, str);\n" + elif func.return_type == "bool": + body += f" return {prefix}{func.name}({args_str}) != 0;\n" + elif func.return_type == "int64": + body += ( + f" return static_cast({prefix}{func.name}({args_str}));\n" + ) else: - body = f" int result = {func.name}({args});\n" - body += f" return @(result);\n" + body += f" return {prefix}{func.name}({args_str});\n" return body - @staticmethod - def _build_objc_args(func: NimFunction) -> str: - """Build argument list for Objective-C method call.""" - args = [] + def _get_jsi_return_type(self, nim_type: str) -> str: + """Get JSI return type.""" + if nim_type in ["cstring", "string"]: + return "facebook::jsi::String" + elif nim_type == "bool": + return "bool" + else: + return "double" + + def _build_jsi_params(self, func: NimFunction) -> str: + """Build JSI parameter list.""" + params = [] for name, ptype in func.params: - if ptype in ['cstring', 'string']: - args.append(f"(NCSTRING)[{name} UTF8String]") - elif ptype in ['cint', 'int']: - args.append(f"[{name} intValue]") + if ptype in ["cstring", "string"]: + params.append(f"facebook::jsi::String {name}") + elif ptype == "bool": + params.append(f"bool {name}") else: - args.append(name) - return ', '.join(args) \ No newline at end of file + params.append(f"double {name}") + return ", ".join(params) + diff --git a/mobile-app/tools/bindings/generators/typescript.py b/mobile-app/tools/bindings/generators/typescript.py index 907e3d8..b383d4e 100644 --- a/mobile-app/tools/bindings/generators/typescript.py +++ b/mobile-app/tools/bindings/generators/typescript.py @@ -6,18 +6,54 @@ class TypeScriptInterfaceGenerator(CodeGenerator): - """Generates TypeScript interface definitions.""" + """Generates TypeScript TurboModule spec definitions.""" def generate(self) -> str: - """Generate TypeScript interface.""" - code = CodeGenerator._generate_header("TypeScript interface for Nim bridge") - code += "export interface NimBridge {\n" + """Generate TypeScript TurboModule spec.""" + code = "import type { TurboModule } from 'react-native';\n" + code += "import { TurboModuleRegistry } from 'react-native';\n\n" + code += "export interface Spec extends TurboModule {\n" + + # Group functions for comments + core_funcs = [] + math_funcs = [] + data_funcs = [] + version_funcs = [] for func in self.functions: - ret_type = self.type_mapper.nim_to_ts_type(func.return_type) - params_str = ', '.join([f"{name}: {self.type_mapper.nim_to_ts_type(ptype)}" - for name, ptype in func.params]) - code += f" {func.name}({params_str}): {ret_type};\n" + js_name = func.js_name or func.name + if js_name in ['helloWorld', 'addNumbers', 'getSystemInfo']: + core_funcs.append(func) + elif js_name in ['fibonacci', 'isPrime', 'factorize']: + math_funcs.append(func) + elif js_name in ['createUser', 'validateEmail']: + data_funcs.append(func) + elif js_name in ['getVersion']: + version_funcs.append(func) + + def generate_functions(funcs, comment=None): + result = "" + if comment: + result += f" // {comment}\n" + for func in funcs: + js_name = func.js_name or func.name + ret_type = self.type_mapper.nim_to_ts_type(func.return_type) + params_str = ', '.join([f"{name}: {self.type_mapper.nim_to_ts_type(ptype)}" + for name, ptype in func.params]) + result += f" readonly {js_name}: ({params_str}) => {ret_type};\n" + return result + + code += generate_functions(core_funcs, "Core API") + if math_funcs: + code += "\n" + code += generate_functions(math_funcs, "Math operations") + if data_funcs: + code += "\n" + code += generate_functions(data_funcs, "Data operations") + if version_funcs: + code += "\n" + code += generate_functions(version_funcs, "Version info") - code += "}\n" + code += "}\n\n" + code += f"export default TurboModuleRegistry.getEnforcing('{self.config.module_name}');" return code \ No newline at end of file diff --git a/mobile-app/tools/bindings/models.py b/mobile-app/tools/bindings/models.py index 3d1c15f..05596ce 100644 --- a/mobile-app/tools/bindings/models.py +++ b/mobile-app/tools/bindings/models.py @@ -15,31 +15,22 @@ class NimFunction: return_type: str params: List[Tuple[str, str]] # List of (name, type) tuples memory_type: Optional[str] = None # 'literal' or 'allocated' for string returns + js_name: Optional[str] = None # Optional JavaScript/TypeScript name mapping class TypeMapper: """Handles type conversions between Nim and target languages.""" - + def __init__(self, config: GeneratorConfig): self.config = config self.type_mappings = config.data.get('type_mappings', {}) - + def nim_to_cpp_type(self, nim_type: str) -> str: """Convert Nim type to C++ type.""" cpp_mappings = self.type_mappings.get('cpp', {}) return cpp_mappings.get(nim_type, nim_type) - - def nim_to_objc_type(self, nim_type: str) -> str: - """Convert Nim type to Objective-C type.""" - objc_mappings = self.type_mappings.get('objc', {}) - return objc_mappings.get(nim_type, 'id') - + def nim_to_ts_type(self, nim_type: str) -> str: """Convert Nim type to TypeScript type.""" ts_mappings = self.type_mappings.get('typescript', {}) - return ts_mappings.get(nim_type, 'any') - - def nim_to_kotlin_type(self, nim_type: str) -> str: - """Convert Nim type to Kotlin type.""" - kotlin_mappings = self.type_mappings.get('kotlin', {}) - return kotlin_mappings.get(nim_type, 'String') \ No newline at end of file + return ts_mappings.get(nim_type, 'any') \ No newline at end of file diff --git a/mobile-app/tools/bindings/orchestrator.py b/mobile-app/tools/bindings/orchestrator.py index b7de4d3..ee88959 100644 --- a/mobile-app/tools/bindings/orchestrator.py +++ b/mobile-app/tools/bindings/orchestrator.py @@ -43,6 +43,21 @@ def discover_functions(self) -> bool: print("No exported functions found!") return False + # Apply function name mappings from config + name_mappings = self.config.data.get('function_name_mappings', {}) + boolean_returns = self.config.data.get('boolean_returns', []) + + for func in self.functions: + # Apply name mapping + if func.name in name_mappings: + func.js_name = name_mappings[func.name] + else: + func.js_name = func.name + + # Mark functions that should return booleans + if func.name in boolean_returns: + func.return_type = 'bool' + return True def generate_all(self) -> None: @@ -60,9 +75,9 @@ def generate_all(self) -> None: }) if self.config.generate_typescript: - generators["TypeScript interface"] = ( + generators["TypeScript TurboModule spec"] = ( TypeScriptInterfaceGenerator(self.functions, self.config), - self.output_dir / "src" / f"{self.config.module_name}.types.ts" + self.output_dir / "src" / f"Native{self.config.module_name}.ts" ) if self.config.generate_android: @@ -92,9 +107,9 @@ def print_summary(self) -> None: print(f"\n✅ Successfully generated bindings for {len(self.functions)} functions!") print("\nGenerated files:") print(" iOS: nim_functions.h, NimBridge.h, NimBridge.mm") - print(" Android: NimBridgeModule.kt, NimBridgePackage.kt, NimBridge.cpp") - print(" TypeScript: NimBridge.types.ts") + print(" Android: NimBridgeModule.kt, NimBridgePackage.kt, NimBridge.cpp, CMakeLists.txt") + print(" TypeScript: NativeNimBridge.ts (TurboModule spec)") print("\nNext steps:") print("1. Review the generated files") - print("2. Run 'pod install' in ios/ directory") + print("2. Run 'pod install' in ios/ directory (for iOS)") print("3. Rebuild the app") \ No newline at end of file diff --git a/mobile-app/tools/generator_config.json b/mobile-app/tools/generator_config.json index 7729bca..73f68a3 100644 --- a/mobile-app/tools/generator_config.json +++ b/mobile-app/tools/generator_config.json @@ -7,6 +7,15 @@ "generate_ios": true, "generate_android": true, "generate_typescript": true, + "function_name_mappings": { + "mobileFibonacci": "fibonacci", + "mobileIsPrime": "isPrime", + "mobileFactorize": "factorize", + "mobileCreateUser": "createUser", + "mobileValidateEmail": "validateEmail", + "getNimCoreVersion": "getVersion" + }, + "boolean_returns": ["mobileIsPrime", "mobileValidateEmail"], "type_mappings": { "cpp": { "cstring": "NCSTRING", @@ -17,15 +26,6 @@ "bool": "int", "float": "double" }, - "objc": { - "cstring": "NSString *", - "string": "NSString *", - "cint": "NSNumber *", - "int": "NSNumber *", - "int64": "NSNumber *", - "bool": "NSNumber *", - "float": "NSNumber *" - }, "typescript": { "cstring": "string", "string": "string", @@ -34,15 +34,6 @@ "int64": "number", "bool": "boolean", "float": "number" - }, - "kotlin": { - "cstring": "String", - "string": "String", - "cint": "Double", - "int": "Double", - "int64": "Double", - "bool": "Double", - "float": "Double" } }, "cmake": { From b0bfccc020cd098e2ea3afa76037ec77d766fd5a Mon Sep 17 00:00:00 2001 From: Siddarth Kumar Date: Tue, 30 Sep 2025 23:06:28 +0530 Subject: [PATCH 3/6] ci: fix android build --- .../modules/nim-bridge/android/build.gradle | 20 ++++++++++--------- mobile-app/package.json | 10 +--------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/mobile-app/modules/nim-bridge/android/build.gradle b/mobile-app/modules/nim-bridge/android/build.gradle index bb57216..e868ba3 100644 --- a/mobile-app/modules/nim-bridge/android/build.gradle +++ b/mobile-app/modules/nim-bridge/android/build.gradle @@ -23,14 +23,9 @@ def reactNativeArchitectures() { } react { - // Point to the root project directory - root = file("../../../") - reactNativeDir = new File(["node", "--print", "require.resolve('react-native/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile() - codegenDir = new File(["node", "--print", "require.resolve('@react-native/codegen/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile() - - // Point to the module's src directory for codegen - libraryName = "NimBridge" - codegenJavaPackageName = "com.nimbridge" + root = file("../../") + reactNativeDir = file("../../../node_modules/react-native") + codegenDir = file("../../../node_modules/@react-native/codegen") } android { @@ -56,6 +51,13 @@ android { } } + // Ensure CMake runs after codegen + tasks.configureEach { task -> + if (task.name.contains('configureCMake')) { + task.dependsOn(preBuild) + } + } + buildTypes { release { minifyEnabled false @@ -80,4 +82,4 @@ repositories { dependencies { implementation 'com.facebook.react:react-native:+' -} \ No newline at end of file +} diff --git a/mobile-app/package.json b/mobile-app/package.json index 7e1af4e..5c47923 100644 --- a/mobile-app/package.json +++ b/mobile-app/package.json @@ -54,13 +54,5 @@ "cross-platform" ], "author": "Nim-RN Team", - "license": "MIT", - "codegenConfig": { - "name": "NimBridgeSpec", - "type": "modules", - "jsSrcsDir": "modules/nim-bridge/src", - "android": { - "javaPackageName": "com.nimbridge" - } - } + "license": "MIT" } From 78bf52b1ffabf3f12040e94be38a312f6ca7ae2c Mon Sep 17 00:00:00 2001 From: Siddarth Kumar Date: Sat, 4 Oct 2025 21:07:00 +0530 Subject: [PATCH 4/6] ci: fix iOS build --- .github/workflows/build-ios.yml | 36 ++++++++++--------- mobile-app/ios/Podfile | 24 ------------- mobile-app/ios/Podfile.lock | 31 ++++++++++++---- .../modules/nim-bridge/NimBridge.podspec | 21 ++--------- 4 files changed, 45 insertions(+), 67 deletions(-) diff --git a/.github/workflows/build-ios.yml b/.github/workflows/build-ios.yml index d00be94..fea2cdb 100644 --- a/.github/workflows/build-ios.yml +++ b/.github/workflows/build-ios.yml @@ -63,12 +63,6 @@ jobs: ruby-version: '3.0' working-directory: mobile-app/ios - - name: Install CocoaPods dependencies - working-directory: mobile-app/ios - run: | - rm -rf Pods || true - pod install --repo-update || pod install - - name: Select Xcode 16.4 run: sudo xcode-select -s "/Applications/Xcode_16.4.app/Contents/Developer" @@ -83,22 +77,29 @@ jobs: rm -rf /tmp/metro-* || true rm -rf ios/build || true - - name: Generate ReactCodegen files + - name: Generate codegen artifacts + working-directory: mobile-app + env: + RCT_NEW_ARCH_ENABLED: '1' + run: | + # Generate codegen artifacts for all modules including custom nim-bridge + node node_modules/react-native/scripts/generate-codegen-artifacts.js \ + --path . \ + --targetPlatform ios \ + --outputPath ios/build/generated/ios + + - name: Install CocoaPods dependencies working-directory: mobile-app/ios + env: + RCT_NEW_ARCH_ENABLED: '1' run: | - # Generate ReactCodegen files (this will fail but creates the required files) - xcodebuild -workspace nimrnmobileapp.xcworkspace \ - -scheme ReactCodegen \ - -sdk iphonesimulator \ - -configuration Release \ - -destination 'platform=iOS Simulator,name=iPhone 16' \ - -derivedDataPath build \ - CODE_SIGNING_ALLOWED=NO \ - ARCHS=arm64 \ - ONLY_ACTIVE_ARCH=YES || echo "ReactCodegen files generated (expected failure)" + rm -rf Pods || true + pod install --repo-update || pod install - name: Build iOS Simulator App working-directory: mobile-app/ios + env: + RCT_NEW_ARCH_ENABLED: '1' run: | set -o pipefail xcodebuild -workspace nimrnmobileapp.xcworkspace \ @@ -110,6 +111,7 @@ jobs: CODE_SIGNING_ALLOWED=NO \ ARCHS=arm64 \ ONLY_ACTIVE_ARCH=YES \ + RCT_NEW_ARCH_ENABLED=1 \ | xcbeautify - name: Prepare iOS app for upload diff --git a/mobile-app/ios/Podfile b/mobile-app/ios/Podfile index 99a753a..04dd271 100644 --- a/mobile-app/ios/Podfile +++ b/mobile-app/ios/Podfile @@ -53,30 +53,6 @@ target 'nimrnmobileapp' do :ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true', ) - # Patch Folly source files to disable coroutines - folly_expected = File.join(installer.sandbox.root, 'RCT-Folly/folly/Expected.h') - folly_optional = File.join(installer.sandbox.root, 'RCT-Folly/folly/Optional.h') - - if File.exist?(folly_expected) - # Make file writable - system("chmod u+w \"#{folly_expected}\"") - contents = File.read(folly_expected) - # Replace #if FOLLY_HAS_COROUTINES with #if 0 to disable the coroutine sections - contents.gsub!(/#if FOLLY_HAS_COROUTINES/, '#if 0 // FOLLY_HAS_COROUTINES disabled by Podfile patch') - File.write(folly_expected, contents) - puts "✅ Patched #{folly_expected} to disable coroutines" - end - - if File.exist?(folly_optional) - # Make file writable - system("chmod u+w \"#{folly_optional}\"") - contents = File.read(folly_optional) - # Replace #if FOLLY_HAS_COROUTINES with #if 0 to disable the coroutine sections - contents.gsub!(/#if FOLLY_HAS_COROUTINES/, '#if 0 // FOLLY_HAS_COROUTINES disabled by Podfile patch') - File.write(folly_optional, contents) - puts "✅ Patched #{folly_optional} to disable coroutines" - end - # fix for Xcode 16 build issues installer.pods_project.targets.each do |target| target.build_configurations.each do |config| diff --git a/mobile-app/ios/Podfile.lock b/mobile-app/ios/Podfile.lock index 3e613a8..8bf9b40 100644 --- a/mobile-app/ios/Podfile.lock +++ b/mobile-app/ios/Podfile.lock @@ -291,13 +291,33 @@ PODS: - hermes-engine/Pre-built (= 0.81.4) - hermes-engine/Pre-built (0.81.4) - NimBridge (1.0.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine - RCT-Folly + - RCT-Folly/Fabric - RCTRequired - RCTTypeSafety - - React-Codegen - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - RCT-Folly (2024.11.18.00): - boost - DoubleConversion @@ -337,7 +357,6 @@ PODS: - React-RCTText (= 0.81.4) - React-RCTVibration (= 0.81.4) - React-callinvoker (0.81.4) - - React-Codegen (0.1.0) - React-Core (0.81.4): - boost - DoubleConversion @@ -2639,7 +2658,6 @@ DEPENDENCIES: SPEC REPOS: trunk: - - React-Codegen - SocketRocket EXTERNAL SOURCES: @@ -2839,14 +2857,13 @@ SPEC CHECKSUMS: fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 hermes-engine: 35c763d57c9832d0eef764316ca1c4d043581394 - NimBridge: 70b6c653edd5f92ee764879f46a6b53ba51da94f + NimBridge: d3882c7c781b494b6f9c21b89869919a302215ef RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669 RCTDeprecation: c0ed3249a97243002615517dff789bf4666cf585 RCTRequired: 58719f5124f9267b5f9649c08bf23d9aea845b23 RCTTypeSafety: 4aefa8328ab1f86da273f08517f1f6b343f6c2cc React: 2073376f47c71b7e9a0af7535986a77522ce1049 React-callinvoker: 751b6f2c83347a0486391c3f266f291f0f53b27e - React-Codegen: 4b8b4817cea7a54b83851d4c1f91f79aa73de30a React-Core: dff5d29973349b11dd6631c9498456d75f846d5e React-CoreModules: c0ae04452e4c5d30e06f8e94692a49107657f537 React-cxxreact: 376fd672c95dfb64ad5cc246e6a1e9edb78dec4c @@ -2902,11 +2919,11 @@ SPEC CHECKSUMS: React-timing: 1e6a8acb66e2b7ac9d418956617fd1fdb19322fd React-utils: 52bbb03f130319ef82e4c3bc7a85eaacdb1fec87 ReactAppDependencyProvider: 433ddfb4536948630aadd5bd925aff8a632d2fe3 - ReactCodegen: aded76e44f752489dfa4a3ec0d41df08dd3ac865 + ReactCodegen: 1d05923ad119796be9db37830d5e5dc76586aa00 ReactCommon: 394c6b92765cf6d211c2c3f7f6bc601dffb316a6 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 Yoga: 922d794dce2af9c437f864bf4093abfa7a131adb -PODFILE CHECKSUM: 5548583703093faf0a61d6a070017162e1c2571a +PODFILE CHECKSUM: 30222b370f2c6e2622deeb5e8d786e95202de871 COCOAPODS: 1.16.2 diff --git a/mobile-app/modules/nim-bridge/NimBridge.podspec b/mobile-app/modules/nim-bridge/NimBridge.podspec index 14ac3eb..2030e3b 100644 --- a/mobile-app/modules/nim-bridge/NimBridge.podspec +++ b/mobile-app/modules/nim-bridge/NimBridge.podspec @@ -1,7 +1,6 @@ require "json" package = JSON.parse(File.read(File.join(__dir__, "package.json"))) -folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' Pod::Spec.new do |s| s.name = "NimBridge" @@ -26,22 +25,6 @@ Pod::Spec.new do |s| 'OTHER_LDFLAGS' => '-pthread' } - # React Native dependencies - s.dependency "React-Core" - - # Don't install the dependencies when we run `pod install` in the old architecture. - if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then - s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1 -DFOLLY_HAS_COROUTINES=0" - s.pod_target_xcconfig = { - "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_TARGET_SRCROOT)/../../build/generated/ios\" \"$(PODS_ROOT)/Headers/Public/React-NativeModulesApple\"", - "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_HAS_COROUTINES=0", - "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" - } - s.dependency "React-Codegen" - s.dependency "RCT-Folly" - s.dependency "RCTRequired" - s.dependency "RCTTypeSafety" - s.dependency "ReactCommon/turbomodule/core" - s.dependency "React-NativeModulesApple" - end + # This one line handles all new architecture dependencies automatically + install_modules_dependencies(s) end \ No newline at end of file From 7d08a1e6f793e3888ec1b6870d0805ba11db6592 Mon Sep 17 00:00:00 2001 From: Siddarth Kumar Date: Mon, 6 Oct 2025 14:02:16 +0530 Subject: [PATCH 5/6] ci: bump @react-native deps to match --- mobile-app/package.json | 8 +- mobile-app/yarn.lock | 424 ++++------------------------------------ 2 files changed, 42 insertions(+), 390 deletions(-) diff --git a/mobile-app/package.json b/mobile-app/package.json index 5c47923..d57165f 100644 --- a/mobile-app/package.json +++ b/mobile-app/package.json @@ -30,10 +30,10 @@ "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", "@react-native-community/cli": "^20.0.1", - "@react-native/babel-preset": "^0.79.6", - "@react-native/eslint-config": "^0.79.6", - "@react-native/metro-config": "^0.79.6", - "@react-native/typescript-config": "^0.79.6", + "@react-native/babel-preset": "^0.81.0", + "@react-native/eslint-config": "^0.81.0", + "@react-native/metro-config": "^0.81.0", + "@react-native/typescript-config": "^0.81.0", "@types/react": "~19.1.0", "@types/react-test-renderer": "^18.0.0", "babel-jest": "^29.6.3", diff --git a/mobile-app/yarn.lock b/mobile-app/yarn.lock index ddc3044..8500420 100644 --- a/mobile-app/yarn.lock +++ b/mobile-app/yarn.lock @@ -2669,16 +2669,6 @@ __metadata: languageName: node linkType: hard -"@react-native/babel-plugin-codegen@npm:0.79.6": - version: 0.79.6 - resolution: "@react-native/babel-plugin-codegen@npm:0.79.6" - dependencies: - "@babel/traverse": "npm:^7.25.3" - "@react-native/codegen": "npm:0.79.6" - checksum: 10c0/dc1e22b31db6e11ab1444ca607ab2cf9430ba0b09aa0f1819204b04dd6b151b254b7605bb3f0c2dc1b4d5fdfbf96dd8f8d92e60251dc1dc08b1fa54deb6b1614 - languageName: node - linkType: hard - "@react-native/babel-plugin-codegen@npm:0.81.4": version: 0.81.4 resolution: "@react-native/babel-plugin-codegen@npm:0.81.4" @@ -2689,62 +2679,7 @@ __metadata: languageName: node linkType: hard -"@react-native/babel-preset@npm:0.79.6, @react-native/babel-preset@npm:^0.79.6": - version: 0.79.6 - resolution: "@react-native/babel-preset@npm:0.79.6" - dependencies: - "@babel/core": "npm:^7.25.2" - "@babel/plugin-proposal-export-default-from": "npm:^7.24.7" - "@babel/plugin-syntax-dynamic-import": "npm:^7.8.3" - "@babel/plugin-syntax-export-default-from": "npm:^7.24.7" - "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" - "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" - "@babel/plugin-transform-arrow-functions": "npm:^7.24.7" - "@babel/plugin-transform-async-generator-functions": "npm:^7.25.4" - "@babel/plugin-transform-async-to-generator": "npm:^7.24.7" - "@babel/plugin-transform-block-scoping": "npm:^7.25.0" - "@babel/plugin-transform-class-properties": "npm:^7.25.4" - "@babel/plugin-transform-classes": "npm:^7.25.4" - "@babel/plugin-transform-computed-properties": "npm:^7.24.7" - "@babel/plugin-transform-destructuring": "npm:^7.24.8" - "@babel/plugin-transform-flow-strip-types": "npm:^7.25.2" - "@babel/plugin-transform-for-of": "npm:^7.24.7" - "@babel/plugin-transform-function-name": "npm:^7.25.1" - "@babel/plugin-transform-literals": "npm:^7.25.2" - "@babel/plugin-transform-logical-assignment-operators": "npm:^7.24.7" - "@babel/plugin-transform-modules-commonjs": "npm:^7.24.8" - "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.24.7" - "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.24.7" - "@babel/plugin-transform-numeric-separator": "npm:^7.24.7" - "@babel/plugin-transform-object-rest-spread": "npm:^7.24.7" - "@babel/plugin-transform-optional-catch-binding": "npm:^7.24.7" - "@babel/plugin-transform-optional-chaining": "npm:^7.24.8" - "@babel/plugin-transform-parameters": "npm:^7.24.7" - "@babel/plugin-transform-private-methods": "npm:^7.24.7" - "@babel/plugin-transform-private-property-in-object": "npm:^7.24.7" - "@babel/plugin-transform-react-display-name": "npm:^7.24.7" - "@babel/plugin-transform-react-jsx": "npm:^7.25.2" - "@babel/plugin-transform-react-jsx-self": "npm:^7.24.7" - "@babel/plugin-transform-react-jsx-source": "npm:^7.24.7" - "@babel/plugin-transform-regenerator": "npm:^7.24.7" - "@babel/plugin-transform-runtime": "npm:^7.24.7" - "@babel/plugin-transform-shorthand-properties": "npm:^7.24.7" - "@babel/plugin-transform-spread": "npm:^7.24.7" - "@babel/plugin-transform-sticky-regex": "npm:^7.24.7" - "@babel/plugin-transform-typescript": "npm:^7.25.2" - "@babel/plugin-transform-unicode-regex": "npm:^7.24.7" - "@babel/template": "npm:^7.25.0" - "@react-native/babel-plugin-codegen": "npm:0.79.6" - babel-plugin-syntax-hermes-parser: "npm:0.25.1" - babel-plugin-transform-flow-enums: "npm:^0.0.2" - react-refresh: "npm:^0.14.0" - peerDependencies: - "@babel/core": "*" - checksum: 10c0/9afdf7ad725d4c5eece4f6390be1bd33c39f8a1da55731c3493d5e61afd31e3c9911ca5e1c539cf8c4cbd9f48c0f9f14914a8b12437011451394ee0db8fd5cdc - languageName: node - linkType: hard - -"@react-native/babel-preset@npm:0.81.4": +"@react-native/babel-preset@npm:0.81.4, @react-native/babel-preset@npm:^0.81.0": version: 0.81.4 resolution: "@react-native/babel-preset@npm:0.81.4" dependencies: @@ -2799,23 +2734,6 @@ __metadata: languageName: node linkType: hard -"@react-native/codegen@npm:0.79.6": - version: 0.79.6 - resolution: "@react-native/codegen@npm:0.79.6" - dependencies: - "@babel/core": "npm:^7.25.2" - "@babel/parser": "npm:^7.25.3" - glob: "npm:^7.1.1" - hermes-parser: "npm:0.25.1" - invariant: "npm:^2.2.4" - nullthrows: "npm:^1.1.1" - yargs: "npm:^17.6.2" - peerDependencies: - "@babel/core": "*" - checksum: 10c0/2359c37016ede418d1fef43e27899599cf753c05481bbfb3ef4de86cdb2f39c9a475ed6f64cc13f267bd547cda10e0b5e62329f8b3fceb94df9058284f126524 - languageName: node - linkType: hard - "@react-native/codegen@npm:0.81.4": version: 0.81.4 resolution: "@react-native/codegen@npm:0.81.4" @@ -2882,13 +2800,13 @@ __metadata: languageName: node linkType: hard -"@react-native/eslint-config@npm:^0.79.6": - version: 0.79.6 - resolution: "@react-native/eslint-config@npm:0.79.6" +"@react-native/eslint-config@npm:^0.81.0": + version: 0.81.4 + resolution: "@react-native/eslint-config@npm:0.81.4" dependencies: "@babel/core": "npm:^7.25.2" "@babel/eslint-parser": "npm:^7.25.1" - "@react-native/eslint-plugin": "npm:0.79.6" + "@react-native/eslint-plugin": "npm:0.81.4" "@typescript-eslint/eslint-plugin": "npm:^7.1.1" "@typescript-eslint/parser": "npm:^7.1.1" eslint-config-prettier: "npm:^8.5.0" @@ -2896,19 +2814,19 @@ __metadata: eslint-plugin-ft-flow: "npm:^2.0.1" eslint-plugin-jest: "npm:^27.9.0" eslint-plugin-react: "npm:^7.30.1" - eslint-plugin-react-hooks: "npm:^4.6.0" + eslint-plugin-react-hooks: "npm:^5.2.0" eslint-plugin-react-native: "npm:^4.0.0" peerDependencies: eslint: ">=8" prettier: ">=2" - checksum: 10c0/92cad242289fed9adc57bc0ba5b531d69538570d826e8d6fb5f5de981d203fdf3d56ba1fce67d701712636932bfc0dfd092361724924775812509a712490f498 + checksum: 10c0/5eb94c12df3c58d9fb2d528bd420952b076a51803569409fa174648445cfc10a78272dca2bef55a1770a9ed59dda8f3c7139212032ca790accc2f162522b6c77 languageName: node linkType: hard -"@react-native/eslint-plugin@npm:0.79.6": - version: 0.79.6 - resolution: "@react-native/eslint-plugin@npm:0.79.6" - checksum: 10c0/de25b2d33c170fa9bb63f081e2fa94d5f75572984e162b9d70d02a354b195a61d2c4daaec0c4d7d37448987fc9ba75b9f9237002b5280ad4b37e60fbca92f27d +"@react-native/eslint-plugin@npm:0.81.4": + version: 0.81.4 + resolution: "@react-native/eslint-plugin@npm:0.81.4" + checksum: 10c0/236bbbded779cda932291939aa21cadbe78484ed2030005f501e38cb47d4fd2e0810500b4d4c68753ac7a9c967e6cdb3aa0bda71b8a011896f95d15da9bcdeb8 languageName: node linkType: hard @@ -2919,13 +2837,6 @@ __metadata: languageName: node linkType: hard -"@react-native/js-polyfills@npm:0.79.6": - version: 0.79.6 - resolution: "@react-native/js-polyfills@npm:0.79.6" - checksum: 10c0/a2f78dac9ed1cf4224c863c00b6ef941097928150404f12951e6d938f6ea52869cbed128e6847ee3d4a34437ae48cc340a259e5967ece0adeba7cb4c6c7a2489 - languageName: node - linkType: hard - "@react-native/js-polyfills@npm:0.81.4": version: 0.81.4 resolution: "@react-native/js-polyfills@npm:0.81.4" @@ -2933,29 +2844,29 @@ __metadata: languageName: node linkType: hard -"@react-native/metro-babel-transformer@npm:0.79.6": - version: 0.79.6 - resolution: "@react-native/metro-babel-transformer@npm:0.79.6" +"@react-native/metro-babel-transformer@npm:0.81.4": + version: 0.81.4 + resolution: "@react-native/metro-babel-transformer@npm:0.81.4" dependencies: "@babel/core": "npm:^7.25.2" - "@react-native/babel-preset": "npm:0.79.6" - hermes-parser: "npm:0.25.1" + "@react-native/babel-preset": "npm:0.81.4" + hermes-parser: "npm:0.29.1" nullthrows: "npm:^1.1.1" peerDependencies: "@babel/core": "*" - checksum: 10c0/1cc35e76b928a440f963894e6b0671b527af5d5eafff180110ecef838a542acb88734131c5e9ba95298b6ee31b0b3ef01422354d75b921455809763fe65f839f + checksum: 10c0/a301d9cd9234942776d7ec94d442c37450477ff4267ef2b56d2bc8cc0bdd83e4258fe7f88092ce3bc4f100a32dfd831b398cdd15e614a6e28491bc4fbfda6c6b languageName: node linkType: hard -"@react-native/metro-config@npm:^0.79.6": - version: 0.79.6 - resolution: "@react-native/metro-config@npm:0.79.6" +"@react-native/metro-config@npm:^0.81.0": + version: 0.81.4 + resolution: "@react-native/metro-config@npm:0.81.4" dependencies: - "@react-native/js-polyfills": "npm:0.79.6" - "@react-native/metro-babel-transformer": "npm:0.79.6" - metro-config: "npm:^0.82.0" - metro-runtime: "npm:^0.82.0" - checksum: 10c0/fd479f17b3628100649c31ffb636401f410f8ae571b410ea71e734b63c642548d2717b2214933aaab5583affc94b7e0705d808a6e3132ba50a7b1884f82590e3 + "@react-native/js-polyfills": "npm:0.81.4" + "@react-native/metro-babel-transformer": "npm:0.81.4" + metro-config: "npm:^0.83.1" + metro-runtime: "npm:^0.83.1" + checksum: 10c0/ae2b359398dda8c1ebe63f0361dbc77f417c543f78f89a230eb554c89099e8a06b33aabf9640da3b8828bc89af614006d3280b104bfbdab0324fa084dbc7ebc2 languageName: node linkType: hard @@ -2966,10 +2877,10 @@ __metadata: languageName: node linkType: hard -"@react-native/typescript-config@npm:^0.79.6": - version: 0.79.6 - resolution: "@react-native/typescript-config@npm:0.79.6" - checksum: 10c0/3e1327f4e69e2ba9edb82055a26480ddaa2da83dad0788ea5aec6478e4fd1594310d6cc4d8c9f0209d760cfc60492d023428e81660ea7bf28cda68b190a6ac12 +"@react-native/typescript-config@npm:^0.81.0": + version: 0.81.4 + resolution: "@react-native/typescript-config@npm:0.81.4" + checksum: 10c0/efe0c9193efdd1aa251897479c1637af9f05e9cb0273769bdaba854acf66c0cf59efb67981446b33f856d82e835ed070ab8cb9f8e1fb59a20cd1418779ea3b51 languageName: node linkType: hard @@ -3838,15 +3749,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-syntax-hermes-parser@npm:0.25.1": - version: 0.25.1 - resolution: "babel-plugin-syntax-hermes-parser@npm:0.25.1" - dependencies: - hermes-parser: "npm:0.25.1" - checksum: 10c0/8f4a0cb65056162b2d4c64d0ccd4d2fdeac8218e83e0338e92564ead659fd9b9351277ed2a10e958d0d8dc4c60591d5b1a40aa425bf0cbf67224e9767c557abf - languageName: node - linkType: hard - "babel-plugin-syntax-hermes-parser@npm:0.29.1, babel-plugin-syntax-hermes-parser@npm:^0.29.1": version: 0.29.1 resolution: "babel-plugin-syntax-hermes-parser@npm:0.29.1" @@ -5226,12 +5128,12 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react-hooks@npm:^4.6.0": - version: 4.6.2 - resolution: "eslint-plugin-react-hooks@npm:4.6.2" +"eslint-plugin-react-hooks@npm:^5.2.0": + version: 5.2.0 + resolution: "eslint-plugin-react-hooks@npm:5.2.0" peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - checksum: 10c0/4844e58c929bc05157fb70ba1e462e34f1f4abcbc8dd5bbe5b04513d33e2699effb8bca668297976ceea8e7ebee4e8fc29b9af9d131bcef52886feaa2308b2cc + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + checksum: 10c0/1c8d50fa5984c6dea32470651807d2922cc3934cf3425e78f84a24c2dfd972e7f019bee84aefb27e0cf2c13fea0ac1d4473267727408feeb1c56333ca1489385 languageName: node linkType: hard @@ -6225,13 +6127,6 @@ __metadata: languageName: node linkType: hard -"hermes-estree@npm:0.25.1": - version: 0.25.1 - resolution: "hermes-estree@npm:0.25.1" - checksum: 10c0/48be3b2fa37a0cbc77a112a89096fa212f25d06de92781b163d67853d210a8a5c3784fac23d7d48335058f7ed283115c87b4332c2a2abaaccc76d0ead1a282ac - languageName: node - linkType: hard - "hermes-estree@npm:0.29.1": version: 0.29.1 resolution: "hermes-estree@npm:0.29.1" @@ -6246,15 +6141,6 @@ __metadata: languageName: node linkType: hard -"hermes-parser@npm:0.25.1": - version: 0.25.1 - resolution: "hermes-parser@npm:0.25.1" - dependencies: - hermes-estree: "npm:0.25.1" - checksum: 10c0/3abaa4c6f1bcc25273f267297a89a4904963ea29af19b8e4f6eabe04f1c2c7e9abd7bfc4730ddb1d58f2ea04b6fee74053d8bddb5656ec6ebf6c79cc8d14202c - languageName: node - linkType: hard - "hermes-parser@npm:0.29.1, hermes-parser@npm:^0.29.1": version: 0.29.1 resolution: "hermes-parser@npm:0.29.1" @@ -7857,18 +7743,6 @@ __metadata: languageName: node linkType: hard -"metro-babel-transformer@npm:0.82.5": - version: 0.82.5 - resolution: "metro-babel-transformer@npm:0.82.5" - dependencies: - "@babel/core": "npm:^7.25.2" - flow-enums-runtime: "npm:^0.0.6" - hermes-parser: "npm:0.29.1" - nullthrows: "npm:^1.1.1" - checksum: 10c0/a672dc1dcf3778120130052bc175bfb754c93b490c1d0170e89e309efa0c122f4dfd4717dda966c7addbbd3a2e764acb610e740d62159601bc9cfdf6684466e8 - languageName: node - linkType: hard - "metro-babel-transformer@npm:0.83.1": version: 0.83.1 resolution: "metro-babel-transformer@npm:0.83.1" @@ -7893,15 +7767,6 @@ __metadata: languageName: node linkType: hard -"metro-cache-key@npm:0.82.5": - version: 0.82.5 - resolution: "metro-cache-key@npm:0.82.5" - dependencies: - flow-enums-runtime: "npm:^0.0.6" - checksum: 10c0/7dd8a2e83bea57b57f49fd30188b70d0c364fa280cffd96609deac764bc671634f174449e4abfbad2197d275ad8a3fd86521652549d9f7fe008efb0dd445778d - languageName: node - linkType: hard - "metro-cache-key@npm:0.83.1": version: 0.83.1 resolution: "metro-cache-key@npm:0.83.1" @@ -7920,18 +7785,6 @@ __metadata: languageName: node linkType: hard -"metro-cache@npm:0.82.5": - version: 0.82.5 - resolution: "metro-cache@npm:0.82.5" - dependencies: - exponential-backoff: "npm:^3.1.1" - flow-enums-runtime: "npm:^0.0.6" - https-proxy-agent: "npm:^7.0.5" - metro-core: "npm:0.82.5" - checksum: 10c0/8480b301c0cf29c113e948598158e64dc2cb43b449be8862d688ffed461a6e08ead23bc8e81c6a323e490436ebc31cb19aecfc3c375325eafd8d34dd0c80bf92 - languageName: node - linkType: hard - "metro-cache@npm:0.83.1": version: 0.83.1 resolution: "metro-cache@npm:0.83.1" @@ -7956,22 +7809,6 @@ __metadata: languageName: node linkType: hard -"metro-config@npm:0.82.5, metro-config@npm:^0.82.0": - version: 0.82.5 - resolution: "metro-config@npm:0.82.5" - dependencies: - connect: "npm:^3.6.5" - cosmiconfig: "npm:^5.0.5" - flow-enums-runtime: "npm:^0.0.6" - jest-validate: "npm:^29.7.0" - metro: "npm:0.82.5" - metro-cache: "npm:0.82.5" - metro-core: "npm:0.82.5" - metro-runtime: "npm:0.82.5" - checksum: 10c0/8c7c9be911aee55e65fc870e79c5695c007bf99cb960e0d9746c92ecd828b69d055bd0e4b83976151e4ed9d2e23d13fa081ee44abbd166822d46d34030138a50 - languageName: node - linkType: hard - "metro-config@npm:0.83.1": version: 0.83.1 resolution: "metro-config@npm:0.83.1" @@ -8004,17 +7841,6 @@ __metadata: languageName: node linkType: hard -"metro-core@npm:0.82.5": - version: 0.82.5 - resolution: "metro-core@npm:0.82.5" - dependencies: - flow-enums-runtime: "npm:^0.0.6" - lodash.throttle: "npm:^4.1.1" - metro-resolver: "npm:0.82.5" - checksum: 10c0/0491679e8ed55431cc325642ddffba7b170dbd2cde8dcb81a54c692ca1ca3c786c9936ed1ee15d092af64adda8ccfd8f475afc85c4a6dbec4614357316e74be6 - languageName: node - linkType: hard - "metro-core@npm:0.83.1": version: 0.83.1 resolution: "metro-core@npm:0.83.1" @@ -8037,23 +7863,6 @@ __metadata: languageName: node linkType: hard -"metro-file-map@npm:0.82.5": - version: 0.82.5 - resolution: "metro-file-map@npm:0.82.5" - dependencies: - debug: "npm:^4.4.0" - fb-watchman: "npm:^2.0.0" - flow-enums-runtime: "npm:^0.0.6" - graceful-fs: "npm:^4.2.4" - invariant: "npm:^2.2.4" - jest-worker: "npm:^29.7.0" - micromatch: "npm:^4.0.4" - nullthrows: "npm:^1.1.1" - walker: "npm:^1.0.7" - checksum: 10c0/86496bc6a15a87cd1af668a588f26f17cbf3c43eee0b021ded8eb6b02a83cd80e14a356900fe3a4cc8c4fa494de55ee7e20e6c45f0c6b27e616f0f03817e0c9e - languageName: node - linkType: hard - "metro-file-map@npm:0.83.1": version: 0.83.1 resolution: "metro-file-map@npm:0.83.1" @@ -8088,16 +7897,6 @@ __metadata: languageName: node linkType: hard -"metro-minify-terser@npm:0.82.5": - version: 0.82.5 - resolution: "metro-minify-terser@npm:0.82.5" - dependencies: - flow-enums-runtime: "npm:^0.0.6" - terser: "npm:^5.15.0" - checksum: 10c0/925be4401912ebc964b61ffe442bee977efb5baa42035d933277d8b669a4852f654778b87be50d12260d63b402054debc92cf703a70d58a1c9fea343401158b8 - languageName: node - linkType: hard - "metro-minify-terser@npm:0.83.1": version: 0.83.1 resolution: "metro-minify-terser@npm:0.83.1" @@ -8118,15 +7917,6 @@ __metadata: languageName: node linkType: hard -"metro-resolver@npm:0.82.5": - version: 0.82.5 - resolution: "metro-resolver@npm:0.82.5" - dependencies: - flow-enums-runtime: "npm:^0.0.6" - checksum: 10c0/a84c4571c78694468e5921f290b50505835fcd90cc490c4e6e028908a1f6b54104635f417de9c1cf0788b642c56e4eeb2b2a3cff6c36f9105ecaa8dfbac12fa7 - languageName: node - linkType: hard - "metro-resolver@npm:0.83.1": version: 0.83.1 resolution: "metro-resolver@npm:0.83.1" @@ -8145,16 +7935,6 @@ __metadata: languageName: node linkType: hard -"metro-runtime@npm:0.82.5, metro-runtime@npm:^0.82.0": - version: 0.82.5 - resolution: "metro-runtime@npm:0.82.5" - dependencies: - "@babel/runtime": "npm:^7.25.0" - flow-enums-runtime: "npm:^0.0.6" - checksum: 10c0/90418c7670fe6e6ece86185ff5c5cb5cdabfcffce0b6a601a3b4049d2643b16878b6819e9fd430fda0e2d7bc378752194c0ce4b4f9d53faa99da910782179789 - languageName: node - linkType: hard - "metro-runtime@npm:0.83.1": version: 0.83.1 resolution: "metro-runtime@npm:0.83.1" @@ -8175,24 +7955,6 @@ __metadata: languageName: node linkType: hard -"metro-source-map@npm:0.82.5": - version: 0.82.5 - resolution: "metro-source-map@npm:0.82.5" - dependencies: - "@babel/traverse": "npm:^7.25.3" - "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3" - "@babel/types": "npm:^7.25.2" - flow-enums-runtime: "npm:^0.0.6" - invariant: "npm:^2.2.4" - metro-symbolicate: "npm:0.82.5" - nullthrows: "npm:^1.1.1" - ob1: "npm:0.82.5" - source-map: "npm:^0.5.6" - vlq: "npm:^1.0.0" - checksum: 10c0/cf04c8f5430eaf2aa8aa97034382d2cb1b0906a4c7cf3c4faaf0203eb00dd683b8d108e74694700a10085796beb292383cfcea50b388cc03062640bd95d3f84a - languageName: node - linkType: hard - "metro-source-map@npm:0.83.1": version: 0.83.1 resolution: "metro-source-map@npm:0.83.1" @@ -8229,22 +7991,6 @@ __metadata: languageName: node linkType: hard -"metro-symbolicate@npm:0.82.5": - version: 0.82.5 - resolution: "metro-symbolicate@npm:0.82.5" - dependencies: - flow-enums-runtime: "npm:^0.0.6" - invariant: "npm:^2.2.4" - metro-source-map: "npm:0.82.5" - nullthrows: "npm:^1.1.1" - source-map: "npm:^0.5.6" - vlq: "npm:^1.0.0" - bin: - metro-symbolicate: src/index.js - checksum: 10c0/39c53b878ae9392586e23ff3a8071eceb1feed2d226e3ac9a170eb6bcd46fe6b69b8204851ee8eb231fdc3eac9012af3c6940ad48f6d1c04810ea9c4a75e1c7c - languageName: node - linkType: hard - "metro-symbolicate@npm:0.83.1": version: 0.83.1 resolution: "metro-symbolicate@npm:0.83.1" @@ -8277,20 +8023,6 @@ __metadata: languageName: node linkType: hard -"metro-transform-plugins@npm:0.82.5": - version: 0.82.5 - resolution: "metro-transform-plugins@npm:0.82.5" - dependencies: - "@babel/core": "npm:^7.25.2" - "@babel/generator": "npm:^7.25.0" - "@babel/template": "npm:^7.25.0" - "@babel/traverse": "npm:^7.25.3" - flow-enums-runtime: "npm:^0.0.6" - nullthrows: "npm:^1.1.1" - checksum: 10c0/394ac0fbb0a33edb412307f09dc3c2dcd5a0268368876b82b9631261e55c7cf2b1c3ce75270d94285ed190a7934137d851b57aa4d27088efe50193fa9bb9aff7 - languageName: node - linkType: hard - "metro-transform-plugins@npm:0.83.1": version: 0.83.1 resolution: "metro-transform-plugins@npm:0.83.1" @@ -8319,27 +8051,6 @@ __metadata: languageName: node linkType: hard -"metro-transform-worker@npm:0.82.5": - version: 0.82.5 - resolution: "metro-transform-worker@npm:0.82.5" - dependencies: - "@babel/core": "npm:^7.25.2" - "@babel/generator": "npm:^7.25.0" - "@babel/parser": "npm:^7.25.3" - "@babel/types": "npm:^7.25.2" - flow-enums-runtime: "npm:^0.0.6" - metro: "npm:0.82.5" - metro-babel-transformer: "npm:0.82.5" - metro-cache: "npm:0.82.5" - metro-cache-key: "npm:0.82.5" - metro-minify-terser: "npm:0.82.5" - metro-source-map: "npm:0.82.5" - metro-transform-plugins: "npm:0.82.5" - nullthrows: "npm:^1.1.1" - checksum: 10c0/28d8a5e6a61e96c20e8ebb9410c2daa8cc60e5464cb339436b640d74b77d0782e4675218053b21b1c7676f79dd9596c2b579bc2e47879594a3111a45fb3dc185 - languageName: node - linkType: hard - "metro-transform-worker@npm:0.83.1": version: 0.83.1 resolution: "metro-transform-worker@npm:0.83.1" @@ -8382,56 +8093,6 @@ __metadata: languageName: node linkType: hard -"metro@npm:0.82.5": - version: 0.82.5 - resolution: "metro@npm:0.82.5" - dependencies: - "@babel/code-frame": "npm:^7.24.7" - "@babel/core": "npm:^7.25.2" - "@babel/generator": "npm:^7.25.0" - "@babel/parser": "npm:^7.25.3" - "@babel/template": "npm:^7.25.0" - "@babel/traverse": "npm:^7.25.3" - "@babel/types": "npm:^7.25.2" - accepts: "npm:^1.3.7" - chalk: "npm:^4.0.0" - ci-info: "npm:^2.0.0" - connect: "npm:^3.6.5" - debug: "npm:^4.4.0" - error-stack-parser: "npm:^2.0.6" - flow-enums-runtime: "npm:^0.0.6" - graceful-fs: "npm:^4.2.4" - hermes-parser: "npm:0.29.1" - image-size: "npm:^1.0.2" - invariant: "npm:^2.2.4" - jest-worker: "npm:^29.7.0" - jsc-safe-url: "npm:^0.2.2" - lodash.throttle: "npm:^4.1.1" - metro-babel-transformer: "npm:0.82.5" - metro-cache: "npm:0.82.5" - metro-cache-key: "npm:0.82.5" - metro-config: "npm:0.82.5" - metro-core: "npm:0.82.5" - metro-file-map: "npm:0.82.5" - metro-resolver: "npm:0.82.5" - metro-runtime: "npm:0.82.5" - metro-source-map: "npm:0.82.5" - metro-symbolicate: "npm:0.82.5" - metro-transform-plugins: "npm:0.82.5" - metro-transform-worker: "npm:0.82.5" - mime-types: "npm:^2.1.27" - nullthrows: "npm:^1.1.1" - serialize-error: "npm:^2.1.0" - source-map: "npm:^0.5.6" - throat: "npm:^5.0.0" - ws: "npm:^7.5.10" - yargs: "npm:^17.6.2" - bin: - metro: src/cli.js - checksum: 10c0/a7bc635014ce74adb498f8e57fc39209d5b4a34bd7d18ad0b8ae7698839fcd6617a183fba4cd0038c1bdb2ab57322a0c8bf02fa5cf6ad8d184bf9d13913092e2 - languageName: node - linkType: hard - "metro@npm:0.83.1": version: 0.83.1 resolution: "metro@npm:0.83.1" @@ -8793,10 +8454,10 @@ __metadata: "@babel/preset-env": "npm:^7.20.0" "@babel/runtime": "npm:^7.20.0" "@react-native-community/cli": "npm:^20.0.1" - "@react-native/babel-preset": "npm:^0.79.6" - "@react-native/eslint-config": "npm:^0.79.6" - "@react-native/metro-config": "npm:^0.79.6" - "@react-native/typescript-config": "npm:^0.79.6" + "@react-native/babel-preset": "npm:^0.81.0" + "@react-native/eslint-config": "npm:^0.81.0" + "@react-native/metro-config": "npm:^0.81.0" + "@react-native/typescript-config": "npm:^0.81.0" "@types/react": "npm:~19.1.0" "@types/react-test-renderer": "npm:^18.0.0" babel-jest: "npm:^29.6.3" @@ -8922,15 +8583,6 @@ __metadata: languageName: node linkType: hard -"ob1@npm:0.82.5": - version: 0.82.5 - resolution: "ob1@npm:0.82.5" - dependencies: - flow-enums-runtime: "npm:^0.0.6" - checksum: 10c0/4d65e82fde0612a5c411f3c926de6bc722bdb4751c4fb08f5a5ef91bdaf860e7f9c4f08dcb7acfdfc05340fc4929efb00ea9e973570c1d61adfc4353657abf55 - languageName: node - linkType: hard - "ob1@npm:0.83.1": version: 0.83.1 resolution: "ob1@npm:0.83.1" From 864275a4e201dd29fd8cec4d68c5ee5bb4733a56 Mon Sep 17 00:00:00 2001 From: Siddarth Kumar Date: Mon, 6 Oct 2025 14:02:41 +0530 Subject: [PATCH 6/6] modules: simplify ts bridge --- mobile-app/modules/nim-bridge/src/index.ts | 38 ++-------------------- 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/mobile-app/modules/nim-bridge/src/index.ts b/mobile-app/modules/nim-bridge/src/index.ts index ae9a482..608740c 100644 --- a/mobile-app/modules/nim-bridge/src/index.ts +++ b/mobile-app/modules/nim-bridge/src/index.ts @@ -1,35 +1,3 @@ -import NativeNimBridge from './NativeNimBridge'; - -export interface NimCore { - // Core API - helloWorld(): string; - addNumbers(a: number, b: number): number; - getSystemInfo(): string; - - // Math operations - fibonacci(n: number): number; - isPrime(n: number): boolean; - factorize(n: number): string; - - // Data operations - createUser(id: number, name: string, email: string): string; - validateEmail(email: string): boolean; - - // Version info - getVersion(): string; -} - -export const NimCore: NimCore = { - helloWorld: () => NativeNimBridge.helloWorld(), - addNumbers: (a: number, b: number) => NativeNimBridge.addNumbers(a, b), - getSystemInfo: () => NativeNimBridge.getSystemInfo(), - fibonacci: (n: number) => NativeNimBridge.fibonacci(n), - isPrime: (n: number) => NativeNimBridge.isPrime(n), - factorize: (n: number) => NativeNimBridge.factorize(n), - createUser: (id: number, name: string, email: string) => - NativeNimBridge.createUser(id, name, email), - validateEmail: (email: string) => NativeNimBridge.validateEmail(email), - getVersion: () => NativeNimBridge.getVersion(), -}; - -export default NimCore; \ No newline at end of file +export { default } from './NativeNimBridge'; +export { default as NimCore } from './NativeNimBridge'; +export type { Spec as NimBridge } from './NativeNimBridge';