react-native-mmkv 4.0.0-beta.0 → 4.0.0-beta.10

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 (234) hide show
  1. package/NitroMmkv.podspec +44 -0
  2. package/README.md +1 -3
  3. package/android/CMakeLists.txt +31 -30
  4. package/android/build.gradle +65 -20
  5. package/android/fix-prefab.gradle +51 -0
  6. package/android/gradle.properties +5 -5
  7. package/android/src/main/cpp/cpp-adapter.cpp +6 -0
  8. package/android/src/main/java/com/margelo/nitro/mmkv/HybridMMKVPlatformContext.kt +19 -0
  9. package/android/src/main/java/com/margelo/nitro/mmkv/NitroMmkvPackage.java +33 -0
  10. package/app.plugin.js +1 -0
  11. package/cpp/HybridMMKV.cpp +184 -0
  12. package/cpp/HybridMMKV.hpp +47 -0
  13. package/cpp/HybridMMKVFactory.cpp +33 -0
  14. package/cpp/HybridMMKVFactory.hpp +24 -0
  15. package/cpp/{MmkvTypes.h → MMKVTypes.hpp} +1 -1
  16. package/cpp/MMKVValueChangedListenerRegistry.cpp +58 -0
  17. package/cpp/MMKVValueChangedListenerRegistry.hpp +43 -0
  18. package/cpp/{ManagedMMBuffer.h → ManagedMMBuffer.hpp} +13 -5
  19. package/ios/HybridMMKVPlatformContext.swift +43 -0
  20. package/lib/__tests__/hooks.test.d.ts +1 -0
  21. package/lib/__tests__/hooks.test.js +69 -0
  22. package/lib/addMemoryWarningListener/addMemoryWarningListener.d.ts +2 -0
  23. package/lib/addMemoryWarningListener/addMemoryWarningListener.js +25 -0
  24. package/lib/addMemoryWarningListener/addMemoryWarningListener.mock.d.ts +2 -0
  25. package/lib/addMemoryWarningListener/addMemoryWarningListener.mock.js +3 -0
  26. package/lib/addMemoryWarningListener/addMemoryWarningListener.web.d.ts +2 -0
  27. package/lib/addMemoryWarningListener/addMemoryWarningListener.web.js +3 -0
  28. package/lib/createMMKV/createMMKV.d.ts +3 -0
  29. package/lib/createMMKV/createMMKV.js +40 -0
  30. package/lib/createMMKV/createMMKV.mock.d.ts +5 -0
  31. package/lib/createMMKV/createMMKV.mock.js +74 -0
  32. package/lib/createMMKV/createMMKV.web.d.ts +3 -0
  33. package/lib/createMMKV/createMMKV.web.js +117 -0
  34. package/lib/createMMKV/createMockMMKV.d.ts +5 -0
  35. package/lib/createMMKV/createMockMMKV.js +74 -0
  36. package/lib/createMMKV/getDefaultMMKVInstance.d.ts +2 -0
  37. package/lib/createMMKV/getDefaultMMKVInstance.js +8 -0
  38. package/lib/expo-plugin/withMMKV.cjs +26 -0
  39. package/lib/expo-plugin/withMMKV.d.cts +3 -0
  40. package/lib/expo-plugin/withMMKV.d.ts +3 -0
  41. package/lib/expo-plugin/withMMKV.js +17 -0
  42. package/lib/hooks/createMMKVHook.d.ts +2 -0
  43. package/lib/hooks/createMMKVHook.js +49 -0
  44. package/lib/hooks/useMMKV.d.ts +11 -0
  45. package/lib/hooks/useMMKV.js +23 -0
  46. package/lib/hooks/useMMKVBoolean.d.ts +11 -0
  47. package/lib/hooks/useMMKVBoolean.js +12 -0
  48. package/lib/hooks/useMMKVBuffer.d.ts +11 -0
  49. package/lib/hooks/useMMKVBuffer.js +12 -0
  50. package/lib/hooks/useMMKVKeys.d.ts +12 -0
  51. package/lib/hooks/useMMKVKeys.js +33 -0
  52. package/lib/hooks/useMMKVListener.d.ts +15 -0
  53. package/lib/hooks/useMMKVListener.js +26 -0
  54. package/lib/hooks/useMMKVNumber.d.ts +11 -0
  55. package/lib/hooks/useMMKVNumber.js +12 -0
  56. package/lib/hooks/useMMKVObject.d.ts +17 -0
  57. package/lib/hooks/useMMKVObject.js +38 -0
  58. package/lib/hooks/useMMKVString.d.ts +11 -0
  59. package/lib/hooks/useMMKVString.js +12 -0
  60. package/lib/index.d.ts +11 -0
  61. package/lib/index.js +11 -0
  62. package/lib/isTest.d.ts +1 -0
  63. package/lib/isTest.js +7 -0
  64. package/lib/specs/MMKV.nitro.d.ts +94 -0
  65. package/lib/specs/MMKV.nitro.js +1 -0
  66. package/lib/{typescript/src/NativeMmkv.d.ts → specs/MMKVFactory.nitro.d.ts} +26 -33
  67. package/lib/specs/MMKVFactory.nitro.js +1 -0
  68. package/lib/specs/MMKVPlatformContext.nitro.d.ts +18 -0
  69. package/lib/specs/MMKVPlatformContext.nitro.js +1 -0
  70. package/lib/{typescript/src → web}/createTextEncoder.d.ts +0 -1
  71. package/lib/web/createTextEncoder.js +17 -0
  72. package/nitro.json +28 -0
  73. package/nitrogen/generated/.gitattributes +1 -0
  74. package/nitrogen/generated/android/NitroMmkv+autolinking.cmake +80 -0
  75. package/nitrogen/generated/android/NitroMmkv+autolinking.gradle +27 -0
  76. package/nitrogen/generated/android/NitroMmkvOnLoad.cpp +54 -0
  77. package/nitrogen/generated/android/NitroMmkvOnLoad.hpp +25 -0
  78. package/nitrogen/generated/android/c++/JHybridMMKVPlatformContextSpec.cpp +52 -0
  79. package/nitrogen/generated/android/c++/JHybridMMKVPlatformContextSpec.hpp +65 -0
  80. package/nitrogen/generated/android/kotlin/com/margelo/nitro/mmkv/HybridMMKVPlatformContextSpec.kt +56 -0
  81. package/nitrogen/generated/android/kotlin/com/margelo/nitro/mmkv/NitroMmkvOnLoad.kt +35 -0
  82. package/nitrogen/generated/ios/NitroMmkv+autolinking.rb +60 -0
  83. package/nitrogen/generated/ios/NitroMmkv-Swift-Cxx-Bridge.cpp +32 -0
  84. package/nitrogen/generated/ios/NitroMmkv-Swift-Cxx-Bridge.hpp +77 -0
  85. package/nitrogen/generated/ios/NitroMmkv-Swift-Cxx-Umbrella.hpp +45 -0
  86. package/nitrogen/generated/ios/NitroMmkvAutolinking.mm +43 -0
  87. package/nitrogen/generated/ios/NitroMmkvAutolinking.swift +25 -0
  88. package/nitrogen/generated/ios/c++/HybridMMKVPlatformContextSpecSwift.cpp +11 -0
  89. package/nitrogen/generated/ios/c++/HybridMMKVPlatformContextSpecSwift.hpp +82 -0
  90. package/nitrogen/generated/ios/swift/HybridMMKVPlatformContextSpec.swift +50 -0
  91. package/nitrogen/generated/ios/swift/HybridMMKVPlatformContextSpec_cxx.swift +141 -0
  92. package/nitrogen/generated/shared/c++/Configuration.hpp +86 -0
  93. package/nitrogen/generated/shared/c++/HybridMMKVFactorySpec.cpp +23 -0
  94. package/nitrogen/generated/shared/c++/HybridMMKVFactorySpec.hpp +69 -0
  95. package/nitrogen/generated/shared/c++/HybridMMKVPlatformContextSpec.cpp +22 -0
  96. package/nitrogen/generated/shared/c++/HybridMMKVPlatformContextSpec.hpp +64 -0
  97. package/nitrogen/generated/shared/c++/HybridMMKVSpec.cpp +34 -0
  98. package/nitrogen/generated/shared/c++/HybridMMKVSpec.hpp +83 -0
  99. package/nitrogen/generated/shared/c++/Listener.hpp +67 -0
  100. package/nitrogen/generated/shared/c++/Mode.hpp +76 -0
  101. package/package.json +78 -125
  102. package/react-native.config.js +2 -15
  103. package/src/__tests__/hooks.test.tsx +39 -34
  104. package/src/addMemoryWarningListener/addMemoryWarningListener.mock.ts +5 -0
  105. package/src/{MemoryWarningListener.ts → addMemoryWarningListener/addMemoryWarningListener.ts} +12 -12
  106. package/src/addMemoryWarningListener/addMemoryWarningListener.web.ts +5 -0
  107. package/src/createMMKV/createMMKV.ts +51 -0
  108. package/src/{createMMKV.web.ts → createMMKV/createMMKV.web.ts} +58 -46
  109. package/src/createMMKV/createMockMMKV.ts +78 -0
  110. package/src/createMMKV/getDefaultMMKVInstance.ts +10 -0
  111. package/src/expo-plugin/withMMKV.cts +31 -0
  112. package/src/hooks/createMMKVHook.ts +66 -0
  113. package/src/hooks/useMMKV.ts +45 -0
  114. package/src/hooks/useMMKVBoolean.ts +15 -0
  115. package/src/hooks/useMMKVBuffer.ts +15 -0
  116. package/src/hooks/useMMKVKeys.ts +36 -0
  117. package/src/hooks/useMMKVListener.ts +33 -0
  118. package/src/hooks/useMMKVNumber.ts +15 -0
  119. package/src/hooks/useMMKVObject.ts +53 -0
  120. package/src/hooks/useMMKVString.ts +15 -0
  121. package/src/index.ts +15 -3
  122. package/src/{PlatformChecker.ts → isTest.ts} +2 -2
  123. package/src/specs/MMKV.nitro.ts +93 -0
  124. package/src/specs/MMKVFactory.nitro.ts +87 -0
  125. package/src/specs/MMKVPlatformContext.nitro.ts +17 -0
  126. package/src/{createTextEncoder.ts → web/createTextEncoder.ts} +7 -7
  127. package/android/src/main/cpp/AndroidLogger.cpp +0 -16
  128. package/android/src/main/java/com/mrousavy/mmkv/MmkvPackage.java +0 -44
  129. package/android/src/main/java/com/mrousavy/mmkv/MmkvPlatformContextModule.java +0 -26
  130. package/cpp/MmkvHostObject.cpp +0 -360
  131. package/cpp/MmkvHostObject.h +0 -31
  132. package/cpp/MmkvLogger.h +0 -35
  133. package/cpp/NativeMmkvModule.cpp +0 -43
  134. package/cpp/NativeMmkvModule.h +0 -31
  135. package/ios/AppleLogger.mm +0 -16
  136. package/ios/MmkvOnLoad.mm +0 -25
  137. package/ios/MmkvPlatformContext.h +0 -19
  138. package/ios/MmkvPlatformContextModule.mm +0 -55
  139. package/lib/commonjs/MMKV.js +0 -124
  140. package/lib/commonjs/MMKV.js.map +0 -1
  141. package/lib/commonjs/MemoryWarningListener.js +0 -31
  142. package/lib/commonjs/MemoryWarningListener.js.map +0 -1
  143. package/lib/commonjs/MemoryWarningListener.web.js +0 -11
  144. package/lib/commonjs/MemoryWarningListener.web.js.map +0 -1
  145. package/lib/commonjs/ModuleNotFoundError.js +0 -75
  146. package/lib/commonjs/ModuleNotFoundError.js.map +0 -1
  147. package/lib/commonjs/NativeMmkv.js +0 -47
  148. package/lib/commonjs/NativeMmkv.js.map +0 -1
  149. package/lib/commonjs/NativeMmkvPlatformContext.js +0 -22
  150. package/lib/commonjs/NativeMmkvPlatformContext.js.map +0 -1
  151. package/lib/commonjs/PlatformChecker.js +0 -14
  152. package/lib/commonjs/PlatformChecker.js.map +0 -1
  153. package/lib/commonjs/Types.js +0 -26
  154. package/lib/commonjs/Types.js.map +0 -1
  155. package/lib/commonjs/createMMKV.js +0 -43
  156. package/lib/commonjs/createMMKV.js.map +0 -1
  157. package/lib/commonjs/createMMKV.mock.js +0 -43
  158. package/lib/commonjs/createMMKV.mock.js.map +0 -1
  159. package/lib/commonjs/createMMKV.web.js +0 -110
  160. package/lib/commonjs/createMMKV.web.js.map +0 -1
  161. package/lib/commonjs/createTextEncoder.js +0 -23
  162. package/lib/commonjs/createTextEncoder.js.map +0 -1
  163. package/lib/commonjs/hooks.js +0 -198
  164. package/lib/commonjs/hooks.js.map +0 -1
  165. package/lib/commonjs/index.js +0 -40
  166. package/lib/commonjs/index.js.map +0 -1
  167. package/lib/commonjs/package.json +0 -1
  168. package/lib/module/MMKV.js +0 -119
  169. package/lib/module/MMKV.js.map +0 -1
  170. package/lib/module/MemoryWarningListener.js +0 -27
  171. package/lib/module/MemoryWarningListener.js.map +0 -1
  172. package/lib/module/MemoryWarningListener.web.js +0 -6
  173. package/lib/module/MemoryWarningListener.web.js.map +0 -1
  174. package/lib/module/ModuleNotFoundError.js +0 -70
  175. package/lib/module/ModuleNotFoundError.js.map +0 -1
  176. package/lib/module/NativeMmkv.js +0 -45
  177. package/lib/module/NativeMmkv.js.map +0 -1
  178. package/lib/module/NativeMmkvPlatformContext.js +0 -18
  179. package/lib/module/NativeMmkvPlatformContext.js.map +0 -1
  180. package/lib/module/PlatformChecker.js +0 -10
  181. package/lib/module/PlatformChecker.js.map +0 -1
  182. package/lib/module/Types.js +0 -25
  183. package/lib/module/Types.js.map +0 -1
  184. package/lib/module/createMMKV.js +0 -38
  185. package/lib/module/createMMKV.js.map +0 -1
  186. package/lib/module/createMMKV.mock.js +0 -38
  187. package/lib/module/createMMKV.mock.js.map +0 -1
  188. package/lib/module/createMMKV.web.js +0 -105
  189. package/lib/module/createMMKV.web.js.map +0 -1
  190. package/lib/module/createTextEncoder.js +0 -19
  191. package/lib/module/createTextEncoder.js.map +0 -1
  192. package/lib/module/hooks.js +0 -189
  193. package/lib/module/hooks.js.map +0 -1
  194. package/lib/module/index.js +0 -6
  195. package/lib/module/index.js.map +0 -1
  196. package/lib/module/package.json +0 -1
  197. package/lib/typescript/src/MMKV.d.ts +0 -34
  198. package/lib/typescript/src/MMKV.d.ts.map +0 -1
  199. package/lib/typescript/src/MemoryWarningListener.d.ts +0 -3
  200. package/lib/typescript/src/MemoryWarningListener.d.ts.map +0 -1
  201. package/lib/typescript/src/MemoryWarningListener.web.d.ts +0 -3
  202. package/lib/typescript/src/MemoryWarningListener.web.d.ts.map +0 -1
  203. package/lib/typescript/src/ModuleNotFoundError.d.ts +0 -7
  204. package/lib/typescript/src/ModuleNotFoundError.d.ts.map +0 -1
  205. package/lib/typescript/src/NativeMmkv.d.ts.map +0 -1
  206. package/lib/typescript/src/NativeMmkvPlatformContext.d.ts +0 -20
  207. package/lib/typescript/src/NativeMmkvPlatformContext.d.ts.map +0 -1
  208. package/lib/typescript/src/PlatformChecker.d.ts +0 -2
  209. package/lib/typescript/src/PlatformChecker.d.ts.map +0 -1
  210. package/lib/typescript/src/Types.d.ts +0 -172
  211. package/lib/typescript/src/Types.d.ts.map +0 -1
  212. package/lib/typescript/src/__tests__/hooks.test.d.ts +0 -2
  213. package/lib/typescript/src/__tests__/hooks.test.d.ts.map +0 -1
  214. package/lib/typescript/src/createMMKV.d.ts +0 -3
  215. package/lib/typescript/src/createMMKV.d.ts.map +0 -1
  216. package/lib/typescript/src/createMMKV.mock.d.ts +0 -3
  217. package/lib/typescript/src/createMMKV.mock.d.ts.map +0 -1
  218. package/lib/typescript/src/createMMKV.web.d.ts +0 -3
  219. package/lib/typescript/src/createMMKV.web.d.ts.map +0 -1
  220. package/lib/typescript/src/createTextEncoder.d.ts.map +0 -1
  221. package/lib/typescript/src/hooks.d.ts +0 -86
  222. package/lib/typescript/src/hooks.d.ts.map +0 -1
  223. package/lib/typescript/src/index.d.ts +0 -4
  224. package/lib/typescript/src/index.d.ts.map +0 -1
  225. package/react-native-mmkv.podspec +0 -32
  226. package/src/MMKV.ts +0 -142
  227. package/src/MemoryWarningListener.web.ts +0 -5
  228. package/src/ModuleNotFoundError.ts +0 -95
  229. package/src/NativeMmkv.ts +0 -118
  230. package/src/NativeMmkvPlatformContext.ts +0 -38
  231. package/src/Types.ts +0 -178
  232. package/src/createMMKV.mock.ts +0 -38
  233. package/src/createMMKV.ts +0 -42
  234. package/src/hooks.ts +0 -247
