react-native-mmkv 4.0.0-beta.1 → 4.0.0-beta.2

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 (219) hide show
  1. package/{react-native-mmkv.podspec → NitroMmkv.podspec} +17 -13
  2. package/README.md +1 -3
  3. package/android/CMakeLists.txt +31 -30
  4. package/android/build.gradle +64 -19
  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/ios/HybridMMKVPlatformContext.swift +32 -0
  11. package/lib/__tests__/hooks.test.d.ts +1 -0
  12. package/lib/__tests__/hooks.test.js +66 -0
  13. package/lib/addMemoryWarningListener/addMemoryWarningListener.d.ts +2 -0
  14. package/lib/addMemoryWarningListener/addMemoryWarningListener.js +25 -0
  15. package/lib/addMemoryWarningListener/addMemoryWarningListener.mock.d.ts +2 -0
  16. package/lib/addMemoryWarningListener/addMemoryWarningListener.mock.js +3 -0
  17. package/lib/addMemoryWarningListener/addMemoryWarningListener.web.d.ts +2 -0
  18. package/lib/addMemoryWarningListener/addMemoryWarningListener.web.js +3 -0
  19. package/lib/createMMKV/createMMKV.d.ts +3 -0
  20. package/lib/createMMKV/createMMKV.js +40 -0
  21. package/lib/createMMKV/createMMKV.mock.d.ts +5 -0
  22. package/lib/createMMKV/createMMKV.mock.js +53 -0
  23. package/lib/createMMKV/createMMKV.web.d.ts +3 -0
  24. package/lib/createMMKV/createMMKV.web.js +117 -0
  25. package/lib/createMMKV/getDefaultMMKVInstance.d.ts +2 -0
  26. package/lib/createMMKV/getDefaultMMKVInstance.js +8 -0
  27. package/lib/hooks/createMMKVHook.d.ts +2 -0
  28. package/lib/hooks/createMMKVHook.js +49 -0
  29. package/lib/hooks/useMMKV.d.ts +11 -0
  30. package/lib/hooks/useMMKV.js +23 -0
  31. package/lib/hooks/useMMKVBoolean.d.ts +11 -0
  32. package/lib/hooks/useMMKVBoolean.js +12 -0
  33. package/lib/hooks/useMMKVBuffer.d.ts +11 -0
  34. package/lib/hooks/useMMKVBuffer.js +12 -0
  35. package/lib/hooks/useMMKVKeys.d.ts +12 -0
  36. package/lib/hooks/useMMKVKeys.js +33 -0
  37. package/lib/hooks/useMMKVListener.d.ts +15 -0
  38. package/lib/hooks/useMMKVListener.js +26 -0
  39. package/lib/hooks/useMMKVNumber.d.ts +11 -0
  40. package/lib/hooks/useMMKVNumber.js +12 -0
  41. package/lib/hooks/useMMKVObject.d.ts +17 -0
  42. package/lib/hooks/useMMKVObject.js +38 -0
  43. package/lib/hooks/useMMKVString.d.ts +11 -0
  44. package/lib/hooks/useMMKVString.js +12 -0
  45. package/lib/index.d.ts +11 -0
  46. package/lib/index.js +11 -0
  47. package/lib/isTest.d.ts +1 -0
  48. package/lib/isTest.js +7 -0
  49. package/lib/specs/MMKV.nitro.d.ts +93 -0
  50. package/lib/specs/MMKV.nitro.js +1 -0
  51. package/lib/{typescript/src/NativeMmkv.d.ts → specs/MMKVFactory.nitro.d.ts} +22 -29
  52. package/lib/specs/MMKVFactory.nitro.js +1 -0
  53. package/lib/specs/MMKVPlatformContext.nitro.d.ts +15 -0
  54. package/lib/specs/MMKVPlatformContext.nitro.js +1 -0
  55. package/lib/{typescript/src → web}/createTextEncoder.d.ts +0 -1
  56. package/lib/web/createTextEncoder.js +17 -0
  57. package/nitro.json +27 -0
  58. package/nitrogen/generated/.gitattributes +1 -0
  59. package/nitrogen/generated/android/NitroMmkv+autolinking.cmake +80 -0
  60. package/nitrogen/generated/android/NitroMmkv+autolinking.gradle +27 -0
  61. package/nitrogen/generated/android/NitroMmkvOnLoad.cpp +55 -0
  62. package/nitrogen/generated/android/NitroMmkvOnLoad.hpp +25 -0
  63. package/nitrogen/generated/android/c++/JHybridMMKVPlatformContextSpec.cpp +51 -0
  64. package/nitrogen/generated/android/c++/JHybridMMKVPlatformContextSpec.hpp +65 -0
  65. package/nitrogen/generated/android/kotlin/com/margelo/nitro/mmkv/HybridMMKVPlatformContextSpec.kt +56 -0
  66. package/nitrogen/generated/android/kotlin/com/margelo/nitro/mmkv/NitroMmkvOnLoad.kt +35 -0
  67. package/nitrogen/generated/ios/NitroMmkv+autolinking.rb +60 -0
  68. package/nitrogen/generated/ios/NitroMmkv-Swift-Cxx-Bridge.cpp +32 -0
  69. package/nitrogen/generated/ios/NitroMmkv-Swift-Cxx-Bridge.hpp +52 -0
  70. package/nitrogen/generated/ios/NitroMmkv-Swift-Cxx-Umbrella.hpp +44 -0
  71. package/nitrogen/generated/ios/NitroMmkvAutolinking.mm +43 -0
  72. package/nitrogen/generated/ios/NitroMmkvAutolinking.swift +25 -0
  73. package/nitrogen/generated/ios/c++/HybridMMKVPlatformContextSpecSwift.cpp +11 -0
  74. package/nitrogen/generated/ios/c++/HybridMMKVPlatformContextSpecSwift.hpp +81 -0
  75. package/nitrogen/generated/ios/swift/HybridMMKVPlatformContextSpec.swift +50 -0
  76. package/nitrogen/generated/ios/swift/HybridMMKVPlatformContextSpec_cxx.swift +135 -0
  77. package/nitrogen/generated/shared/c++/Configuration.hpp +86 -0
  78. package/nitrogen/generated/shared/c++/HybridMMKVFactorySpec.cpp +23 -0
  79. package/nitrogen/generated/shared/c++/HybridMMKVFactorySpec.hpp +69 -0
  80. package/nitrogen/generated/shared/c++/HybridMMKVPlatformContextSpec.cpp +22 -0
  81. package/nitrogen/generated/shared/c++/HybridMMKVPlatformContextSpec.hpp +63 -0
  82. package/nitrogen/generated/shared/c++/HybridMMKVSpec.cpp +34 -0
  83. package/nitrogen/generated/shared/c++/HybridMMKVSpec.hpp +83 -0
  84. package/nitrogen/generated/shared/c++/Listener.hpp +67 -0
  85. package/nitrogen/generated/shared/c++/Mode.hpp +76 -0
  86. package/package.json +71 -122
  87. package/react-native.config.js +2 -15
  88. package/src/__tests__/hooks.test.tsx +34 -34
  89. package/src/addMemoryWarningListener/addMemoryWarningListener.mock.ts +5 -0
  90. package/src/{MemoryWarningListener.ts → addMemoryWarningListener/addMemoryWarningListener.ts} +12 -12
  91. package/src/addMemoryWarningListener/addMemoryWarningListener.web.ts +5 -0
  92. package/src/createMMKV/createMMKV.mock.ts +56 -0
  93. package/src/createMMKV/createMMKV.ts +51 -0
  94. package/src/{createMMKV.web.ts → createMMKV/createMMKV.web.ts} +56 -46
  95. package/src/createMMKV/getDefaultMMKVInstance.ts +10 -0
  96. package/src/hooks/createMMKVHook.ts +66 -0
  97. package/src/hooks/useMMKV.ts +45 -0
  98. package/src/hooks/useMMKVBoolean.ts +15 -0
  99. package/src/hooks/useMMKVBuffer.ts +15 -0
  100. package/src/hooks/useMMKVKeys.ts +36 -0
  101. package/src/hooks/useMMKVListener.ts +33 -0
  102. package/src/hooks/useMMKVNumber.ts +15 -0
  103. package/src/hooks/useMMKVObject.ts +53 -0
  104. package/src/hooks/useMMKVString.ts +15 -0
  105. package/src/index.ts +15 -3
  106. package/src/{PlatformChecker.ts → isTest.ts} +2 -2
  107. package/src/specs/MMKV.nitro.ts +92 -0
  108. package/src/specs/MMKVFactory.nitro.ts +87 -0
  109. package/src/specs/MMKVPlatformContext.nitro.ts +14 -0
  110. package/src/{createTextEncoder.ts → web/createTextEncoder.ts} +7 -7
  111. package/android/src/main/cpp/AndroidLogger.cpp +0 -16
  112. package/android/src/main/java/com/mrousavy/mmkv/MmkvPackage.java +0 -44
  113. package/android/src/main/java/com/mrousavy/mmkv/MmkvPlatformContextModule.java +0 -26
  114. package/cpp/ManagedMMBuffer.h +0 -32
  115. package/cpp/MmkvHostObject.cpp +0 -360
  116. package/cpp/MmkvHostObject.h +0 -31
  117. package/cpp/MmkvLogger.h +0 -35
  118. package/cpp/MmkvTypes.h +0 -50
  119. package/cpp/NativeMmkvModule.cpp +0 -43
  120. package/cpp/NativeMmkvModule.h +0 -31
  121. package/ios/AppleLogger.mm +0 -16
  122. package/ios/MmkvOnLoad.mm +0 -25
  123. package/ios/MmkvPlatformContext.h +0 -19
  124. package/ios/MmkvPlatformContextModule.mm +0 -55
  125. package/lib/commonjs/MMKV.js +0 -124
  126. package/lib/commonjs/MMKV.js.map +0 -1
  127. package/lib/commonjs/MemoryWarningListener.js +0 -31
  128. package/lib/commonjs/MemoryWarningListener.js.map +0 -1
  129. package/lib/commonjs/MemoryWarningListener.web.js +0 -11
  130. package/lib/commonjs/MemoryWarningListener.web.js.map +0 -1
  131. package/lib/commonjs/ModuleNotFoundError.js +0 -75
  132. package/lib/commonjs/ModuleNotFoundError.js.map +0 -1
  133. package/lib/commonjs/NativeMmkv.js +0 -47
  134. package/lib/commonjs/NativeMmkv.js.map +0 -1
  135. package/lib/commonjs/NativeMmkvPlatformContext.js +0 -22
  136. package/lib/commonjs/NativeMmkvPlatformContext.js.map +0 -1
  137. package/lib/commonjs/PlatformChecker.js +0 -14
  138. package/lib/commonjs/PlatformChecker.js.map +0 -1
  139. package/lib/commonjs/Types.js +0 -26
  140. package/lib/commonjs/Types.js.map +0 -1
  141. package/lib/commonjs/createMMKV.js +0 -43
  142. package/lib/commonjs/createMMKV.js.map +0 -1
  143. package/lib/commonjs/createMMKV.mock.js +0 -43
  144. package/lib/commonjs/createMMKV.mock.js.map +0 -1
  145. package/lib/commonjs/createMMKV.web.js +0 -110
  146. package/lib/commonjs/createMMKV.web.js.map +0 -1
  147. package/lib/commonjs/createTextEncoder.js +0 -23
  148. package/lib/commonjs/createTextEncoder.js.map +0 -1
  149. package/lib/commonjs/hooks.js +0 -198
  150. package/lib/commonjs/hooks.js.map +0 -1
  151. package/lib/commonjs/index.js +0 -40
  152. package/lib/commonjs/index.js.map +0 -1
  153. package/lib/commonjs/package.json +0 -1
  154. package/lib/module/MMKV.js +0 -119
  155. package/lib/module/MMKV.js.map +0 -1
  156. package/lib/module/MemoryWarningListener.js +0 -27
  157. package/lib/module/MemoryWarningListener.js.map +0 -1
  158. package/lib/module/MemoryWarningListener.web.js +0 -6
  159. package/lib/module/MemoryWarningListener.web.js.map +0 -1
  160. package/lib/module/ModuleNotFoundError.js +0 -70
  161. package/lib/module/ModuleNotFoundError.js.map +0 -1
  162. package/lib/module/NativeMmkv.js +0 -45
  163. package/lib/module/NativeMmkv.js.map +0 -1
  164. package/lib/module/NativeMmkvPlatformContext.js +0 -18
  165. package/lib/module/NativeMmkvPlatformContext.js.map +0 -1
  166. package/lib/module/PlatformChecker.js +0 -10
  167. package/lib/module/PlatformChecker.js.map +0 -1
  168. package/lib/module/Types.js +0 -25
  169. package/lib/module/Types.js.map +0 -1
  170. package/lib/module/createMMKV.js +0 -38
  171. package/lib/module/createMMKV.js.map +0 -1
  172. package/lib/module/createMMKV.mock.js +0 -38
  173. package/lib/module/createMMKV.mock.js.map +0 -1
  174. package/lib/module/createMMKV.web.js +0 -105
  175. package/lib/module/createMMKV.web.js.map +0 -1
  176. package/lib/module/createTextEncoder.js +0 -19
  177. package/lib/module/createTextEncoder.js.map +0 -1
  178. package/lib/module/hooks.js +0 -189
  179. package/lib/module/hooks.js.map +0 -1
  180. package/lib/module/index.js +0 -6
  181. package/lib/module/index.js.map +0 -1
  182. package/lib/module/package.json +0 -1
  183. package/lib/typescript/src/MMKV.d.ts +0 -34
  184. package/lib/typescript/src/MMKV.d.ts.map +0 -1
  185. package/lib/typescript/src/MemoryWarningListener.d.ts +0 -3
  186. package/lib/typescript/src/MemoryWarningListener.d.ts.map +0 -1
  187. package/lib/typescript/src/MemoryWarningListener.web.d.ts +0 -3
  188. package/lib/typescript/src/MemoryWarningListener.web.d.ts.map +0 -1
  189. package/lib/typescript/src/ModuleNotFoundError.d.ts +0 -7
  190. package/lib/typescript/src/ModuleNotFoundError.d.ts.map +0 -1
  191. package/lib/typescript/src/NativeMmkv.d.ts.map +0 -1
  192. package/lib/typescript/src/NativeMmkvPlatformContext.d.ts +0 -20
  193. package/lib/typescript/src/NativeMmkvPlatformContext.d.ts.map +0 -1
  194. package/lib/typescript/src/PlatformChecker.d.ts +0 -2
  195. package/lib/typescript/src/PlatformChecker.d.ts.map +0 -1
  196. package/lib/typescript/src/Types.d.ts +0 -172
  197. package/lib/typescript/src/Types.d.ts.map +0 -1
  198. package/lib/typescript/src/__tests__/hooks.test.d.ts +0 -2
  199. package/lib/typescript/src/__tests__/hooks.test.d.ts.map +0 -1
  200. package/lib/typescript/src/createMMKV.d.ts +0 -3
  201. package/lib/typescript/src/createMMKV.d.ts.map +0 -1
  202. package/lib/typescript/src/createMMKV.mock.d.ts +0 -3
  203. package/lib/typescript/src/createMMKV.mock.d.ts.map +0 -1
  204. package/lib/typescript/src/createMMKV.web.d.ts +0 -3
  205. package/lib/typescript/src/createMMKV.web.d.ts.map +0 -1
  206. package/lib/typescript/src/createTextEncoder.d.ts.map +0 -1
  207. package/lib/typescript/src/hooks.d.ts +0 -86
  208. package/lib/typescript/src/hooks.d.ts.map +0 -1
  209. package/lib/typescript/src/index.d.ts +0 -4
  210. package/lib/typescript/src/index.d.ts.map +0 -1
  211. package/src/MMKV.ts +0 -142
  212. package/src/MemoryWarningListener.web.ts +0 -5
  213. package/src/ModuleNotFoundError.ts +0 -95
  214. package/src/NativeMmkv.ts +0 -118
  215. package/src/NativeMmkvPlatformContext.ts +0 -38
  216. package/src/Types.ts +0 -178
  217. package/src/createMMKV.mock.ts +0 -38
  218. package/src/createMMKV.ts +0 -42
  219. package/src/hooks.ts +0 -247
