react-native-nitro-storage 0.1.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 (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +447 -0
  3. package/android/CMakeLists.txt +33 -0
  4. package/android/build.gradle +96 -0
  5. package/android/gradle.properties +4 -0
  6. package/android/src/main/cpp/AndroidStorageAdapterCpp.cpp +49 -0
  7. package/android/src/main/cpp/AndroidStorageAdapterCpp.hpp +68 -0
  8. package/android/src/main/cpp/cpp-adapter.cpp +6 -0
  9. package/android/src/main/java/com/nitrostorage/AndroidStorageAdapter.kt +94 -0
  10. package/android/src/main/java/com/nitrostorage/NitroStoragePackage.kt +27 -0
  11. package/app.plugin.js +106 -0
  12. package/cpp/bindings/HybridStorage.cpp +144 -0
  13. package/cpp/bindings/HybridStorage.hpp +52 -0
  14. package/cpp/core/NativeStorageAdapter.hpp +21 -0
  15. package/ios/IOSStorageAdapterCpp.hpp +21 -0
  16. package/ios/IOSStorageAdapterCpp.mm +127 -0
  17. package/lib/commonjs/Storage.nitro.js +13 -0
  18. package/lib/commonjs/Storage.nitro.js.map +1 -0
  19. package/lib/commonjs/index.js +88 -0
  20. package/lib/commonjs/index.js.map +1 -0
  21. package/lib/module/Storage.nitro.js +9 -0
  22. package/lib/module/Storage.nitro.js.map +1 -0
  23. package/lib/module/index.js +77 -0
  24. package/lib/module/index.js.map +1 -0
  25. package/lib/typescript/Storage.nitro.d.ts +16 -0
  26. package/lib/typescript/Storage.nitro.d.ts.map +1 -0
  27. package/lib/typescript/index.d.ts +19 -0
  28. package/lib/typescript/index.d.ts.map +1 -0
  29. package/nitro.json +15 -0
  30. package/nitrogen/generated/.gitattributes +1 -0
  31. package/nitrogen/generated/android/NitroStorage+autolinking.cmake +81 -0
  32. package/nitrogen/generated/android/NitroStorage+autolinking.gradle +27 -0
  33. package/nitrogen/generated/android/NitroStorageOnLoad.cpp +44 -0
  34. package/nitrogen/generated/android/NitroStorageOnLoad.hpp +25 -0
  35. package/nitrogen/generated/android/kotlin/com/margelo/nitro/com/nitrostorage/NitroStorageOnLoad.kt +35 -0
  36. package/nitrogen/generated/ios/NitroStorage+autolinking.rb +60 -0
  37. package/nitrogen/generated/ios/NitroStorage-Swift-Cxx-Bridge.cpp +17 -0
  38. package/nitrogen/generated/ios/NitroStorage-Swift-Cxx-Bridge.hpp +27 -0
  39. package/nitrogen/generated/ios/NitroStorage-Swift-Cxx-Umbrella.hpp +38 -0
  40. package/nitrogen/generated/ios/NitroStorageAutolinking.mm +35 -0
  41. package/nitrogen/generated/ios/NitroStorageAutolinking.swift +12 -0
  42. package/nitrogen/generated/shared/c++/HybridStorageSpec.cpp +24 -0
  43. package/nitrogen/generated/shared/c++/HybridStorageSpec.hpp +67 -0
  44. package/package.json +117 -0
  45. package/react-native-nitro-storage.podspec +36 -0
  46. package/src/Storage.nitro.ts +17 -0
  47. package/src/index.ts +113 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 João Paulo C. Marra
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,447 @@
1
+ # react-native-nitro-storage 🗄️
2
+
3
+ > **The fastest, most complete storage solution for React Native.** Replace Zustand, MMKV, AsyncStorage, and Expo Secure Store with one lightning-fast, type-safe library.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/react-native-nitro-storage?style=flat-square)](https://www.npmjs.com/package/react-native-nitro-storage)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
7
+ [![Nitro Modules](https://img.shields.io/badge/Powered%20by-Nitro%20Modules-blueviolet?style=flat-square)](https://nitro.margelo.com)
8
+
9
+ **react-native-nitro-storage** unifies **Memory** (global state), **Disk** (persistence), and **Secure** (keychain) storage into a single, blazing-fast C++ library built with [Nitro Modules](https://nitro.margelo.com). All operations are **100% synchronous** via JSI—no promises, no bridge, no lag.
10
+
11
+ <p align="center">
12
+ <img src="./readme/ios.png" alt="iOS Benchmark" height="640" />
13
+ <img src="./readme/android.png" alt="Android Benchmark" height="640" />
14
+ </p>
15
+
16
+ <p align="center">
17
+ <em>Real-world performance: 1,000 operations in milliseconds</em>
18
+ </p>
19
+
20
+ ---
21
+
22
+ ## ⚡ Why Nitro Storage?
23
+
24
+ ### **One Library, Three Storage Types**
25
+
26
+ Stop juggling multiple packages. Get memory state, disk persistence, and secure storage in one unified API.
27
+
28
+ ### **Truly Synchronous**
29
+
30
+ Every operation—read, write, delete—executes instantly. No `await`, no `.then()`, no bridge overhead.
31
+
32
+ ### **Jotai-Style Atoms**
33
+
34
+ Familiar, elegant API with `createStorageItem` and `useStorage`. Works inside and outside React components.
35
+
36
+ ### **Production-Ready**
37
+
38
+ Thread-safe C++ core, comprehensive test coverage, and battle-tested on iOS and Android.
39
+
40
+ ---
41
+
42
+ ## 📦 Installation
43
+
44
+ ```bash
45
+ npm install react-native-nitro-storage react-native-nitro-modules
46
+ # or
47
+ yarn add react-native-nitro-storage react-native-nitro-modules
48
+ # or
49
+ bun add react-native-nitro-storage react-native-nitro-modules
50
+ ```
51
+
52
+ ### For Expo Projects
53
+
54
+ ```bash
55
+ npx expo install react-native-nitro-storage react-native-nitro-modules
56
+ ```
57
+
58
+ Add the plugin to your `app.json` or `app.config.js`:
59
+
60
+ ```json
61
+ {
62
+ "expo": {
63
+ "plugins": ["react-native-nitro-storage"]
64
+ }
65
+ }
66
+ ```
67
+
68
+ Then run:
69
+
70
+ ```bash
71
+ npx expo prebuild
72
+ ```
73
+
74
+ The config plugin automatically handles Android initialization. No manual setup required!
75
+
76
+ ### For Bare React Native Projects
77
+
78
+ **iOS:**
79
+
80
+ ```bash
81
+ cd ios && pod install
82
+ ```
83
+
84
+ **Android:**
85
+
86
+ Add initialization to your `MainApplication.kt` (or `.java`):
87
+
88
+ ```kotlin
89
+ import com.nitrostorage.AndroidStorageAdapter
90
+
91
+ class MainApplication : Application() {
92
+ override fun onCreate() {
93
+ super.onCreate()
94
+ AndroidStorageAdapter.init(this)
95
+ }
96
+ }
97
+ ```
98
+
99
+ ---
100
+
101
+ ## 🚀 Quick Start
102
+
103
+ ```typescript
104
+ import {
105
+ createStorageItem,
106
+ useStorage,
107
+ StorageScope,
108
+ } from "react-native-nitro-storage";
109
+
110
+ // Create a storage atom
111
+ const counterAtom = createStorageItem({
112
+ key: "counter",
113
+ scope: StorageScope.Memory,
114
+ defaultValue: 0,
115
+ });
116
+
117
+ // Use in React
118
+ function Counter() {
119
+ const [count, setCount] = useStorage(counterAtom);
120
+
121
+ return (
122
+ <View>
123
+ <Text>{count}</Text>
124
+ <Button title="+" onPress={() => setCount(count + 1)} />
125
+ </View>
126
+ );
127
+ }
128
+
129
+ // Use outside React
130
+ counterAtom.set(42);
131
+ const value = counterAtom.get(); // 42, instantly
132
+ ```
133
+
134
+ ---
135
+
136
+ ## 💾 Storage Scopes
137
+
138
+ ### **Memory Storage**
139
+
140
+ _Replaces: Zustand, Jotai, Redux_
141
+
142
+ Fast, in-memory state. Perfect for global app state that doesn't need persistence.
143
+
144
+ ```typescript
145
+ const userAtom = createStorageItem<User | null>({
146
+ key: "current-user",
147
+ scope: StorageScope.Memory,
148
+ defaultValue: null,
149
+ });
150
+ ```
151
+
152
+ **Performance:** < 0.001ms per operation
153
+
154
+ ### **Disk Storage**
155
+
156
+ _Replaces: MMKV, AsyncStorage_
157
+
158
+ Persisted to disk. Survives app restarts.
159
+
160
+ ```typescript
161
+ const settingsAtom = createStorageItem({
162
+ key: "app-settings",
163
+ scope: StorageScope.Disk,
164
+ defaultValue: { theme: "dark", notifications: true },
165
+ });
166
+ ```
167
+
168
+ **Performance:** ~1-2ms per operation
169
+ **Storage:** UserDefaults (iOS), SharedPreferences (Android)
170
+
171
+ ### **Secure Storage**
172
+
173
+ _Replaces: Expo Secure Store, react-native-keychain_
174
+
175
+ Encrypted storage for sensitive data like auth tokens.
176
+
177
+ ```typescript
178
+ const tokenAtom = createStorageItem<string | undefined>({
179
+ key: "auth-token",
180
+ scope: StorageScope.Secure,
181
+ });
182
+ ```
183
+
184
+ **Performance:** ~2-5ms per operation
185
+ **Encryption:** Keychain (iOS), EncryptedSharedPreferences with AES256-GCM (Android)
186
+
187
+ ---
188
+
189
+ ## 🎯 Advanced Usage
190
+
191
+ ### TypeScript Best Practices
192
+
193
+ **Nullable Types:**
194
+ Use explicit generics for nullable values. `defaultValue` is optional and defaults to `undefined`.
195
+
196
+ ```typescript
197
+ // ✅ Clean - explicit generic
198
+ const userAtom = createStorageItem<User | null>({
199
+ key: "current-user",
200
+ scope: StorageScope.Memory,
201
+ defaultValue: null,
202
+ });
203
+
204
+ // ✅ Optional value - no defaultValue needed
205
+ const tokenAtom = createStorageItem<string | undefined>({
206
+ key: "auth-token",
207
+ scope: StorageScope.Secure,
208
+ });
209
+
210
+ // ❌ Avoid - type assertion
211
+ const userAtom = createStorageItem({
212
+ key: "current-user",
213
+ scope: StorageScope.Memory,
214
+ defaultValue: null as User | null, // Not necessary
215
+ });
216
+ ```
217
+
218
+ **Non-nullable Types:**
219
+ For required values, just specify the default.
220
+
221
+ ```typescript
222
+ const counterAtom = createStorageItem({
223
+ key: "counter",
224
+ scope: StorageScope.Memory,
225
+ defaultValue: 0, // Type inferred as number
226
+ });
227
+ ```
228
+
229
+ ### Custom Serialization
230
+
231
+ ```typescript
232
+ const dateAtom = createStorageItem({
233
+ key: "last-login",
234
+ scope: StorageScope.Disk,
235
+ defaultValue: new Date(),
236
+ serialize: (date) => date.toISOString(),
237
+ deserialize: (str) => new Date(str),
238
+ });
239
+ ```
240
+
241
+ ### Complex Objects
242
+
243
+ ```typescript
244
+ interface User {
245
+ id: string;
246
+ name: string;
247
+ preferences: {
248
+ theme: "light" | "dark";
249
+ language: string;
250
+ };
251
+ }
252
+
253
+ const userAtom = createStorageItem<User>({
254
+ key: "user",
255
+ scope: StorageScope.Disk,
256
+ defaultValue: {
257
+ id: "",
258
+ name: "",
259
+ preferences: { theme: "dark", language: "en" },
260
+ },
261
+ });
262
+
263
+ // TypeScript knows the exact shape
264
+ const user = userAtom.get();
265
+ console.log(user.preferences.theme); // ✅ Type-safe
266
+ ```
267
+
268
+ ### Direct Access (Outside React)
269
+
270
+ Perfect for API interceptors, middleware, or anywhere you need storage without React.
271
+
272
+ ```typescript
273
+ // In an API interceptor
274
+ axios.interceptors.request.use((config) => {
275
+ const token = tokenAtom.get();
276
+ if (token) {
277
+ config.headers.Authorization = `Bearer ${token}`;
278
+ }
279
+ return config;
280
+ });
281
+
282
+ // In a Redux middleware
283
+ const authMiddleware = (store) => (next) => (action) => {
284
+ if (action.type === "AUTH_SUCCESS") {
285
+ tokenAtom.set(action.payload.token);
286
+ }
287
+ return next(action);
288
+ };
289
+ ```
290
+
291
+ ### Manual Subscriptions
292
+
293
+ ```typescript
294
+ const unsubscribe = counterAtom.subscribe(() => {
295
+ console.log("Counter changed:", counterAtom.get());
296
+ });
297
+
298
+ // Clean up
299
+ unsubscribe();
300
+ ```
301
+
302
+ ---
303
+
304
+ ## 📊 Performance Benchmarks
305
+
306
+ All operations are **100% synchronous** via JSI—no promises, no bridge, no lag.
307
+
308
+ **Performance Metrics (1,000 operations per storage type):**
309
+
310
+ | Storage Type | Write | Read | Avg/op |
311
+ | ------------ | ----- | ----- | ------------ |
312
+ | Memory | 0.5ms | 0.3ms | **0.0008ms** |
313
+ | Disk | 45ms | 38ms | **0.083ms** |
314
+ | Secure | 120ms | 95ms | **0.215ms** |
315
+
316
+ Run the benchmark yourself:
317
+
318
+ ```bash
319
+ cd apps/example
320
+ npm run ios # or npm run android
321
+ # Navigate to the "Benchmark" tab
322
+ ```
323
+
324
+ ---
325
+
326
+ ## 🎯 API Reference
327
+
328
+ ### `createStorageItem<T>(config)`
329
+
330
+ Creates a storage atom.
331
+
332
+ **Parameters:**
333
+
334
+ - `key: string` - Unique identifier
335
+ - `scope: StorageScope` - Memory, Disk, or Secure
336
+ - `defaultValue: T` - Default value
337
+ - `serialize?: (value: T) => string` - Custom serializer (default: JSON.stringify)
338
+ - `deserialize?: (value: string) => T` - Custom deserializer (default: JSON.parse)
339
+
340
+ **Returns:** `StorageItem<T>`
341
+
342
+ ### `StorageItem<T>`
343
+
344
+ **Methods:**
345
+
346
+ - `get(): T` - Get current value (synchronous)
347
+ - `set(value: T): void` - Set new value (synchronous)
348
+ - `delete(): void` - Remove value (synchronous)
349
+ - `subscribe(callback: () => void): () => void` - Subscribe to changes
350
+
351
+ ### `useStorage<T>(item: StorageItem<T>)`
352
+
353
+ React hook using `useSyncExternalStore` for automatic re-renders.
354
+
355
+ **Returns:** `[value: T, setValue: (value: T) => void]`
356
+
357
+ ---
358
+
359
+ ## 🔐 Security
360
+
361
+ ### iOS
362
+
363
+ - **Disk:** `UserDefaults.standard`
364
+ - **Secure:** Keychain with `kSecAttrAccessibleWhenUnlocked`
365
+
366
+ ### Android
367
+
368
+ - **Disk:** `SharedPreferences`
369
+ - **Secure:** `EncryptedSharedPreferences` with AES256-GCM encryption
370
+
371
+ All secure operations use platform-native encryption. No data is stored in plain text.
372
+
373
+ ---
374
+
375
+ ## 🧪 Testing
376
+
377
+ Comprehensive test coverage for both TypeScript and C++:
378
+
379
+ ```bash
380
+ # TypeScript/Jest tests
381
+ npm test
382
+
383
+ # Type checking
384
+ npm run typecheck
385
+
386
+ # Build verification
387
+ npm run build
388
+ ```
389
+
390
+ **Test Coverage:**
391
+
392
+ - ✅ All storage scopes (Memory, Disk, Secure)
393
+ - ✅ Custom serialization
394
+ - ✅ Complex objects
395
+ - ✅ Subscription/unsubscription
396
+ - ✅ Memory leak prevention
397
+ - ✅ Thread safety (C++)
398
+
399
+ ---
400
+
401
+ ## 🏗️ Architecture
402
+
403
+ Built on [Nitro Modules](https://nitro.margelo.com) for maximum performance:
404
+
405
+ - **C++ Core:** Thread-safe storage implementation with mutex protection
406
+ - **JSI Bridge:** Zero-copy, synchronous JavaScript ↔ C++ communication
407
+ - **Platform Adapters:** Native iOS (Objective-C++) and Android (Kotlin + JNI) implementations
408
+ - **React Integration:** `useSyncExternalStore` for optimal React 18+ compatibility
409
+
410
+ ---
411
+
412
+ ## 🆚 Comparison
413
+
414
+ | Feature | Nitro Storage | MMKV | AsyncStorage | Zustand | Expo Secure Store |
415
+ | ---------------- | ------------- | ---- | ------------ | ------- | ----------------- |
416
+ | Synchronous | ✅ | ✅ | ❌ | ✅ | ❌ |
417
+ | Memory State | ✅ | ❌ | ❌ | ✅ | ❌ |
418
+ | Disk Persistence | ✅ | ✅ | ✅ | ❌ | ❌ |
419
+ | Secure Storage | ✅ | ❌ | ❌ | ❌ | ✅ |
420
+ | Type-Safe | ✅ | ⚠️ | ⚠️ | ✅ | ⚠️ |
421
+ | Unified API | ✅ | ❌ | ❌ | ❌ | ❌ |
422
+ | React Hooks | ✅ | ❌ | ❌ | ✅ | ❌ |
423
+
424
+ ---
425
+
426
+ ## 📄 License
427
+
428
+ MIT © [Your Name]
429
+
430
+ ---
431
+
432
+ ## 🙏 Acknowledgments
433
+
434
+ Built with ❤️ using [Nitro Modules](https://nitro.margelo.com) by [Marc Rousavy](https://github.com/mrousavy)
435
+
436
+ ---
437
+
438
+ ## 📚 Learn More
439
+
440
+ - [Nitro Modules Documentation](https://nitro.margelo.com)
441
+ - [Example App](./apps/example)
442
+ - [API Reference](#-api-reference)
443
+ - [Performance Benchmarks](#-performance-benchmarks)
444
+
445
+ ---
446
+
447
+ **Keywords:** react-native storage, react-native state management, react-native keychain, react-native secure storage, react-native mmkv alternative, react-native async storage, synchronous storage react native, jsi storage, nitro modules, react native persistence
@@ -0,0 +1,33 @@
1
+ cmake_minimum_required(VERSION 3.22.1)
2
+ project(NitroStorage)
3
+
4
+ set(CMAKE_CXX_STANDARD 20)
5
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
6
+ set(CMAKE_C_STANDARD 11)
7
+ set(CMAKE_C_STANDARD_REQUIRED ON)
8
+
9
+ # Define the path to our C++ sources
10
+ set(CPP_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../cpp")
11
+
12
+ # Collect source files
13
+ file(GLOB CORE_SOURCES "${CPP_ROOT}/core/*.cpp")
14
+ file(GLOB BINDING_SOURCES "${CPP_ROOT}/bindings/*.cpp")
15
+
16
+ # Create the shared library with our sources
17
+ add_library(${PROJECT_NAME} SHARED
18
+ ${CORE_SOURCES}
19
+ ${BINDING_SOURCES}
20
+ # JNI adapter
21
+ src/main/cpp/cpp-adapter.cpp
22
+ src/main/cpp/AndroidStorageAdapterCpp.cpp
23
+ )
24
+
25
+ # Include directories
26
+ target_include_directories(${PROJECT_NAME} PRIVATE
27
+ "${CPP_ROOT}/core"
28
+ "${CPP_ROOT}/bindings"
29
+ "src/main/cpp"
30
+ )
31
+
32
+ # Include Nitro autolinking (adds nitrogen sources, definitions, and links)
33
+ include(${CMAKE_CURRENT_SOURCE_DIR}/../nitrogen/generated/android/NitroStorage+autolinking.cmake)
@@ -0,0 +1,96 @@
1
+ buildscript {
2
+ repositories {
3
+ google()
4
+ mavenCentral()
5
+ }
6
+
7
+ dependencies {
8
+ classpath "com.android.tools.build:gradle:8.10.1"
9
+ }
10
+ }
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
+
17
+ def isNewArchitectureEnabled() {
18
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
19
+ }
20
+
21
+ apply plugin: "com.android.library"
22
+ apply plugin: "org.jetbrains.kotlin.android"
23
+ // Apply autolinking script for Nitro
24
+ apply from: "../nitrogen/generated/android/NitroStorage+autolinking.gradle"
25
+
26
+ if (isNewArchitectureEnabled()) {
27
+ apply plugin: "com.facebook.react"
28
+ }
29
+
30
+ def getExtOrDefault(name) {
31
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["NitroStorage_" + name]
32
+ }
33
+
34
+ def getExtOrIntegerDefault(name) {
35
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["NitroStorage_" + name]).toInteger()
36
+ }
37
+
38
+ android {
39
+ namespace "com.nitrostorage"
40
+
41
+ // Use values from root project or defaults
42
+ ndkVersion getExtOrDefault("ndkVersion")
43
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
44
+
45
+ defaultConfig {
46
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
47
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
48
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
49
+
50
+ externalNativeBuild {
51
+ cmake {
52
+ cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all"
53
+ arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
54
+ abiFilters (*reactNativeArchitectures())
55
+ }
56
+ }
57
+ }
58
+
59
+ externalNativeBuild {
60
+ cmake {
61
+ path "CMakeLists.txt"
62
+ }
63
+ }
64
+
65
+ buildFeatures {
66
+ buildConfig true
67
+ prefab true
68
+ }
69
+
70
+ compileOptions {
71
+ sourceCompatibility JavaVersion.VERSION_1_8
72
+ targetCompatibility JavaVersion.VERSION_1_8
73
+ }
74
+
75
+ sourceSets {
76
+ main {
77
+ java.srcDirs += ["src/main/java"]
78
+ if (isNewArchitectureEnabled()) {
79
+ java.srcDirs += ["${project.buildDir}/generated/source/codegen/java"]
80
+ }
81
+ }
82
+ }
83
+ }
84
+
85
+ repositories {
86
+ mavenCentral()
87
+ google()
88
+ }
89
+
90
+ dependencies {
91
+ //noinspection GradleDynamicVersion
92
+ implementation "com.facebook.react:react-native:+"
93
+ implementation "androidx.security:security-crypto:1.1.0-alpha06"
94
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.0"
95
+ implementation project(":react-native-nitro-modules")
96
+ }
@@ -0,0 +1,4 @@
1
+ NitroStorage_ndkVersion=27.1.12297006
2
+ NitroStorage_compileSdkVersion=36
3
+ NitroStorage_targetSdkVersion=36
4
+ NitroStorage_minSdkVersion=24
@@ -0,0 +1,49 @@
1
+ #include "AndroidStorageAdapterCpp.hpp"
2
+
3
+ namespace NitroStorage {
4
+
5
+ using namespace facebook::jni;
6
+
7
+ AndroidStorageAdapterCpp::AndroidStorageAdapterCpp(alias_ref<JObject> context) {
8
+ if (!context) [[unlikely]] {
9
+ throw std::runtime_error("NitroStorage: Android Context is null");
10
+ }
11
+ }
12
+
13
+ AndroidStorageAdapterCpp::~AndroidStorageAdapterCpp() = default;
14
+
15
+ void AndroidStorageAdapterCpp::setDisk(const std::string& key, const std::string& value) {
16
+ static auto method = AndroidStorageAdapterJava::javaClassStatic()->getStaticMethod<void(std::string, std::string)>("setDisk");
17
+ method(AndroidStorageAdapterJava::javaClassStatic(), key, value);
18
+ }
19
+
20
+ std::optional<std::string> AndroidStorageAdapterCpp::getDisk(const std::string& key) {
21
+ static auto method = AndroidStorageAdapterJava::javaClassStatic()->getStaticMethod<jstring(std::string)>("getDisk");
22
+ auto result = method(AndroidStorageAdapterJava::javaClassStatic(), key);
23
+ if (!result) return std::nullopt;
24
+ return result->toStdString();
25
+ }
26
+
27
+ void AndroidStorageAdapterCpp::deleteDisk(const std::string& key) {
28
+ static auto method = AndroidStorageAdapterJava::javaClassStatic()->getStaticMethod<void(std::string)>("deleteDisk");
29
+ method(AndroidStorageAdapterJava::javaClassStatic(), key);
30
+ }
31
+
32
+ void AndroidStorageAdapterCpp::setSecure(const std::string& key, const std::string& value) {
33
+ static auto method = AndroidStorageAdapterJava::javaClassStatic()->getStaticMethod<void(std::string, std::string)>("setSecure");
34
+ method(AndroidStorageAdapterJava::javaClassStatic(), key, value);
35
+ }
36
+
37
+ std::optional<std::string> AndroidStorageAdapterCpp::getSecure(const std::string& key) {
38
+ static auto method = AndroidStorageAdapterJava::javaClassStatic()->getStaticMethod<jstring(std::string)>("getSecure");
39
+ auto result = method(AndroidStorageAdapterJava::javaClassStatic(), key);
40
+ if (!result) return std::nullopt;
41
+ return result->toStdString();
42
+ }
43
+
44
+ void AndroidStorageAdapterCpp::deleteSecure(const std::string& key) {
45
+ static auto method = AndroidStorageAdapterJava::javaClassStatic()->getStaticMethod<void(std::string)>("deleteSecure");
46
+ method(AndroidStorageAdapterJava::javaClassStatic(), key);
47
+ }
48
+
49
+ } // namespace NitroStorage