@@ -0,0 +1,44 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "NitroMmkv"
7
+ s.version = package["version"]
8
+ s.summary = package["description"]
9
+ s.homepage = package["homepage"]
10
+ s.license = package["license"]
11
+ s.authors = package["author"]
12
+
13
+ s.platforms = { :ios => min_ios_version_supported, :visionos => 1.0, :tvos => "12.0", :osx => "10.14" }
14
+ s.source = { :git => "https://github.com/mrousavy/react-native-mmkv.git", :tag => "#{s.version}" }
15
+
16
+ s.source_files = [
17
+ # Implementation (Swift)
18
+ "ios/**/*.{swift}",
19
+ # Autolinking/Registration (Objective-C++)
20
+ "ios/**/*.{m,mm}",
21
+ # Implementation (C++ objects)
22
+ "cpp/**/*.{hpp,cpp}",
23
+ ]
24
+
25
+ # Add MMKV Core dependency
26
+ s.compiler_flags = '-x objective-c++'
27
+ s.libraries = 'z', 'c++'
28
+ s.dependency 'MMKVCore', '>= 2.2.3'
29
+
30
+ # TODO: Remove when no one uses RN 0.79 anymore
31
+ # Add support for React Native 0.79 or below
32
+ s.pod_target_xcconfig = {
33
+ "HEADER_SEARCH_PATHS" => ["${PODS_ROOT}/RCT-Folly"],
34
+ "GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) FOLLY_NO_CONFIG FOLLY_CFG_NO_COROUTINES",
35
+ "OTHER_CPLUSPLUSFLAGS" => "$(inherited) -DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"
36
+ }
37
+
38
+ load 'nitrogen/generated/ios/NitroMmkv+autolinking.rb'
39
+ add_nitrogen_files(s)
40
+
41
+ s.dependency 'React-jsi'
42
+ s.dependency 'React-callinvoker'
43
+ install_modules_dependencies(s)
44
+ end
package/README.md CHANGED
@@ -1,5 +1,3 @@
1
1
  # react-native-mmkv