@@ -2,31 +2,35 @@ require "json"
2
2
 
3
3
  package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
4
 
5
- Pod::UI.puts "[react-native-mmkv] Thank you for using react-native-mmkv ❤️"
6
- Pod::UI.puts "[react-native-mmkv] If you enjoy using react-native-mmkv, please consider sponsoring this project: https://github.com/sponsors/mrousavy"
7
-
8
5
  Pod::Spec.new do |s|
9
- s.name = "react-native-mmkv"
6
+ s.name = "NitroMmkv"
10
7
  s.version = package["version"]
11
8
  s.summary = package["description"]
12
9
  s.homepage = package["homepage"]
13
10
  s.license = package["license"]
14
11
  s.authors = package["author"]
15
12
 
16
- s.platforms = { :ios => min_ios_version_supported, :tvos => "12.0", :osx => "10.14" }
13
+ s.platforms = { :ios => min_ios_version_supported, :visionos => 1.0, :tvos => "12.0", :osx => "10.14" }
17
14
  s.source = { :git => "https://github.com/mrousavy/react-native-mmkv.git", :tag => "#{s.version}" }
18
15
 
19
- s.pod_target_xcconfig = {
20
- "CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
21
- }
22
- s.compiler_flags = '-x objective-c++'
23
- s.libraries = "z", "c++"
24
16
  s.source_files = [
25
- # react-native-mmkv
26
- "ios/**/*.{h,m,mm}",
27
- "cpp/**/*.{hpp,cpp,c,h}"
17
+ # Implementation (Swift)
18
+ "ios/**/*.{swift}",
19
+ # Autolinking/Registration (Objective-C++)
20
+ "ios/**/*.{m,mm}",
21
+ # Implementation (C++ objects)
22
+ "cpp/**/*.{hpp,cpp}",
28
23
  ]
