react-native-fs-turbo 0.3.6 → 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 +128 -27
- package/RNFSTurbo.podspec +2 -2
- package/android/CMakeLists.txt +63 -10
- 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
|
|
|
@@ -60,6 +80,41 @@ yarn add react-native-fs-turbo
|
|
|
60
80
|
cd ios && pod install
|
|
61
81
|
```
|
|
62
82
|
|
|
83
|
+
### Android
|
|
84
|
+
|
|
85
|
+
#### Proguard
|
|
86
|
+
If you're using Proguard, make sure to add the following rule at proguard-rules.pro:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
-keep class com.cmpayc.rnfsturbo.** { *; }
|
|
90
|
+
```
|
|
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
|
+
|
|
63
118
|
## Usage
|
|
64
119
|
|
|
65
120
|
### Import
|
|
@@ -199,6 +254,33 @@ const uploadJob = RNFSTurbo.uploadFiles(
|
|
|
199
254
|
console.log('Upload job id', uploadJob.jobId);
|
|
200
255
|
```
|
|
201
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
|
+
|
|
202
284
|
## API
|
|
203
285
|
|
|
204
286
|
### Constants
|
|
@@ -289,7 +371,15 @@ Reads the file at `path` and return contents. `options` can be string of encrypt
|
|
|
289
371
|
```ts
|
|
290
372
|
type ReadOptions =
|
|
291
373
|
| 'utf8' | 'ascii' | 'base64' | 'uint8' | 'float32'
|
|
292
|
-
| {
|
|
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
|
+
};
|
|
293
383
|
```
|
|
294
384
|
|
|
295
385
|
Note: you will take quite a performance hit if you are reading big files
|
|
@@ -306,6 +396,7 @@ type ReadOptions =
|
|
|
306
396
|
|
|
307
397
|
Note: reading big files piece by piece using this method may be useful in terms of performance.
|
|
308
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
|
|
309
400
|
|
|
310
401
|
### (Android only) `readFileAssets(filepath: string, options?: ReadOptions) => string[]`
|
|
311
402
|
|
|
@@ -343,7 +434,13 @@ type WriteOptions =
|
|
|
343
434
|
| "NSFileProtectionComplete"
|
|
344
435
|
| "NSFileProtectionCompleteUnlessOpen"
|
|
345
436
|
| "NSFileProtectionCompleteUntilFirstUserAuthentication"
|
|
346
|
-
| "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";
|
|
347
444
|
};
|
|
348
445
|
```
|
|
349
446
|
|
|
@@ -367,6 +464,8 @@ type WriteOptions =
|
|
|
367
464
|
};
|
|
368
465
|
```
|
|
369
466
|
|
|
467
|
+
Note: encryption doesn't work for to partially write a file
|
|
468
|
+
|
|
370
469
|
(IOS only): `options.NSFileProtectionKey` property can be provided to set this attribute on iOS platforms.
|
|
371
470
|
|
|
372
471
|
### `write(filepath: string, contents: string | number[], position?: number, options?: WriteOptions): void`
|
|
@@ -388,6 +487,7 @@ type WriteOptions =
|
|
|
388
487
|
```
|
|
389
488
|
|
|
390
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
|
|
391
491
|
|
|
392
492
|
(IOS only): `options.NSFileProtectionKey` property can be provided to set this attribute on iOS platforms.
|
|
393
493
|
|
|
@@ -702,6 +802,7 @@ type FSInfoResult = {
|
|
|
702
802
|
freeSpace: number; // The amount of available storage space on the device (in bytes).
|
|
703
803
|
totalSpaceEx?: number; // The amount of available external storage space on the device (in bytes) (android only)
|
|
704
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
|
|
705
806
|
};
|
|
706
807
|
```
|
|
707
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
|
@@ -2,16 +2,19 @@ cmake_minimum_required(VERSION 3.9.0)
|
|
|
2
2
|
project(RNFSTurbo)
|
|
3
3
|
|
|
4
4
|
set(CMAKE_VERBOSE_MAKEFILE ON)
|
|
5
|
-
set(CMAKE_CXX_STANDARD
|
|
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
|
+
}
|