react-native-fs-turbo 0.3.7 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +119 -27
  2. package/RNFSTurbo.podspec +2 -2
  3. package/android/CMakeLists.txt +62 -9
  4. package/android/build.gradle +80 -3
  5. package/android/gradle.properties +5 -5
  6. package/android/src/main/codegen/RNFSTurboSpec.java +17 -0
  7. package/android/src/main/cpp/JNIOnLoad.cpp +18 -0
  8. package/android/src/main/cpp/RNFSTurboLogger.cpp +4 -0
  9. package/android/src/main/cpp/RNFSTurboModule.cpp +44 -0
  10. package/android/src/main/cpp/RNFSTurboModule.h +40 -0
  11. package/android/src/main/cpp/RNFSTurboPlatformHelper.cpp +5 -1
  12. package/android/src/main/java/com/cmpayc/rnfsturbo/JNIOnLoad.java +27 -0
  13. package/android/src/main/java/com/cmpayc/rnfsturbo/{RNFSTurboPlatformContextModule.java → RNFSTurboModule.java} +62 -11
  14. package/android/src/main/java/com/cmpayc/rnfsturbo/RNFSTurboPackage.java +11 -9
  15. package/cpp/RNFSTurboHostObject.cpp +138 -15
  16. package/cpp/RNFSTurboHostObject.h +12 -4
  17. package/cpp/RNFSTurboInstall.cpp +27 -0
  18. package/cpp/RNFSTurboInstall.h +20 -0
  19. package/cpp/RNFSTurboLogger.h +4 -0
  20. package/cpp/RNFSTurboPlatformHelper.h +4 -0
  21. package/cpp/algorithms/Krypt/AES.cpp +502 -0
  22. package/cpp/algorithms/Krypt/bytearray.cpp +158 -0
  23. package/cpp/algorithms/Krypt/functions.cpp +137 -0
  24. package/cpp/algorithms/Krypt/mode.cpp +203 -0
  25. package/cpp/algorithms/Krypt/padding.cpp +219 -0
  26. package/cpp/encryption/encryption-utils.cpp +162 -0
  27. package/cpp/encryption/encryption-utils.h +43 -0
  28. package/cpp/filesystem/{helpers.cpp → filesystem-utils.cpp} +5 -1
  29. package/cpp/filesystem/{helpers.h → filesystem-utils.h} +4 -0
  30. package/ios/RNFSTurboLogger.mm +4 -0
  31. package/ios/{RNFSTurboPlatformContextModule.h → RNFSTurboModule.h} +3 -3
  32. package/ios/{RNFSTurboPlatformContextModule.mm → RNFSTurboModule.mm} +22 -5
  33. package/ios/RNFSTurboPlatformHelper.mm +4 -0
  34. package/lib/commonjs/NativeRNFSTurboModule.js +14 -16
  35. package/lib/commonjs/NativeRNFSTurboModule.js.map +1 -1
  36. package/lib/commonjs/createRNFSTurbo.js +3 -2
  37. package/lib/commonjs/createRNFSTurbo.js.map +1 -1
  38. package/lib/commonjs/globals.d.js +6 -0
  39. package/lib/commonjs/globals.d.js.map +1 -0
  40. package/lib/module/NativeRNFSTurboModule.js +14 -16
  41. package/lib/module/NativeRNFSTurboModule.js.map +1 -1
  42. package/lib/module/createRNFSTurbo.js +3 -2
  43. package/lib/module/createRNFSTurbo.js.map +1 -1
  44. package/lib/module/globals.d.js +4 -0
  45. package/lib/module/globals.d.js.map +1 -0
  46. package/lib/typescript/NativeRNFSTurboModule.d.ts +12 -3
  47. package/lib/typescript/NativeRNFSTurboModule.d.ts.map +1 -1
  48. package/lib/typescript/Types.d.ts +11 -0
  49. package/lib/typescript/Types.d.ts.map +1 -1
  50. package/lib/typescript/createRNFSTurbo.d.ts.map +1 -1
  51. package/package.json +6 -3
  52. package/react-native.config.js +1 -5
  53. package/src/NativeRNFSTurboModule.ts +25 -21
  54. package/src/Types.ts +11 -0
  55. package/src/createRNFSTurbo.ts +4 -2
  56. package/src/globals.d.ts +9 -0
  57. package/cpp/NativeRNFSTurboModule.cpp +0 -24
  58. package/cpp/NativeRNFSTurboModule.h +0 -31
  59. package/ios/RNFSTurboOnLoad.mm +0 -25
  60. package/lib/commonjs/NativeRNFSTurboPlatformContextModule.js +0 -22
  61. package/lib/commonjs/NativeRNFSTurboPlatformContextModule.js.map +0 -1
  62. package/lib/module/NativeRNFSTurboPlatformContextModule.js +0 -18
  63. package/lib/module/NativeRNFSTurboPlatformContextModule.js.map +0 -1
  64. package/lib/typescript/NativeRNFSTurboPlatformContextModule.d.ts +0 -16
  65. package/lib/typescript/NativeRNFSTurboPlatformContextModule.d.ts.map +0 -1
  66. package/src/NativeRNFSTurboPlatformContextModule.ts +0 -34