2
2
 
3
- The fastest key/value storage for React Native. ~30x faster than AsyncStorage!
4
-
5
- See [README.md](https://github.com/mrousavy/react-native-mmkv) for more information.
3
+ See https://github.com/mrousavy/react-native-mmkv
@@ -1,41 +1,42 @@
1
+ project(NitroMmkv)
1
2
  cmake_minimum_required(VERSION 3.9.0)
2
- project(ReactNativeMmkv)
3
-
4
- set(CMAKE_VERBOSE_MAKEFILE ON)
5
- set(CMAKE_CXX_STANDARD 20)
6
-
7
- # Check for supported ABIs only
8
- if(NOT (ANDROID_ABI STREQUAL "arm64-v8a" OR ANDROID_ABI STREQUAL "x86_64"))
9
- message(FATAL_ERROR "MMKV prefab does not support ABI: ${ANDROID_ABI}. Supported ABIs: arm64-v8a, x86_64")
10
- endif()
11
-
12
- # Compile sources
13
- add_library(
14
- react-native-mmkv
15
- SHARED
16
- src/main/cpp/AndroidLogger.cpp
17
- ../cpp/MmkvHostObject.cpp
18
- ../cpp/NativeMmkvModule.cpp
3
+
4
+ set (PACKAGE_NAME NitroMmkv)
5
+ set (CMAKE_VERBOSE_MAKEFILE ON)
6
+ set (CMAKE_CXX_STANDARD 20)
7
+
8
+ # Find all C++ files (shared and platform specifics)
9
+ file(GLOB_RECURSE shared_files RELATIVE ${CMAKE_SOURCE_DIR}
10
+ "../cpp/**.cpp"
11
+ )
12
+ file(GLOB_RECURSE android_files RELATIVE ${CMAKE_SOURCE_DIR}
13
+ "src/main/cpp/**.cpp"
19
14
  )
20
15
 
21
- include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../cpp)
16
+ # Define C++ library and add all sources
17
+ add_library(${PACKAGE_NAME} SHARED
18
+ ${shared_files}
19
+ ${android_files}
20
+ )
22
21
 
23
- # Find MMKV prefab package
22
+ # Find MMKV prefab package (from mmkv-shared gradle dependency)
24
23
  find_package(mmkv REQUIRED CONFIG)
25
24
 
26
- # Add android/log dependency
27
- find_library(android_log log)
25
+ # Add Nitrogen specs :)
26
+ include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/NitroMmkv+autolinking.cmake)
28
27
 
