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.
- package/README.md +119 -27
- package/RNFSTurbo.podspec +2 -2
- package/android/CMakeLists.txt +62 -9
- package/android/build.gradle +80 -3
- package/android/gradle.properties +5 -5
- package/android/src/main/codegen/RNFSTurboSpec.java +17 -0
- package/android/src/main/cpp/JNIOnLoad.cpp +18 -0
- package/android/src/main/cpp/RNFSTurboLogger.cpp +4 -0
- package/android/src/main/cpp/RNFSTurboModule.cpp +44 -0
- package/android/src/main/cpp/RNFSTurboModule.h +40 -0
- package/android/src/main/cpp/RNFSTurboPlatformHelper.cpp +5 -1
- package/android/src/main/java/com/cmpayc/rnfsturbo/JNIOnLoad.java +27 -0
- package/android/src/main/java/com/cmpayc/rnfsturbo/{RNFSTurboPlatformContextModule.java → RNFSTurboModule.java} +62 -11
- package/android/src/main/java/com/cmpayc/rnfsturbo/RNFSTurboPackage.java +11 -9
- package/cpp/RNFSTurboHostObject.cpp +138 -15
- package/cpp/RNFSTurboHostObject.h +12 -4
- package/cpp/RNFSTurboInstall.cpp +27 -0
- package/cpp/RNFSTurboInstall.h +20 -0
- package/cpp/RNFSTurboLogger.h +4 -0
- package/cpp/RNFSTurboPlatformHelper.h +4 -0
- package/cpp/algorithms/Krypt/AES.cpp +502 -0
- package/cpp/algorithms/Krypt/bytearray.cpp +158 -0
- package/cpp/algorithms/Krypt/functions.cpp +137 -0
- package/cpp/algorithms/Krypt/mode.cpp +203 -0
- package/cpp/algorithms/Krypt/padding.cpp +219 -0
- package/cpp/encryption/encryption-utils.cpp +162 -0
- package/cpp/encryption/encryption-utils.h +43 -0
- package/cpp/filesystem/{helpers.cpp → filesystem-utils.cpp} +5 -1
- package/cpp/filesystem/{helpers.h → filesystem-utils.h} +4 -0
- package/ios/RNFSTurboLogger.mm +4 -0
- package/ios/{RNFSTurboPlatformContextModule.h → RNFSTurboModule.h} +3 -3
- package/ios/{RNFSTurboPlatformContextModule.mm → RNFSTurboModule.mm} +22 -5
- package/ios/RNFSTurboPlatformHelper.mm +4 -0
- package/lib/commonjs/NativeRNFSTurboModule.js +14 -16
- package/lib/commonjs/NativeRNFSTurboModule.js.map +1 -1
- package/lib/commonjs/createRNFSTurbo.js +3 -2
- package/lib/commonjs/createRNFSTurbo.js.map +1 -1
- package/lib/commonjs/globals.d.js +6 -0
- package/lib/commonjs/globals.d.js.map +1 -0
- package/lib/module/NativeRNFSTurboModule.js +14 -16
- package/lib/module/NativeRNFSTurboModule.js.map +1 -1
- package/lib/module/createRNFSTurbo.js +3 -2
- package/lib/module/createRNFSTurbo.js.map +1 -1
- package/lib/module/globals.d.js +4 -0
- package/lib/module/globals.d.js.map +1 -0
- package/lib/typescript/NativeRNFSTurboModule.d.ts +12 -3
- package/lib/typescript/NativeRNFSTurboModule.d.ts.map +1 -1
- package/lib/typescript/Types.d.ts +11 -0
- package/lib/typescript/Types.d.ts.map +1 -1
- package/lib/typescript/createRNFSTurbo.d.ts.map +1 -1
- package/package.json +6 -3
- package/react-native.config.js +1 -5
- package/src/NativeRNFSTurboModule.ts +25 -21
- package/src/Types.ts +11 -0
- package/src/createRNFSTurbo.ts +4 -2
- package/src/globals.d.ts +9 -0
- package/cpp/NativeRNFSTurboModule.cpp +0 -24
- package/cpp/NativeRNFSTurboModule.h +0 -31
- package/ios/RNFSTurboOnLoad.mm +0 -25
- package/lib/commonjs/NativeRNFSTurboPlatformContextModule.js +0 -22
- package/lib/commonjs/NativeRNFSTurboPlatformContextModule.js.map +0 -1
- package/lib/module/NativeRNFSTurboPlatformContextModule.js +0 -18
- package/lib/module/NativeRNFSTurboPlatformContextModule.js.map +0 -1
- package/lib/typescript/NativeRNFSTurboPlatformContextModule.d.ts +0 -16
- package/lib/typescript/NativeRNFSTurboPlatformContextModule.d.ts.map +0 -1
- 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.
|
|
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
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
| react-native-fs
|
|
29
|
-
| react-native-fs (
|
|
30
|
-
| react-native-fs (
|
|
31
|
-
| react-native-fs
|
|
32
|
-
|
|
33
|
-
|
|
|
34
|
-
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
| react-native-fs
|
|
38
|
-
| react-native-fs (
|
|
39
|
-
| react-native-fs (
|
|
40
|
-
| react-native-fs
|
|
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) |
|
|
45
|
-
| react-native-fs (ios, parallel) |
|
|
46
|
-
| react-native-fs-turbo (ios) | 1.
|
|
47
|
-
| react-native-fs (android, serial) |
|
|
48
|
-
| react-native-fs (android, parallel) | 1.
|
|
49
|
-
| react-native-fs-turbo (android) | 0.
|
|
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
|
-
| {
|
|
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++
|
|
23
|
+
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20"
|
|
24
24
|
}
|
|
25
25
|
install_modules_dependencies(s)
|
|
26
26
|
end
|
package/android/CMakeLists.txt
CHANGED
|
@@ -4,14 +4,17 @@ project(RNFSTurbo)
|
|
|
4
4
|
set(CMAKE_VERBOSE_MAKEFILE ON)
|
|
5
5
|
set(CMAKE_CXX_STANDARD 20)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
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/
|
|
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/
|
|
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(
|
|
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
|
-
|
|
70
|
+
RNFSTurbo
|
|
33
71
|
${log-lib} # <-- Logcat logger
|
|
34
72
|
android # <-- Android JNI core
|
|
35
|
-
|
|
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()
|
package/android/build.gradle
CHANGED
|
@@ -5,10 +5,15 @@ buildscript {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
dependencies {
|
|
8
|
-
classpath "com.android.tools.build:gradle:
|
|
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
|
|
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.
|
|
2
|
-
RNFSTurbo_minSdkVersion=
|
|
3
|
-
RNFSTurbo_targetSdkVersion=
|
|
4
|
-
RNFSTurbo_compileSdkVersion=
|
|
5
|
-
|
|
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/
|
|
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
|
+
}
|