29
24
 
25
+ # Add MMKV Core dependency
26
+ s.compiler_flags = '-x objective-c++'
27
+ s.libraries = 'z', 'c++'
30
28
  s.dependency 'MMKVCore', '>= 2.2.3'
29
+
30
+ load 'nitrogen/generated/ios/NitroMmkv+autolinking.rb'
31
+ add_nitrogen_files(s)
32
+
33
+ s.dependency 'React-jsi'
34
+ s.dependency 'React-callinvoker'
31
35
  install_modules_dependencies(s)
32
36
  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
  )
@@ -9,29 +9,34 @@ buildscript {
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
+ }
@@ -0,0 +1,32 @@
1
+ //
2
+ // HybridMMKVPlatformContext.h
3
+ // react-native-mmkv
4
+ //
5
+ // Created by Marc Rousavy on 25.03.24.
6
+ //
7
+
8
+ import NitroModules
9
+
10
+ class HybridMMKVPlatformContext: HybridMMKVPlatformContextSpec {
11
+ static var directory: FileManager.SearchPathDirectory {
12
+ #if os(tvOS)
13
+ return .cachesDirectory
14
+ #else
15
+ return .documentDirectory
16
+ #endif
17
+ }
18
+
19
+ func getBaseDirectory() throws -> String {
20
+ let paths = NSSearchPathForDirectoriesInDomains(Self.directory, .userDomainMask, true)
21
+ if let documentPath = paths.first {
22
+ let basePath = documentPath + "/mmkv"
23
+ return basePath
24
+ } else {
25
+ throw RuntimeError.error(withMessage: "Cannot find base-path to store MMKV files!")
26
+ }
27
+ }
28
+
29
+ func getAppGroupDirectory() -> String {
30
+ return ""
31
+ }
32
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,66 @@
1
+ import React from 'react';
2
+ import { Button, Text } from 'react-native';
3
+ import { act, fireEvent, render, renderHook, screen, } from '@testing-library/react-native';
4
+ import { createMMKV, useMMKVNumber, useMMKVString } from '..';
5
+ const mmkv = createMMKV();
6
+ beforeEach(() => {
7
+ mmkv.clearAll();
8
+ mmkv.trim();
9
+ });
10
+ test('hooks update when the value is changed directly through the instance', () => {
11
+ const { result } = renderHook(() => useMMKVString('string-key', mmkv));
12
+ expect(result.current[0]).toBeUndefined();
13
+ // First, make a "normal" change
14
+ act(() => {
15
+ result.current[1]('value 1');
16
+ });
17
+ expect(result.current[0]).toStrictEqual('value 1');
18
+ // Now, make the change directly through the instance.
19
+ act(() => {
20
+ mmkv.set('string-key', 'value 2');
21
+ });
22
+ expect(result.current[0]).toStrictEqual('value 2');
23
+ });
24
+ test('functional updates to hooks', () => {
25
+ const Component = () => {
26
+ const [state, setState] = React.useState(0);
27
+ const [value, setValue] = useMMKVNumber('number-key', mmkv);
28
+ return (React.createElement(React.Fragment, null,
29
+ React.createElement(Button, { testID: "button", title: "Double Increment Me", onPress: () => {
30
+ // Increment the state value twice, using the function form of useState.
31
+ setState((current) => current + 1);
32
+ setState((current) => current + 1);
33
+ // Increment the MMKV value twice, using the same function form.
34
+ setValue((current) => (current ?? 0) + 1);
35
+ setValue((current) => (current ?? 0) + 1);
36
+ } }),
37
+ React.createElement(Text, { testID: "state-value" },
38
+ "State: ",
39
+ state.toString()),
40
+ React.createElement(Text, { testID: "mmkv-value" },
41
+ "MMKV: ",
42
+ (value ?? 0).toString())));
43
+ };
44
+ render(React.createElement(Component, null));
45
+ const button = screen.getByTestId('button');
46
+ // Why these assertions:
47
+ // https://github.com/mrousavy/react-native-mmkv/issues/599
48
+ fireEvent.press(button);
49
+ expect(screen.getByTestId('state-value').children).toStrictEqual([
50
+ 'State: ',
51
+ '2',
52
+ ]);
53
+ expect(screen.getByTestId('mmkv-value').children).toStrictEqual([
54
+ 'MMKV: ',
55
+ '2',
56
+ ]);
57
+ fireEvent.press(button);
58
+ expect(screen.getByTestId('state-value').children).toStrictEqual([
59
+ 'State: ',
60
+ '4',
61
+ ]);
62
+ expect(screen.getByTestId('mmkv-value').children).toStrictEqual([
63
+ 'MMKV: ',
64
+ '4',
65
+ ]);
66
+ });
@@ -0,0 +1,2 @@
1
+ import type { MMKV } from '../specs/MMKV.nitro';
2
+ export declare function addMemoryWarningListener(mmkv: MMKV): void;
@@ -0,0 +1,25 @@
1
+ import { AppState } from 'react-native';
2
+ export function addMemoryWarningListener(mmkv) {
3
+ if (global.WeakRef != null && global.FinalizationRegistry != null) {
4
+ // 1. Weakify MMKV so we can safely use it inside the memoryWarning event listener
5
+ const weakMmkv = new WeakRef(mmkv);
6
+ const listener = AppState.addEventListener('memoryWarning', () => {
7
+ // 0. Everytime we receive a memoryWarning, we try to trim the MMKV instance (if it is still valid)
8
+ weakMmkv.deref()?.trim();
9
+ });
10
+ // 2. Add a listener to when the MMKV instance is deleted
11
+ const finalization = new FinalizationRegistry((l) => {
12
+ // 3. When MMKV is deleted, this listener will be called with the memoryWarning listener.
13
+ l.remove();
14
+ });
15
+ // 2.1. Bind the listener to the actual MMKV instance.
16
+ finalization.register(mmkv, listener);
17
+ }
18
+ else {
19
+ // WeakRef/FinalizationRegistry is not implemented in this engine.
20
+ // Just add the listener, even if it retains MMKV strong forever.
21
+ AppState.addEventListener('memoryWarning', () => {
22
+ mmkv.trim();
23
+ });
24
+ }
25
+ }
@@ -0,0 +1,2 @@
1
+ import type { MMKV } from '../specs/MMKV.nitro';
2
+ export declare function addMemoryWarningListener(_mmkv: MMKV): void;
@@ -0,0 +1,3 @@
1
+ export function addMemoryWarningListener(_mmkv) {
2
+ // This is no-op in a mocked environment.
3
+ }
@@ -0,0 +1,2 @@
1
+ import type { MMKV } from '../specs/MMKV.nitro';
2
+ export declare const addMemoryWarningListener: (_mmkv: MMKV) => void;
@@ -0,0 +1,3 @@
1
+ export const addMemoryWarningListener = (_mmkv) => {
2
+ //no-op function, there is not a web equivalent to memory warning
3
+ };
@@ -0,0 +1,3 @@
1
+ import type { MMKV } from '../specs/MMKV.nitro';
2
+ import type { Configuration } from '../specs/MMKVFactory.nitro';
3
+ export declare function createMMKV(configuration?: Configuration): MMKV;
@@ -0,0 +1,40 @@
1
+ import { NitroModules } from 'react-native-nitro-modules';
2
+ import { Platform } from 'react-native';
3
+ import { addMemoryWarningListener } from '../addMemoryWarningListener/addMemoryWarningListener';
4
+ import { isTest } from '../isTest';
5
+ import { createMockMMKV } from './createMMKV.mock';
6
+ let factory;
7
+ let platformContext;
8
+ export function createMMKV(configuration) {
9
+ if (isTest()) {
10
+ // In a test environment, we mock the MMKV instance.
11
+ return createMockMMKV();
12
+ }
13
+ if (platformContext == null) {
14
+ // Lazy-init the platform-context HybridObject
15
+ platformContext = NitroModules.createHybridObject('MMKVPlatformContext');
16
+ }
17
+ if (factory == null) {
18
+ // Lazy-init the factory HybridObject
19
+ factory = NitroModules.createHybridObject('MMKVFactory');
20
+ const baseDirectory = platformContext.getBaseDirectory();
21
+ factory.initializeMMKV(baseDirectory);
22
+ }
23
+ // Pre-parse the config
24
+ let config = configuration ?? { id: factory.defaultMMKVInstanceId };
25
+ if (Platform.OS === 'ios') {
26
+ if (config.path == null) {
27
+ // If the user set an App Group directory in Info.plist, let's use
28
+ // the App Group as a MMKV path:
29
+ const appGroupDirectory = platformContext.getAppGroupDirectory();
30
+ if (appGroupDirectory != null) {
31
+ config.path = appGroupDirectory;
32
+ }
33
+ }
34
+ }
35
+ // Creates the C++ MMKV HybridObject
36
+ const mmkv = factory.createMMKV(config);
37
+ // Add a hook that trims the storage when we get a memory warning
38
+ addMemoryWarningListener(mmkv);
39
+ return mmkv;
40
+ }
@@ -0,0 +1,5 @@
1
+ import type { MMKV } from '../specs/MMKV.nitro';
2
+ /**
3
+ * Mock MMKV instance when used in a Jest/Test environment.
4
+ */
5
+ export declare function createMockMMKV(): MMKV;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Mock MMKV instance when used in a Jest/Test environment.
3
+ */
4
+ export function createMockMMKV() {
5
+ const storage = new Map();
6
+ const listeners = new Set();
7
+ return {
8
+ clearAll: () => storage.clear(),
9
+ remove: (key) => storage.delete(key),
10
+ set: (key, value) => storage.set(key, value),
11
+ getString: (key) => {
12
+ const result = storage.get(key);
13
+ return typeof result === 'string' ? result : undefined;
14
+ },
15
+ getNumber: (key) => {
16
+ const result = storage.get(key);
17
+ return typeof result === 'number' ? result : undefined;
18
+ },
19
+ getBoolean: (key) => {
20
+ const result = storage.get(key);
21
+ return typeof result === 'boolean' ? result : undefined;
22
+ },
23
+ getBuffer: (key) => {
24
+ const result = storage.get(key);
25
+ return result instanceof ArrayBuffer ? result : undefined;
26
+ },
27
+ getAllKeys: () => Array.from(storage.keys()),
28
+ contains: (key) => storage.has(key),
29
+ recrypt: () => {
30
+ console.warn('Encryption is not supported in mocked MMKV instances!');
31
+ },
32
+ get size() {
33
+ return storage.size;
34
+ },
35
+ isReadOnly: false,
36
+ trim: () => {
37
+ // no-op
38
+ },
39
+ name: 'MMKV',
40
+ dispose: () => { },
41
+ equals: () => {
42
+ return false;
43
+ },
44
+ addOnValueChangedListener: (listener) => {
45
+ listeners.add(listener);
46
+ return {
47
+ remove: () => {
48
+ listeners.delete(listener);
49
+ },
50
+ };
51
+ },
52
+ };
53
+ }
@@ -0,0 +1,3 @@
1
+ import type { MMKV } from '../specs/MMKV.nitro';
2
+ import type { Configuration } from '../specs/MMKVFactory.nitro';
3
+ export declare function createMMKV(config: Configuration): MMKV;