29
- target_include_directories(
30
- react-native-mmkv
31
- PUBLIC
32
- ${CMAKE_CURRENT_SOURCE_DIR}/../cpp
28
+ # Set up local includes
29
+ include_directories(
30
+ "src/main/cpp"
31
+ "../cpp"
33
32
  )
34
33
 
34
+ find_library(LOG_LIB log)
35
+
36
+ # Link all libraries together
35
37
  target_link_libraries(
36
- react-native-mmkv
37
- mmkv::mmkv # <-- MMKV core (now manually configured)
38
- ${android_log} # <-- Logcat logger
39
- android # <-- Android JNI core
40
- react_codegen_RNMmkvSpec # <-- Generated Specs from CodeGen
38
+ ${PACKAGE_NAME}
39
+ ${LOG_LIB}
40
+ mmkv::mmkv # <-- MMKV core
41
+ android # <-- Android core
41
42
  )
@@ -5,33 +5,38 @@ buildscript {
5
5
  }
6
6
 
7
7
  dependencies {
8
- classpath "com.android.tools.build:gradle:7.2.2"
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(",") : ["x86_64", "arm64-v8a"]
15
+ }
16
+
12
17
  def isNewArchitectureEnabled() {
13
18
  return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
14
19
  }
15
20
 
16
21
  apply plugin: "com.android.library"
22
+ apply plugin: 'org.jetbrains.kotlin.android'
23
+ apply from: '../nitrogen/generated/android/NitroMmkv+autolinking.gradle'
24
+ apply from: "./fix-prefab.gradle"
17
25
 
18
26
  if (isNewArchitectureEnabled()) {
19
27
  apply plugin: "com.facebook.react"
20
28
  }
21
29
 
22
30
  def getExtOrDefault(name) {
23
- return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["Mmkv_" + name]
31
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["NitroMmkv_" + name]
24
32
  }
25
33
 
26
34
  def getExtOrIntegerDefault(name) {
27
- return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["Mmkv_" + name]).toInteger()
35
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["NitroMmkv_" + name]).toInteger()
28
36
  }