package/README.md CHANGED
@@ -1,16 +1,18 @@
1
1
  ## react-native-fs-turbo
2
2
 
3
3
  * This library repeats all the methods of the original [react-native-fs](https://github.com/itinance/react-native-fs) but all the code is executed synchronously in C++ files via JSI (and JNI) and written using TypeScript.
4
+ * New methods for working with files have also been added, including AES256 encryption (disabled by default)
4
5
 
5
6
  > [!IMPORTANT]
6
- > `react-native-fs-turbo` is a pure C++ TurboModule, and **requires the new architecture to be enabled**. (react-native 0.74+)
7
+ > `react-native-fs-turbo` is a pure C++ TurboModule, and **requires the new architecture to be enabled**. (react-native 0.75+)
7
8
  > - If you want to use `react-native-fs-turbo`, you need to enable the new architecture in your app (see ["Enable the New Architecture for Apps"](https://github.com/reactwg/react-native-new-architecture/blob/main/docs/enable-apps.md))
8
9
  > - If you cannot use the new architecture yet, use the standard [react-native-fs](https://github.com/itinance/react-native-fs) library.
10
+ > - React-Native version 0.74 is no longer supported. Use the `0.3.7` library version. (`"react-native-fs-turbo": "0.3.7")
9
11
 
10
12
  ## Benchmark
11
13
 
12
14
  <details open>
13
- <summary>Benchmark tests of <b>react-native-fs-turbo</b> and <b>react-native-fs</b> libraries (iPhone 14, Samsung Galaxy Note 20 Ultra, release mode, 10,000 iterations)</summary>
15
+ <summary>Benchmark tests of <b>react-native-fs-turbo</b> and <b>react-native-fs</b> libraries (React-Native 0.82.0, iPhone 12 Pro (iOS 18.6.2), Samsung Galaxy Note 20 Ultra (Android 13), release mode, 10,000 iterations)</summary>
14
16
  <br>
15
17
  Conducted 10 tests, showed average time (only basic functions tested)
16
18
  <br>
@@ -21,32 +23,50 @@ Conducted 10 tests, showed average time (only basic functions tested)
21
23
  <b>readDir</b> test checked reading of 10,000 files in a folder
22
24
  <br>
23
25
 
24
- | Library | writeFile | appendFile | stat | unlink |
25
- | ----------------------------------- | ------------- | -------------- | -------------- | ------------- |
26
- | react-native-fs (ios, serial) | 7.855s | 2.683s | 1.595s | 1.728s |
27
- | react-native-fs (ios, parallel) | 7.596s | 2.719s | 1.234s | 1.480s |
28
- | react-native-fs-turbo (ios) | 4.849s (^1.6) | 1.986s (^1.4) | 0.267s (^4.6) | 0.634s (^2.3) |
29
- | react-native-fs (android, serial) | 8.764s | 6.320s | 4.821s | 4.307s |
30
- | react-native-fs (android, parallel) | 3.505s | 2.856s | 0.947s | 0.892s |
31
- | react-native-fs-turbo (android) | 0.551s (^6.3) | 0.199s (^14.4) | 0.093s (^10.2) | 0.251s (^3.6) |
32
-
33
- | Library | readFile (utf8) | readFile (base64) |
34
- | ----------------------------------- | --------------- | ----------------- |
35
- | react-native-fs (ios, serial) | 4.082s | 3.058s |
36
- | react-native-fs (ios, parallel) | 3.020s | 2.738s |
37
- | react-native-fs-turbo (ios) | 1.525s (^2.0) | 1.617s (^1.7) |
38
- | react-native-fs (android, serial) | 10.533s | 4.735s |
39
- | react-native-fs (android, parallel) | 1.944s | 0.928s |
40
- | react-native-fs-turbo (android) | 0.209s (^9.3) | 0.213s (^4.4) |
26
+ #### Basic functions
27
+
28
+ | Library | writeFile | appendFile | writeFile (100Mb, 1 iter) |
29
+ | ----------------------------------- | ------------- | -------------- | -------------------------- |
30
+ | react-native-fs (ios, serial) | 9.793s | 3.424s | 58.608s |
31
+ | react-native-fs (ios, parallel) | 9.251s | 2.911s | -- |
32
+ | react-native-fs-turbo (ios) | 6.254s (^1.5) | 1.836s (^1.6) | 0.192s (^305) |
33
+ | react-native-fs (android, serial) | 8.309s | 5.571s | Crash (10Mb - 6.989s) |
34
+ | react-native-fs (android, parallel) | 1.655s | 1.092s | -- |
35
+ | react-native-fs-turbo (android) | 0.701s (^2.3) | 0.266s (^4.1) | 3.510s (^20) |
36
+
37
+ | Library | readFile (utf8) | readFile (base64) | readFile (100Mb, 1 iter) |
38
+ | ----------------------------------- | --------------- | ----------------- | ------------------------ |
39
+ | react-native-fs (ios, serial) | 5.347s | 4.385s | 120.863s |
40
+ | react-native-fs (ios, parallel) | 4.590s | 4.202s | -- |
41
+ | react-native-fs-turbo (ios) | 1.578s (^2.9) | 1.597s (^2.6) | 0.073s (^1655) |
42
+ | react-native-fs (android, serial) | 9.067s | 3.932s | Crash (10Mb - 13.758s) |
43
+ | react-native-fs (android, parallel) | 2.438s | 0.984s | -- |
44
+ | react-native-fs-turbo (android) | 0.283s (^8.6) | 0.284s (^3.4) | 0.204 (^674) |
45
+
46
+ | Library | stat | unlink |
47
+ | ----------------------------------- | -------------- | ------------- |
48
+ | react-native-fs (ios, serial) | 2.542s | 2.607s |
49
+ | react-native-fs (ios, parallel) | 2.332s | 2.421s |
50
+ | react-native-fs-turbo (ios) | 0.538s (^4.3) | 1.475s (^1.6) |
51
+ | react-native-fs (android, serial) | 4.132s | 5.691s |
52
+ | react-native-fs (android, parallel) | 1.087s | 1.456s |
53
+ | react-native-fs-turbo (android) | 0.159s (^6.8) | 0.401s (^3.6) |
41
54
 
42
55
  | Library | hash (md5) | hash (sha512) | readDir |
43
56
  | ----------------------------------- | ------------- | ------------- | ------------- |
44
- | react-native-fs (ios, serial) | 3.073s | 6.297s | 1.077s |
45
- | react-native-fs (ios, parallel) | 2.675s | 5.437s | 1.059s |
46
- | react-native-fs-turbo (ios) | 1.541 (^1.7) | 3.146s (^1.7) | 0.269s (^3.9) |
47
- | react-native-fs (android, serial) | 5.218s | 12.247s | 0.303s |
48
- | react-native-fs (android, parallel) | 1.386s | 3.525s | 0.308s |
49
- | react-native-fs-turbo (android) | 0.231s (^6.0) | 0.501s (^7.0) | 0.081s (^3.8) |
57
+ | react-native-fs (ios, serial) | 4.452s | 9.040s | 2.181s |
58
+ | react-native-fs (ios, parallel) | 4.216s | 8.602s | 2.154s |
59
+ | react-native-fs-turbo (ios) | 1.616s (^2.6) | 3.271s (^2.6) | 0.447s (^4.8) |
60
+ | react-native-fs (android, serial) | 4.124s | 9.609s | 0.303s |
61
+ | react-native-fs (android, parallel) | 1.696s | 4.560s | 0.407s |
62
+ | react-native-fs-turbo (android) | 0.301s (^5.6) | 0.640s (^7.1) | 0.083s (^4.9) |
63
+
64
+ #### AES256 Encryption (extra)
65
+
66
+ | Library | readFile (cbc) | writeFile (cbc) |
67
+ | ----------------------------------- | -------------- | --------------- |
68
+ | react-native-fs-turbo (ios) | 1.602s | 6.515s |
69
+ | react-native-fs-turbo (android) | 0.406s | 2.215s |
50
70
 
51
71
  </details>
52
72
 
@@ -69,6 +89,32 @@ If you're using Proguard, make sure to add the following rule at proguard-rules.
69
89
  -keep class com.cmpayc.rnfsturbo.** { *; }
70
90
  ```
71
91
 
92
+ ### AES256 Encryption (disabled by default)
93
+ To enable AES256 encryption methods, you need to add encryption flags to Android and iOS builds.
94
+
95
+ #### iOS
96
+ Add a new strings to `ios/Podfile` file to `post_install` section
97
+
98
+ ```ruby
99
+ post_install do |installer|
100
+ ...
101
+ installer.pods_project.targets.each do |target|
102
+ if target.name == 'RNFSTurbo'
103
+ target.build_configurations.each do |config|
104
+ config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', 'RNFSTURBO_USE_ENCRYPTION=1']
105
+ end
106
+ end
107
+ end
108
+ end
109
+ ```
110
+
111
+ #### Android
112
+ Add a new string to `android/gradle.properties` file
113
+
114
+ ```
115
+ rnFsTurboUseEncryption=true
116
+ ```
117
+
72
118
  ## Usage
73
119
 
74
120
  ### Import
@@ -208,6 +254,33 @@ const uploadJob = RNFSTurbo.uploadFiles(
208
254
  console.log('Upload job id', uploadJob.jobId);
209
255
  ```
210
256
 
257
+ #### Encryption (extra)
258
+
259
+ ```ts
260
+ const aesKey = '29f4734849a0ee82fd9fd56e9cc4d163';
261
+
262
+ RNFSTurbo.writeFile(
263
+ `${RNFSTurbo.DocumentDirectoryPath}/encrypted.txt`,
264
+ 'Hello world!',
265
+ {
266
+ encrypted: true,
267
+ passphrase: aesKey,
268
+ mode: 'ecb',
269
+ },
270
+ );
271
+
272
+ const decrypted = RNFSTurbo.readFile(
273
+ `${RNFSTurbo.DocumentDirectoryPath}/encrypted.txt`,
274
+ {
275
+ encrypted: true,
276
+ passphrase: aesKey,
277
+ mode: 'ecb',
278
+ },
279
+ );
280
+
281
+ console.log('Decrypted data', decrypted);
282
+ ```
283
+
211
284
  ## API
212
285
 
213
286
  ### Constants
@@ -298,7 +371,15 @@ Reads the file at `path` and return contents. `options` can be string of encrypt
298
371
  ```ts
299
372
  type ReadOptions =
300
373
  | 'utf8' | 'ascii' | 'base64' | 'uint8' | 'float32'
301
- | { encoding: 'utf8' | 'ascii' | 'base64' | 'uint8' | 'float32' };
374
+ | {
375
+ encoding: 'utf8' | 'ascii' | 'base64' | 'uint8' | 'float32'.
376
+ // Next flags will work only if encryption is enabled
377
+ encrypted?: boolean;
378
+ passphrase?: string | number[];
379
+ iv?: string | number[];
380
+ mode?: "ecb" | "cbc" | "cfb";
381
+ padding?: "ansi_x9.23" | "iso/iec_7816-4" | "pkcs5/pkcs7" | "zero" | "no";
382
+ };
302
383
  ```
303
384
 
304
385
  Note: you will take quite a performance hit if you are reading big files
@@ -315,6 +396,7 @@ type ReadOptions =
315
396
 
316
397
  Note: reading big files piece by piece using this method may be useful in terms of performance.
317
398
  Note: `float32` size is 4 bytes, so `position` and `length` should be specified in bytes (multiplied by 4)
399
+ Note: encryption doesn't work for partial file reading
318
400
 
319
401
  ### (Android only) `readFileAssets(filepath: string, options?: ReadOptions) => string[]`
320
402
 
@@ -352,7 +434,13 @@ type WriteOptions =
352
434
  | "NSFileProtectionComplete"
353
435
  | "NSFileProtectionCompleteUnlessOpen"
354
436
  | "NSFileProtectionCompleteUntilFirstUserAuthentication"
355
- | "NSFileProtectionCompleteWhenUserInactive" // iOS 17+ only
437
+ | "NSFileProtectionCompleteWhenUserInactive" // iOS 17+ only,
438
+ // Next flags will work only if encryption is enabled
439
+ encrypted?: boolean;
440
+ passphrase?: string | number[];
441
+ iv?: string | number[];
442
+ mode?: "ecb" | "cbc" | "cfb";
443
+ padding?: "ansi_x9.23" | "iso/iec_7816-4" | "pkcs5/pkcs7" | "zero" | "no";
356
444
  };
357
445
  ```
358
446
 
@@ -376,6 +464,8 @@ type WriteOptions =
376
464
  };
377
465
  ```
378
466
 
467
+ Note: encryption doesn't work for to partially write a file
468
+
379
469
  (IOS only): `options.NSFileProtectionKey` property can be provided to set this attribute on iOS platforms.
380
470
 
381
471
  ### `write(filepath: string, contents: string | number[], position?: number, options?: WriteOptions): void`
@@ -397,6 +487,7 @@ type WriteOptions =
397
487
  ```
398
488
 
399
489
  Note: `float32` size is 4 bytes, so `position` should be specified in bytes (multiplied by 4)
490
+ Note: encryption doesn't work for to partially write a file
400
491
 
401
492
  (IOS only): `options.NSFileProtectionKey` property can be provided to set this attribute on iOS platforms.
402
493
 
@@ -711,6 +802,7 @@ type FSInfoResult = {
711
802
  freeSpace: number; // The amount of available storage space on the device (in bytes).
712
803
  totalSpaceEx?: number; // The amount of available external storage space on the device (in bytes) (android only)
713
804
  freeSpaceEx?: number; // The amount of available external storage space on the device (in bytes) (android only)
805
+ encryptionEnabled: boolean; // Check if encryption is enabled in the RNFSTurbo library
714
806
  };
715
807
  ```
716
808
 
package/RNFSTurbo.podspec CHANGED
@@ -17,10 +17,10 @@ Pod::Spec.new do |s|
17
17
  "cpp/**/*.{hpp,cpp,c,h}",
18
18
  ]
19
19
  s.resource_bundles = { 'RNFSTurbo_PrivacyInfo' => 'ios/PrivacyInfo.xcprivacy' }
20
- s.compiler_flags = '-x objective-c++'
20
+ s.compiler_flags = '-x objective-c++ -DUSE_ARM_AES'
21
21
  s.frameworks = 'Photos', 'AVFoundation'
22
22
  s.pod_target_xcconfig = {
23
- "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
23
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++20"
24
24
  }
25
25
  install_modules_dependencies(s)
26
26
  end
@@ -4,14 +4,17 @@ project(RNFSTurbo)
4
4
  set(CMAKE_VERBOSE_MAKEFILE ON)
5
5
  set(CMAKE_CXX_STANDARD 20)
6
6
 
7
- # Compile sources
8
- add_library(
9
- react-native-fs-turbo
10
- SHARED
7
+ set(
8
+ ANDROID_SOURCES
11
9
  src/main/cpp/RNFSTurboLogger.cpp
12
10
  src/main/cpp/RNFSTurboPlatformHelper.cpp
11
+ src/main/cpp/JNIOnLoad.cpp
12
+ src/main/cpp/RNFSTurboModule.cpp
13
+ )
14
+ set(
15
+ SHARED_SOURCES
13
16
  ../cpp/RNFSTurboHostObject.cpp
14
- ../cpp/NativeRNFSTurboModule.cpp
17
+ ../cpp/RNFSTurboInstall.cpp
15
18
  ../cpp/algorithms/base64.cpp
16
19
  ../cpp/algorithms/md5.cpp
17
20
  ../cpp/algorithms/sha1.cpp
@@ -19,18 +22,68 @@ add_library(
19
22
  ../cpp/algorithms/sha256.cpp
20
23
  ../cpp/algorithms/sha384.cpp
21
24
  ../cpp/algorithms/sha512.cpp
22
- ../cpp/filesystem/helpers.cpp
25
+ ../cpp/algorithms/base64.cpp
26
+ ../cpp/filesystem/filesystem-utils.cpp
27
+ )
28
+
29
+ if(RNFSTURBO_USE_ENCRYPTION)
30
+ set(CMAKE_CXX_FLAGS "-DUSE_ARM_AES")
31
+ add_definitions(-DRNFSTURBO_USE_ENCRYPTION)
32
+
33
+ list(
34
+ APPEND
35
+ SHARED_SOURCES
36
+ ../cpp/algorithms/Krypt/bytearray.cpp
37
+ ../cpp/algorithms/Krypt/functions.cpp
38
+ ../cpp/algorithms/Krypt/AES.cpp
39
+ ../cpp/algorithms/Krypt/mode.cpp
40
+ ../cpp/algorithms/Krypt/padding.cpp
41
+ ../cpp/encryption/encryption-utils.cpp
42
+ )
43
+ endif()
44
+
45
+ # Compile sources
46
+ add_library(
47
+ RNFSTurbo
48
+ SHARED
49
+ ${ANDROID_SOURCES}
50
+ ${SHARED_SOURCES}
23
51
  )
24
52
 
25
53
  # Add headers search paths
26
- target_include_directories(react-native-fs-turbo PUBLIC ../cpp)
54
+ target_include_directories(
55
+ RNFSTurbo
56
+ PUBLIC
57
+ src/main/cpp
58
+ ../cpp
59
+ )
27
60
 
28
61
  # Add android/log dependency
29
62
  find_library(log-lib log)
30
63
 
64
+ # Add react dependencies
65
+ find_package(fbjni)
66
+ find_package(ReactAndroid)
67
+
68
+ # Link all libraries together
31
69
  target_link_libraries(
32
- react-native-fs-turbo
70
+ RNFSTurbo
33
71
  ${log-lib} # <-- Logcat logger
34
72
  android # <-- Android JNI core
35
- react_codegen_RNFSTurboSpec # <-- Generated Specs from CodeGen
73
+ fbjni::fbjni # <-- Facebook C++ JNI helpers
74
+ ReactAndroid::jsi # <-- RN: JSI
36
75
  )
76
+
77
+ # Link react-native (different prefab between RN 0.75 and RN 0.76)
78
+ if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
79
+ target_link_libraries(
80
+ RNFSTurbo
81
+ ReactAndroid::reactnative # <-- RN: Native Modules umbrella prefab
82
+ )
83
+ else()
84
+ target_link_libraries(
85
+ RNFSTurbo
86
+ ReactAndroid::react_nativemodule_core # <-- RN: TurboModules Core
87
+ ReactAndroid::turbomodulejsijni # <-- RN: TurboModules utils (e.g. CallInvokerHolder)
88
+ )
89
+ endif()
@@ -5,10 +5,15 @@ buildscript {
5
5
  }
6
6
 
7
7
  dependencies {
8
- classpath "com.android.tools.build:gradle:7.2.1"
8
+ classpath "com.android.tools.build:gradle:8.13.0"
9
9
  }
10
10
  }
11
11
 
12
+ def reactNativeArchitectures() {
13
+ def value = rootProject.getProperties().get("reactNativeArchitectures")
14
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
15
+ }
16
+
12
17
  def isNewArchitectureEnabled() {
13
18
  return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
14
19
  }
@@ -27,6 +32,12 @@ def getExtOrIntegerDefault(name) {
27
32
  return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["RNFSTurbo_" + name]).toInteger()
28
33
  }
29
34
 
35
+ def getExtOrBooleanDefault(name) {
36
+ return Boolean.parseBoolean(getExtOrDefault(name))
37
+ }
38
+
39
+ def useEncryption = getExtOrBooleanDefault("rnFsTurboUseEncryption")
40
+
30
41
  def supportsNamespace() {
31
42
  def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
32
43
  def major = parsed[0].toInteger()
@@ -54,10 +65,65 @@ android {
54
65
  minSdkVersion getExtOrIntegerDefault("minSdkVersion")
55
66
  targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
56
67
  buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
68
+
69
+ externalNativeBuild {
70
+ cmake {
71
+ cppFlags "-frtti -fexceptions -fstack-protector-all"
72
+ arguments "-DANDROID_STL=c++_shared"
73
+ if (useEncryption) {
74
+ arguments.add("-DRNFSTURBO_USE_ENCRYPTION=1")
75
+ }
76
+ abiFilters (*reactNativeArchitectures())
77
+
78
+ buildTypes {
79
+ debug {
80
+ cppFlags "-O1 -g"
81
+ }
82
+ release {
83
+ cppFlags "-O2"
84
+ }
85
+ }
86
+ }
87
+ }
88
+ }
89
+
90
+ externalNativeBuild {
91
+ cmake {
92
+ path "CMakeLists.txt"
93
+ }
57
94
  }
58
95
 
59
96
  buildFeatures {
60
97
  buildConfig true
98
+ prefab true
99
+ prefabPublishing true
100
+ }
101
+
102
+ packagingOptions {
103
+ excludes = [
104
+ "META-INF",
105
+ "META-INF/**",
106
+ "**/libc++_shared.so",
107
+ "**/libfbjni.so",
108
+ "**/libjsi.so",
109
+ "**/libfolly_json.so",
110
+ "**/libfolly_runtime.so",
111
+ "**/libglog.so",
112
+ "**/libhermes.so",
113
+ "**/libhermes-executor-debug.so",
114
+ "**/libhermes_executor.so",
115
+ "**/libreactnative.so",
116
+ "**/libreactnativejni.so",
117
+ "**/libturbomodulejsijni.so",
118
+ "**/libreact_nativemodule_core.so",
119
+ "**/libjscexecutor.so"
120
+ ]
121
+ }
122
+
123
+ prefab {
124
+ RNFSTurbo {
125
+ headers "${project.buildDir}/headers/rnfsturbo/"
126
+ }
61
127
  }
62
128
 
63
129
  buildTypes {
@@ -79,8 +145,9 @@ android {
79
145
  main {
80
146
  if (isNewArchitectureEnabled()) {
81
147
  java.srcDirs += [
82
- // This is needed to build Kotlin project with NewArch enabled
83
- "${project.buildDir}/generated/source/codegen/java"
148
+ // This is needed to build a project with NewArch enabled
149
+ "${project.buildDir}/generated/source/codegen/java",
150
+ "src/main/codegen"
84
151
  ]
85
152
  }
86
153
  }
@@ -104,3 +171,13 @@ if (isNewArchitectureEnabled()) {
104
171
  codegenJavaPackageName = "com.cmpayc.rnfsturbo"
105
172
  }
106
173
  }
174
+
175
+ tasks.register('prepareHeaders', Copy) {
176
+ from fileTree('./src/main/cpp').filter { it.isFile() }
177
+ from fileTree('../cpp/').filter { it.isFile() }
178
+ include "*.h"
179
+ into "${project.buildDir}/headers/rnfsturbo/RNFSTurbo/"
180
+ includeEmptyDirs = false
181
+ }
182
+
183
+ preBuild.dependsOn(prepareHeaders)
@@ -1,5 +1,5 @@
1
- RNFSTurbo_kotlinVersion=1.7.0
2
- RNFSTurbo_minSdkVersion=21
3
- RNFSTurbo_targetSdkVersion=31
4
- RNFSTurbo_compileSdkVersion=31
5
- RNFSTurbo_ndkversion=21.4.7075529
1
+ RNFSTurbo_kotlinVersion=2.1.20
2
+ RNFSTurbo_minSdkVersion=23
3
+ RNFSTurbo_targetSdkVersion=36
4
+ RNFSTurbo_compileSdkVersion=36
5
+ RNFSTurbo_ndkVersion=27.1.12297006
@@ -0,0 +1,17 @@
1
+ //
2
+ // RNFSTurboModule.java
3
+ // react-native-fs-turbo
4
+ //
5
+ // Created by Sergei Kazakov on 20.10.25.
6
+ //
7
+
8
+ package com.cmpayc.rnfsturbo;
9
+
10
+ import com.facebook.react.bridge.ReactApplicationContext;
11
+
12
+ public abstract class RNFSTurboSpec extends NativeRNFSTurboModuleSpec {
13
+
14
+ public RNFSTurboSpec(ReactApplicationContext context) {
15
+ super(context);
16
+ }
17
+ }
@@ -0,0 +1,18 @@
1
+ //
2
+ // JNIOnLoad.cpp
3
+ // react-native-fs-turbo
4
+ //
5
+ // Created by Sergei Kazakov on 20.10.25.
6
+ //
7
+
8
+ #include "RNFSTurboModule.h"
9
+ #include <fbjni/fbjni.h>
10
+ #include <jni.h>
11
+
12
+ using namespace cmpayc::rnfsturbo;
13
+
14
+ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
15
+ return facebook::jni::initialize(vm, [] {
16
+ RNFSTurboModule::registerNatives();
17
+ });
18
+ }
@@ -8,9 +8,13 @@
8
8
  #import "RNFSTurboLogger.h"
9
9
  #include <android/log.h>
10
10
 
11
+ namespace cmpayc::rnfsturbo {
12
+
11
13
  void RNFSTurboLogger::log(const std::string& tag, const std::string& message) {
12
14
  #pragma clang diagnostic push
13
15
  #pragma clang diagnostic ignored "-Wformat-security"
14
16
  __android_log_print(ANDROID_LOG_INFO, tag.c_str(), message.c_str());
15
17
  #pragma clang diagnostic pop
16
18
  }
19
+
20
+ }
@@ -0,0 +1,44 @@
1
+ //
2
+ // RNFSTurboModule.cpp
3
+ // react-native-fs-turbo
4
+ //
5
+ // Created by Sergei Kazakov on 19.10.25.
6
+ //
7
+
8
+ #include "RNFSTurboModule.h"
9
+ #include "RNFSTurboInstall.h"
10
+ #include "RNFSTurboLogger.h"
11
+
12
+ #include <exception>
13
+
14
+ namespace cmpayc::rnfsturbo {
15
+
16
+ jni::local_ref<RNFSTurboModule::jhybriddata> RNFSTurboModule::initHybrid(jni::alias_ref<RNFSTurboModule::jhybridobject>) {
17
+ return makeCxxInstance();
18
+ }
19
+
20
+ bool RNFSTurboModule::createRNFSTurbo(jlong runtimePointer, jni::alias_ref<react::CallInvokerHolder::javaobject> callInvokerHolder) {
21
+ auto runtime = reinterpret_cast<jsi::Runtime*>(runtimePointer);
22
+ if (runtime == nullptr) {
23
+ throw std::invalid_argument("jsi::Runtime not found");
24
+ }
25
+
26
+ if (callInvokerHolder == nullptr) {
27
+ throw std::invalid_argument("CallInvoker not found");
28
+ }
29
+ auto callInvoker = callInvokerHolder->cthis()->getCallInvoker();
30
+ if (callInvoker == nullptr) {
31
+ throw std::invalid_argument("CallInvoker not found");
32
+ }
33
+
34
+ return cmpayc::rnfsturbo::install(*runtime, callInvoker);
35
+ }
36
+
37
+ void RNFSTurboModule::registerNatives() {
38
+ registerHybrid({
39
+ makeNativeMethod("initHybrid", RNFSTurboModule::initHybrid),
40
+ makeNativeMethod("createRNFSTurbo", RNFSTurboModule::createRNFSTurbo),
41
+ });
42
+ }
43
+
44
+ } // namespace cmpayc::rnfsturbo
@@ -0,0 +1,40 @@
1
+ //
2
+ // RNFSTurboModule.h
3
+ // react-native-fs-turbo
4
+ //
5
+ // Created by Sergei Kazakov on 20.10.25.
6
+ //
7
+
8
+ #pragma once
9
+
10
+ #include <ReactCommon/CallInvoker.h>
11
+ #include <ReactCommon/CallInvokerHolder.h>
12
+ #include <fbjni/fbjni.h>
13
+ #include <jsi/jsi.h>
14
+
15
+ namespace cmpayc::rnfsturbo {
16
+
17
+ using namespace facebook;
18
+
19
+ class RNFSTurboModule final : public jni::HybridClass<RNFSTurboModule> {
20
+ public:
21
+ static auto constexpr kJavaDescriptor = "Lcom/cmpayc/rnfsturbo/RNFSTurboModule;";
22
+
23
+ private:
24
+ explicit RNFSTurboModule() = default;
25
+
26
+ private:
27
+ static jni::local_ref<RNFSTurboModule::jhybriddata> initHybrid(jni::alias_ref<jhybridobject> javaThis);
28
+
29
+ bool createRNFSTurbo(jlong runtimePointer, jni::alias_ref<react::CallInvokerHolder::javaobject> callInvokerHolder);
30
+
31
+ private:
32
+ static auto constexpr TAG = "RNFSTurboModule";
33
+ using HybridBase::HybridBase;
34
+ friend HybridBase;
35
+
36
+ public:
37
+ static void registerNatives();
38
+ };
39
+
40
+ } // namespace cmpayc::rnfsturbo
@@ -9,6 +9,8 @@
9
9
  #include "RNFSTurboPlatformHelper.h"
10
10
  #include "RNFSTurboLogger.h"
11
11
 
12
+ namespace cmpayc::rnfsturbo {
13
+
12
14
  void JavaHashMapToStlStringStringMap(JNIEnv *env, jobject hashMap, std::map<std::string, std::string>& mapOut) {
13
15
  // Get the Map's entry Set.
14
16
  jclass mapClass = env->FindClass("java/util/Map");
@@ -303,7 +305,7 @@ RNFSTurboPlatformHelper::RNFSTurboPlatformHelper(JNIEnv *env) {
303
305
  jniEnv = env;
304
306
  jclass jniCls = env->FindClass("com/cmpayc/rnfsturbo/RNFSTurboPlatformHelper");
305
307
  jmethodID initObject = jniEnv->GetMethodID(jniCls, "<init>", "(Landroid/content/Context;)V");
306
- jclass contextCls = env->FindClass("com/cmpayc/rnfsturbo/RNFSTurboPlatformContextModule");
308
+ jclass contextCls = env->FindClass("com/cmpayc/rnfsturbo/RNFSTurboModule");
307
309
  jmethodID mid = env->GetStaticMethodID(contextCls, "getContext", "()Landroid/content/Context;");
308
310
  jobject context = env->CallStaticObjectMethod(contextCls, mid);
309
311
  jobject obj = jniEnv->NewObject(jniCls, initObject, context);
@@ -719,3 +721,5 @@ std::vector<std::string> RNFSTurboPlatformHelper::getAllExternalFilesDirs() {
719
721
 
720
722
  return items;
721
723
  }
724
+
725
+ }
@@ -0,0 +1,27 @@
1
+ //
2
+ // JNIOnLoad.java
3
+ // react-native-fs-turbo
4
+ //
5
+ // Created by Sergei Kazakov on 20.10.25.
6
+ //
7
+
8
+ package com.cmpayc.rnfsturbo;
9
+
10
+ import android.util.Log;
11
+
12
+ public class JNIOnLoad {
13
+ private static final String TAG = "RNFSTurboModule";
14
+
15
+ private static boolean isInitialized = false;
16
+
17
+ public synchronized static void initializeNativeRNFSTurboModule() {
18
+ if (isInitialized) return;
19
+ try {
20
+ System.loadLibrary("RNFSTurbo");
21
+ isInitialized = true;
22
+ } catch (Throwable e) {
23
+ Log.e(TAG, "Failed to load RNFSTurbo C++ library", e);
24
+ throw e;
25
+ }
26
+ }
27
+ }