29
37
 
30
- logger.warn("[react-native-mmkv] Thank you for using react-native-mmkv ❤️")
31
- logger.warn("[react-native-mmkv] If you enjoy using react-native-mmkv, please consider sponsoring this project: https://github.com/sponsors/mrousavy")
32
-
33
38
  android {
34
- namespace "com.mrousavy.mmkv"
39
+ namespace "com.margelo.nitro.mmkv"
35
40
 
36
41
  ndkVersion getExtOrDefault("ndkVersion")
37
42
  compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
@@ -40,6 +45,50 @@ android {
40
45
  minSdkVersion getExtOrIntegerDefault("minSdkVersion")
41
46
  targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
42
47
  buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
48
+
49
+ externalNativeBuild {
50
+ cmake {
51
+ cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all"
52
+ arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
53
+ abiFilters (*reactNativeArchitectures())
54
+
55
+ buildTypes {
56
+ debug {
57
+ cppFlags "-O1 -g"
58
+ }
59
+ release {
60
+ cppFlags "-O2"
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
66
+
67
+ externalNativeBuild {
68
+ cmake {
69
+ path "CMakeLists.txt"
70
+ }
71
+ }
72
+
73
+ packagingOptions {
74
+ excludes = [
75
+ "META-INF",
76
+ "META-INF/**",
77
+ "**/libc++_shared.so",
78
+ "**/libfbjni.so",
79
+ "**/libjsi.so",
80
+ "**/libfolly_json.so",
81
+ "**/libfolly_runtime.so",
82
+ "**/libglog.so",
83
+ "**/libhermes.so",
84
+ "**/libhermes-executor-debug.so",
85
+ "**/libhermes_executor.so",
86
+ "**/libreactnative.so",
87
+ "**/libreactnativejni.so",
88
+ "**/libturbomodulejsijni.so",
89
+ "**/libreact_nativemodule_core.so",
90
+ "**/libjscexecutor.so"
91
+ ]
43
92
  }
44
93
 
45
94
  buildFeatures {
@@ -65,18 +114,18 @@ android {
65
114
  sourceSets {
66
115
  main {
67
116
  if (isNewArchitectureEnabled()) {
68
- java.srcDirs += [
69
- // This is needed to build Kotlin project with NewArch enabled
70
- "${project.buildDir}/generated/source/codegen/java"
71
- ]
117
+ java.srcDirs += [
118
+ // React Codegen files
119
+ "${project.buildDir}/generated/source/codegen/java"
120
+ ]
72
121
  }
73
122
  }
74
123
  }
75
124
  }
76
125
 
77
126
  repositories {
78
- google()
79
127
  mavenCentral()
128
+ google()
80
129
  }
81
130
 
82
131
 
@@ -86,14 +135,10 @@ dependencies {
86
135
  //noinspection GradleDynamicVersion
87
136
  implementation "com.facebook.react:react-native:+"
88
137
 
89
- // Use the MMKV shared lib - includes C++ prefabs (shared STL for React Native compatibility)
138
+ // Add a dependency on NitroModules
139
+ implementation project(":react-native-nitro-modules")
140
+
141
+ // Add a dependency on mmkv core (this ships a C++ prefab)
90
142
  implementation "com.tencent:mmkv-shared:2.2.3"
91
143
  }
92
144
 
93
- if (isNewArchitectureEnabled()) {
94
- react {
95
- jsRootDir = file("../src/")
96
- libraryName = "Mmkv"
97
- codegenJavaPackageName = "com.mrousavy.mmkv"
98
- }
99
- }
@@ -0,0 +1,51 @@
1
+ tasks.configureEach { task ->
2
+ // Make sure that we generate our prefab publication file only after having built the native library
3
+ // so that not a header publication file, but a full configuration publication will be generated, which
4
+ // will include the .so file
5
+
6
+ def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/
7
+ def matcher = task.name =~ prefabConfigurePattern
8
+ if (matcher.matches()) {
9
+ def variantName = matcher[0][1]
10
+ task.outputs.upToDateWhen { false }
11
+ task.dependsOn("externalNativeBuild${variantName}")
12
+ }
13
+ }
14
+
15
+ afterEvaluate {
16
+ def abis = reactNativeArchitectures()
17
+ rootProject.allprojects.each { proj ->
18
+ if (proj === rootProject) return
19
+
20
+ def dependsOnThisLib = proj.configurations.findAll { it.canBeResolved }.any { config ->
21
+ config.dependencies.any { dep ->
22
+ dep.group == project.group && dep.name == project.name
23
+ }
24
+ }
25
+ if (!dependsOnThisLib && proj != project) return
26
+
27
+ if (!proj.plugins.hasPlugin('com.android.application') && !proj.plugins.hasPlugin('com.android.library')) {
28
+ return
29
+ }
30
+
31
+ def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants
32
+ // Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to
33
+ // generate a libnameConfig.cmake file that will contain our native library (.so).
34
+ // See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue
35
+ variants.all { variant ->
36
+ def variantName = variant.name
37
+ abis.each { abi ->
38
+ def searchDir = new File(proj.projectDir, ".cxx/${variantName}")
39
+ if (!searchDir.exists()) return
40
+ def matches = []
41
+ searchDir.eachDir { randomDir ->
42
+ def prefabFile = new File(randomDir, "${abi}/prefab_config.json")
43
+ if (prefabFile.exists()) matches << prefabFile
44
+ }
45
+ matches.each { prefabConfig ->
46
+ prefabConfig.setLastModified(System.currentTimeMillis())
47
+ }
48
+ }
49
+ }
50
+ }
51
+ }
@@ -1,5 +1,5 @@
1
- Mmkv_kotlinVersion=1.9.24
2
- Mmkv_minSdkVersion=23
3
- Mmkv_targetSdkVersion=34
4
- Mmkv_compileSdkVersion=34
5
- Mmkv_ndkversion=26.1.10909125
1
+ NitroMmkv_kotlinVersion=2.1.20
2
+ NitroMmkv_minSdkVersion=23
3
+ NitroMmkv_targetSdkVersion=36
4
+ NitroMmkv_compileSdkVersion=36
5
+ NitroMmkv_ndkVersion=27.1.12297006
@@ -0,0 +1,6 @@
1
+ #include "NitroMmkvOnLoad.hpp"
2
+ #include <jni.h>
3
+
4
+ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
5
+ return margelo::nitro::mmkv::initialize(vm);
6
+ }
@@ -0,0 +1,19 @@
1
+ package com.margelo.nitro.mmkv
2
+
3
+ import androidx.annotation.Keep
4
+ import com.facebook.common.internal.DoNotStrip
5
+ import com.margelo.nitro.NitroModules
6
+
7
+ @DoNotStrip
8
+ @Keep
9
+ class HybridMMKVPlatformContext: HybridMMKVPlatformContextSpec() {
10
+ override fun getBaseDirectory(): String {
11
+ val context = NitroModules.applicationContext ?: throw Error("Cannot get MMKV base directory - No Android Context available!")
12
+ return context.filesDir.absolutePath + "/mmkv";
13
+ }
14
+
15
+ override fun getAppGroupDirectory(): String? {
16
+ // AppGroups do not exist on Android. It's iOS only.
17
+ throw Error("getAppGroupDirectory() is not supported on Android! It's iOS only.")
18
+ }
19
+ }
@@ -0,0 +1,33 @@
1
+ package com.margelo.nitro.mmkv;
2
+
3
+ import android.util.Log;
4
+
5
+ import androidx.annotation.Nullable;
6
+
7
+ import com.facebook.react.bridge.NativeModule;
8
+ import com.facebook.react.bridge.ReactApplicationContext;
9
+ import com.facebook.react.module.model.ReactModuleInfoProvider;
10
+ import com.facebook.react.TurboReactPackage;
11
+ import com.margelo.nitro.core.HybridObject;
12
+
13
+ import java.util.HashMap;
14
+ import java.util.function.Supplier;
15
+
16
+ public class NitroMmkvPackage extends TurboReactPackage {
17
+ @Nullable
18
+ @Override
19
+ public NativeModule getModule(String name, ReactApplicationContext reactContext) {
20
+ return null;
21
+ }
22
+
23
+ @Override
24
+ public ReactModuleInfoProvider getReactModuleInfoProvider() {
25
+ return () -> {
26
+ return new HashMap<>();
27
+ };
28
+ }
29
+
30
+ static {
31
+ NitroMmkvOnLoad.initializeNative();
32
+ }
33
+ }
package/app.plugin.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./lib/expo-plugin/withMMKV.cjs')
@@ -0,0 +1,184 @@
1
+ //
2
+ // HybridMMKV.cpp
3
+ // react-native-mmkv
4
+ //
5
+ // Created by Marc Rousavy on 21.08.2025.
6
+ //
7
+
8
+ #include "HybridMMKV.hpp"
9
+ #include "MMKVTypes.hpp"
10
+ #include "MMKVValueChangedListenerRegistry.hpp"
11
+ #include "ManagedMMBuffer.hpp"
12
+ #include <NitroModules/NitroLogger.hpp>
13
+
14
+ namespace margelo::nitro::mmkv {
15
+
16
+ HybridMMKV::HybridMMKV(const Configuration& config) : HybridObject(TAG) {
17
+ std::string path = config.path.has_value() ? config.path.value() : "";
18
+ std::string encryptionKey = config.encryptionKey.has_value() ? config.encryptionKey.value() : "";
19
+ bool hasEncryptionKey = encryptionKey.size() > 0;
20
+ Logger::log(LogLevel::Info, TAG, "Creating MMKV instance \"%s\"... (Path: %s, Encrypted: %s)", config.id.c_str(), path.c_str(),
21
+ hasEncryptionKey ? "true" : "false");
22
+
23
+ std::string* pathPtr = path.size() > 0 ? &path : nullptr;
24
+ std::string* encryptionKeyPtr = encryptionKey.size() > 0 ? &encryptionKey : nullptr;
25
+ MMKVMode mode = getMMKVMode(config);
26
+ if (config.readOnly.has_value() && config.readOnly.value()) {
27
+ Logger::log(LogLevel::Info, TAG, "Instance is read-only!");
28
+ mode = mode | ::mmkv::MMKV_READ_ONLY;
29
+ }
30
+
31
+ #ifdef __APPLE__
32
+ instance = MMKV::mmkvWithID(config.id, mode, encryptionKeyPtr, pathPtr);
33
+ #else
34
+ instance = MMKV::mmkvWithID(config.id, DEFAULT_MMAP_SIZE, mode, encryptionKeyPtr, pathPtr);
35
+ #endif
36
+
37
+ if (instance == nullptr) [[unlikely]] {
38
+ // Check if instanceId is invalid
39
+ if (config.id.empty()) [[unlikely]] {
40
+ throw std::runtime_error("Failed to create MMKV instance! `id` cannot be empty!");
41
+ }
42
+
43
+ // Check if encryptionKey is invalid
44
+ if (encryptionKey.size() > 16) [[unlikely]] {
45
+ throw std::runtime_error("Failed to create MMKV instance! `encryptionKey` cannot be longer "
46
+ "than 16 bytes!");
47
+ }
48
+
49
+ // Check if path is maybe invalid
50
+ if (path.empty()) [[unlikely]] {
51
+ throw std::runtime_error("Failed to create MMKV instance! `path` cannot be empty!");
52
+ }
53
+
54
+ throw std::runtime_error("Failed to create MMKV instance!");
55
+ }
56
+ }
57
+
58
+ double HybridMMKV::getSize() {
59
+ return instance->actualSize();
60
+ }
61
+ bool HybridMMKV::getIsReadOnly() {
62
+ return instance->isReadOnly();
63
+ }
64
+
65
+ // helper: overload pattern matching for lambdas
66
+ template <class... Ts>
67
+ struct overloaded : Ts... {
68
+ using Ts::operator()...;
69
+ };
70
+ template <class... Ts>
71
+ overloaded(Ts...) -> overloaded<Ts...>;
72
+
73
+ void HybridMMKV::set(const std::string& key, const std::variant<std::string, double, bool, std::shared_ptr<ArrayBuffer>>& value) {
74
+ // Pattern-match each potential value in std::variant
75
+ std::visit(overloaded{[&](const std::string& string) { instance->set(string, key); }, [&](double number) { instance->set(number, key); },
76
+ [&](bool b) { instance->set(b, key); },
77
+ [&](const std::shared_ptr<ArrayBuffer>& buf) {
78
+ MMBuffer buffer(buf->data(), buf->size(), MMBufferCopyFlag::MMBufferNoCopy);
79
+ instance->set(std::move(buffer), key);
80
+ }},
81
+ value);
82
+
83
+ // Notify on changed
84
+ MMKVValueChangedListenerRegistry::notifyOnValueChanged(instance->mmapID(), key);
85
+ }
86
+ std::optional<bool> HybridMMKV::getBoolean(const std::string& key) {
87
+ bool hasValue;
88
+ bool result = instance->getBool(key, /* defaultValue */ false, &hasValue);
89
+ if (hasValue) {
90
+ return result;
91
+ } else {
92
+ return std::nullopt;
93
+ }
94
+ }
95
+ std::optional<std::string> HybridMMKV::getString(const std::string& key) {
96
+ std::string result;
97
+ bool hasValue = instance->getString(key, result, /* inplaceModification */ true);
98
+ if (hasValue) {
99
+ return result;
100
+ } else {
101
+ return std::nullopt;
102
+ }
103
+ }
104
+ std::optional<double> HybridMMKV::getNumber(const std::string& key) {
105
+ bool hasValue;
106
+ double result = instance->getDouble(key, /* defaultValue */ 0.0, &hasValue);
107
+ if (hasValue) {
108
+ return result;
109
+ } else {
110
+ return std::nullopt;
111
+ }
112
+ }
113
+ std::optional<std::shared_ptr<ArrayBuffer>> HybridMMKV::getBuffer(const std::string& key) {
114
+ MMBuffer result;
115
+ #ifdef __APPLE__
116
+ // iOS: Convert std::string to NSString* for MMKVCore pod compatibility
117
+ bool hasValue = instance->getBytes(@(key.c_str()), result);
118
+ #else
119
+ // Android/other platforms: Use std::string directly (converts to
120
+ // std::string_view)
121
+ bool hasValue = instance->getBytes(key, result);
122
+ #endif
123
+ if (hasValue) {
124
+ return std::make_shared<ManagedMMBuffer>(std::move(result));
125
+ } else {
126
+ return std::nullopt;
127
+ }
128
+ }
129
+ bool HybridMMKV::contains(const std::string& key) {
130
+ return instance->containsKey(key);
131
+ }
132
+ bool HybridMMKV::remove(const std::string& key) {
133
+ return instance->removeValueForKey(key);
134
+ }
135
+ std::vector<std::string> HybridMMKV::getAllKeys() {
136
+ return instance->allKeys();
137
+ }
138
+ void HybridMMKV::clearAll() {
139
+ instance->clearAll();
140
+ }
141
+ void HybridMMKV::recrypt(const std::optional<std::string>& key) {
142
+ bool successful = false;
143
+ if (key.has_value()) {
144
+ // Encrypt with the given key
145
+ successful = instance->reKey(key.value());
146
+ } else {
147
+ // Remove the encryption key by setting it to a blank string
148
+ successful = instance->reKey(std::string());
149
+ }
150
+ if (!successful) {
151
+ throw std::runtime_error("Failed to recrypt MMKV instance!");
152
+ }
153
+ }
154
+ void HybridMMKV::trim() {
155
+ instance->trim();
156
+ instance->clearMemoryCache();
157
+ }
158
+
159
+ Listener HybridMMKV::addOnValueChangedListener(const std::function<void(const std::string& /* key */)>& onValueChanged) {
160
+ // Add listener
161
+ auto mmkvID = instance->mmapID();
162
+ auto listenerID = MMKVValueChangedListenerRegistry::addListener(instance->mmapID(), onValueChanged);
163
+
164
+ return Listener([=]() {
165
+ // remove()
166
+ MMKVValueChangedListenerRegistry::removeListener(mmkvID, listenerID);
167
+ });
168
+ }
169
+
170
+ MMKVMode HybridMMKV::getMMKVMode(const Configuration& config) {
171
+ if (!config.mode.has_value()) {
172
+ return ::mmkv::MMKV_SINGLE_PROCESS;
173
+ }
174
+ switch (config.mode.value()) {
175
+ case Mode::SINGLE_PROCESS:
176
+ return ::mmkv::MMKV_SINGLE_PROCESS;
177
+ case Mode::MULTI_PROCESS:
178
+ return ::mmkv::MMKV_MULTI_PROCESS;
179
+ default:
180
+ [[unlikely]] throw std::runtime_error("Invalid MMKV Mode value!");
181
+ }
182
+ }
183
+
184
+ } // namespace margelo::nitro::mmkv
@@ -0,0 +1,47 @@
1
+ //
2
+ // HybridMMKV.hpp
3
+ // react-native-mmkv
4
+ //
5
+ // Created by Marc Rousavy on 21.08.2025.
6
+ //
7
+
8
+ #pragma once
9
+
10
+ #include "Configuration.hpp"
11
+ #include "HybridMMKVSpec.hpp"
12
+ #include "MMKVTypes.hpp"
13
+
14
+ namespace margelo::nitro::mmkv {
15
+
16
+ class HybridMMKV final : public HybridMMKVSpec {
17
+ public:
18
+ explicit HybridMMKV(const Configuration& configuration);
19
+
20
+ public:
21
+ // Properties
22
+ double getSize() override;
23
+ bool getIsReadOnly() override;
24
+
25
+ public:
26
+ // Methods
27
+ void set(const std::string& key, const std::variant<std::string, double, bool, std::shared_ptr<ArrayBuffer>>& value) override;
28
+ std::optional<bool> getBoolean(const std::string& key) override;
29
+ std::optional<std::string> getString(const std::string& key) override;
30
+ std::optional<double> getNumber(const std::string& key) override;
31
+ std::optional<std::shared_ptr<ArrayBuffer>> getBuffer(const std::string& key) override;
32
+ bool contains(const std::string& key) override;
33
+ bool remove(const std::string& key) override;
34
+ std::vector<std::string> getAllKeys() override;
35
+ void clearAll() override;
36
+ void recrypt(const std::optional<std::string>& key) override;
37
+ void trim() override;
38
+ Listener addOnValueChangedListener(const std::function<void(const std::string& /* key */)>& onValueChanged) override;
39
+
40
+ private:
41
+ static MMKVMode getMMKVMode(const Configuration& config);
42
+
43
+ private:
44
+ MMKV* instance;
45
+ };
46
+
47
+ } // namespace margelo::nitro::mmkv
@@ -0,0 +1,33 @@
1
+ //
2
+ // HybridMMKVFactory.cpp
3
+ // react-native-mmkv
4
+ //
5
+ // Created by Marc Rousavy on 21.08.2025.
6
+ //
7
+
8
+ #include "HybridMMKVFactory.hpp"
9
+ #include "HybridMMKV.hpp"
10
+ #include "MMKVTypes.hpp"
11
+
12
+ namespace margelo::nitro::mmkv {
13
+
14
+ std::string HybridMMKVFactory::getDefaultMMKVInstanceId() {
15
+ return DEFAULT_MMAP_ID;
16
+ }
17
+
18
+ std::shared_ptr<HybridMMKVSpec> HybridMMKVFactory::createMMKV(const Configuration& configuration) {
19
+ return std::make_shared<HybridMMKV>(configuration);
20
+ }
21
+
22
+ void HybridMMKVFactory::initializeMMKV(const std::string& rootPath) {
23
+ Logger::log(LogLevel::Info, TAG, "Initializing MMKV with rootPath=%s", rootPath.c_str());
24
+
25
+ #ifdef NITRO_DEBUG
26
+ MMKVLogLevel logLevel = ::mmkv::MMKVLogDebug;
27
+ #else
28
+ MMKVLogLevel logLevel = ::mmkv::MMKVLogWarning;
29
+ #endif
30
+ MMKV::initializeMMKV(rootPath, logLevel);
31
+ }
32
+
33
+ } // namespace margelo::nitro::mmkv
@@ -0,0 +1,24 @@
1
+ //
2
+ // HybridMMKVFactory.hpp
3
+ // react-native-mmkv
4
+ //
5
+ // Created by Marc Rousavy on 21.08.2025.
6
+ //
7
+
8
+ #pragma once
9
+
10
+ #include "HybridMMKVFactorySpec.hpp"
11
+
12
+ namespace margelo::nitro::mmkv {
13
+
14
+ class HybridMMKVFactory final : public HybridMMKVFactorySpec {
15
+ public:
16
+ HybridMMKVFactory() : HybridObject(TAG) {}
17
+
18
+ public:
19
+ std::string getDefaultMMKVInstanceId() override;
20
+ std::shared_ptr<HybridMMKVSpec> createMMKV(const Configuration& configuration) override;
21
+ void initializeMMKV(const std::string& rootPath) override;
22
+ };
23
+
24
+ } // namespace margelo::nitro::mmkv