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
@@ -1,360 +0,0 @@
1
- //
2
- // MmkvHostObject.cpp
3
- // Mmkv
4
- //
5
- // Created by Marc Rousavy on 03.09.21.
6
- // Copyright © 2021 Facebook. All rights reserved.
7
- //
8
-
9
- #include "MmkvHostObject.h"
10
- #include "ManagedMMBuffer.h"
11
- #include "MmkvLogger.h"
12
- #include <string>
13
- #include <vector>
14
-
15
- using namespace mmkv;
16
- using namespace facebook;
17
-
18
- MmkvHostObject::MmkvHostObject(const facebook::react::MMKVConfig& config) {
19
- std::string path = config.path.has_value() ? config.path.value() : "";
20
- std::string encryptionKey = config.encryptionKey.has_value() ? config.encryptionKey.value() : "";
21
- bool hasEncryptionKey = encryptionKey.size() > 0;
22
- MmkvLogger::log("RNMMKV", "Creating MMKV instance \"%s\"... (Path: %s, Encrypted: %s)",
23
- config.id.c_str(), path.c_str(), hasEncryptionKey ? "true" : "false");
24
-
25
- std::string* pathPtr = path.size() > 0 ? &path : nullptr;
26
- std::string* encryptionKeyPtr = encryptionKey.size() > 0 ? &encryptionKey : nullptr;
27
- MMKVMode mode = getMMKVMode(config);
28
- if (config.readOnly.has_value() && config.readOnly.value()) {
29
- MmkvLogger::log("RNMMKV", "Instance is read-only!");
30
- mode = mode | mmkv::MMKV_READ_ONLY;
31
- }
32
-
33
- #ifdef __APPLE__
34
- instance = MMKV::mmkvWithID(config.id, mode, encryptionKeyPtr, pathPtr);
35
- #else
36
- instance = MMKV::mmkvWithID(config.id, DEFAULT_MMAP_SIZE, mode, encryptionKeyPtr, pathPtr);
37
- #endif
38
-
39
- if (instance == nullptr) [[unlikely]] {
40
- // Check if instanceId is invalid
41
- if (config.id.empty()) [[unlikely]] {
42
- throw std::runtime_error("Failed to create MMKV instance! `id` cannot be empty!");
43
- }
44
-
45
- // Check if encryptionKey is invalid
46
- if (encryptionKey.size() > 16) [[unlikely]] {
47
- throw std::runtime_error(
48
- "Failed to create MMKV instance! `encryptionKey` cannot be longer than 16 bytes!");
49
- }
50
-
51
- throw std::runtime_error("Failed to create MMKV instance!");
52
- }
53
- }
54
-
55
- MmkvHostObject::~MmkvHostObject() {
56
- if (instance != nullptr) {
57
- std::string instanceId = instance->mmapID();
58
- MmkvLogger::log("RNMMKV", "Destroying MMKV instance \"%s\"...", instanceId.c_str());
59
- instance->sync();
60
- instance->clearMemoryCache();
61
- }
62
- instance = nullptr;
63
- }
64
-
65
- std::vector<jsi::PropNameID> MmkvHostObject::getPropertyNames(jsi::Runtime& rt) {
66
- return jsi::PropNameID::names(rt, "set", "getBoolean", "getBuffer", "getString", "getNumber",
67
- "contains", "delete", "getAllKeys", "deleteAll", "recrypt", "trim",
68
- "size", "isReadOnly");
69
- }
70
-
71
- MMKVMode MmkvHostObject::getMMKVMode(const facebook::react::MMKVConfig& config) {
72
- if (!config.mode.has_value()) {
73
- return mmkv::MMKV_SINGLE_PROCESS;
74
- }
75
- react::NativeMmkvMode mode = config.mode.value();
76
- switch (mode) {
77
- case react::NativeMmkvMode::SINGLE_PROCESS:
78
- return mmkv::MMKV_SINGLE_PROCESS;
79
- case react::NativeMmkvMode::MULTI_PROCESS:
80
- return mmkv::MMKV_MULTI_PROCESS;
81
- default:
82
- [[unlikely]] throw std::runtime_error("Invalid MMKV Mode value!");
83
- }
84
- }
85
-
86
- jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& propNameId) {
87
- std::string propName = propNameId.utf8(runtime);
88
-
89
- if (propName == "set") {
90
- // MMKV.set(key: string, value: string | number | bool | ArrayBuffer)
91
- return jsi::Function::createFromHostFunction(
92
- runtime, jsi::PropNameID::forAscii(runtime, propName),
93
- 2, // key, value
94
- [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
95
- size_t count) -> jsi::Value {
96
- if (count != 2 || !arguments[0].isString()) [[unlikely]] {
97
- throw jsi::JSError(runtime,
98
- "MMKV::set: First argument ('key') has to be of type string!");
99
- }
100
-
101
- std::string keyName = arguments[0].getString(runtime).utf8(runtime);
102
-
103
- bool successful = false;
104
- if (arguments[1].isBool()) {
105
- // bool
106
- successful = instance->set(arguments[1].getBool(), keyName);
107
- } else if (arguments[1].isNumber()) {
108
- // number
109
- successful = instance->set(arguments[1].getNumber(), keyName);
110
- } else if (arguments[1].isString()) {
111
- // string
112
- std::string stringValue = arguments[1].getString(runtime).utf8(runtime);
113
- successful = instance->set(stringValue, keyName);
114
- } else if (arguments[1].isObject()) {
115
- // object
116
- jsi::Object object = arguments[1].getObject(runtime);
117
- if (object.isArrayBuffer(runtime)) {
118
- // ArrayBuffer
119
- jsi::ArrayBuffer arrayBuffer = object.getArrayBuffer(runtime);
120
- MMBuffer data(arrayBuffer.data(runtime), arrayBuffer.size(runtime), MMBufferNoCopy);
121
- successful = instance->set(data, keyName);
122
- } else [[unlikely]] {
123
- // unknown object
124
- throw jsi::JSError(
125
- runtime,
126
- "MMKV::set: 'value' argument is an object, but not of type ArrayBuffer!");
127
- }
128
- } else [[unlikely]] {
129
- // unknown type
130
- throw jsi::JSError(
131
- runtime,
132
- "MMKV::set: 'value' argument is not of type bool, number, string or buffer!");
133
- }
134
-
135
- if (!successful) [[unlikely]] {
136
- if (instance->isReadOnly()) {
137
- throw jsi::JSError(runtime,
138
- "Failed to set " + keyName + "! This instance is read-only!");
139
- } else {
140
- throw jsi::JSError(runtime, "Failed to set " + keyName + "!");
141
- }
142
- }
143
-
144
- return jsi::Value::undefined();
145
- });
146
- }
147
-
148
- if (propName == "getBoolean") {
149
- // MMKV.getBoolean(key: string)
150
- return jsi::Function::createFromHostFunction(
151
- runtime, jsi::PropNameID::forAscii(runtime, propName),
152
- 1, // key
153
- [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
154
- size_t count) -> jsi::Value {
155
- if (count != 1 || !arguments[0].isString()) [[unlikely]] {
156
- throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
157
- }
158
-
159
- std::string keyName = arguments[0].getString(runtime).utf8(runtime);
160
- bool hasValue;
161
- bool value = instance->getBool(keyName, false, &hasValue);
162
- if (!hasValue) [[unlikely]] {
163
- return jsi::Value::undefined();
164
- }
165
- return jsi::Value(value);
166
- });
167
- }
168
-
169
- if (propName == "getNumber") {
170
- // MMKV.getNumber(key: string)
171
- return jsi::Function::createFromHostFunction(
172
- runtime, jsi::PropNameID::forAscii(runtime, propName),
173
- 1, // key
174
- [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
175
- size_t count) -> jsi::Value {
176
- if (count != 1 || !arguments[0].isString()) [[unlikely]] {
177
- throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
178
- }
179
-
180
- std::string keyName = arguments[0].getString(runtime).utf8(runtime);
181
- bool hasValue;
182
- double value = instance->getDouble(keyName, 0.0, &hasValue);
183
- if (!hasValue) [[unlikely]] {
184
- return jsi::Value::undefined();
185
- }
186
- return jsi::Value(value);
187
- });
188
- }
189
-
190
- if (propName == "getString") {
191
- // MMKV.getString(key: string)
192
- return jsi::Function::createFromHostFunction(
193
- runtime, jsi::PropNameID::forAscii(runtime, propName),
194
- 1, // key
195
- [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
196
- size_t count) -> jsi::Value {
197
- if (count != 1 || !arguments[0].isString()) [[unlikely]] {
198
- throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
199
- }
200
-
201
- std::string keyName = arguments[0].getString(runtime).utf8(runtime);
202
- std::string result;
203
- bool hasValue = instance->getString(keyName, result);
204
- if (!hasValue) [[unlikely]] {
205
- return jsi::Value::undefined();
206
- }
207
- return jsi::Value(runtime, jsi::String::createFromUtf8(runtime, result));
208
- });
209
- }
210
-
211
- if (propName == "getBuffer") {
212
- // MMKV.getBuffer(key: string)
213
- return jsi::Function::createFromHostFunction(
214
- runtime, jsi::PropNameID::forAscii(runtime, propName),
215
- 1, // key
216
- [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
217
- size_t count) -> jsi::Value {
218
- if (count != 1 || !arguments[0].isString()) [[unlikely]] {
219
- throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
220
- }
221
-
222
- std::string keyName = arguments[0].getString(runtime).utf8(runtime);
223
- MMBuffer buffer;
224
- #ifdef __OBJC__
225
- // iOS: Convert std::string to NSString* for MMKVCore pod compatibility
226
- bool hasValue = instance->getBytes(@(keyName.c_str()), buffer);
227
- #else
228
- // Android/other platforms: Use std::string directly (converts to std::string_view)
229
- bool hasValue = instance->getBytes(keyName, buffer);
230
- #endif
231
- if (!hasValue) [[unlikely]] {
232
- return jsi::Value::undefined();
233
- }
234
- auto mutableData = std::make_shared<ManagedMMBuffer>(std::move(buffer));
235
- return jsi::ArrayBuffer(runtime, mutableData);
236
- });
237
- }
238
-
239
- if (propName == "contains") {
240
- // MMKV.contains(key: string)
241
- return jsi::Function::createFromHostFunction(
242
- runtime, jsi::PropNameID::forAscii(runtime, propName),
243
- 1, // key
244
- [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
245
- size_t count) -> jsi::Value {
246
- if (count != 1 || !arguments[0].isString()) [[unlikely]] {
247
- throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
248
- }
249
-
250
- std::string keyName = arguments[0].getString(runtime).utf8(runtime);
251
- bool containsKey = instance->containsKey(keyName);
252
- return jsi::Value(containsKey);
253
- });
254
- }
255
-
256
- if (propName == "delete") {
257
- // MMKV.delete(key: string)
258
- return jsi::Function::createFromHostFunction(
259
- runtime, jsi::PropNameID::forAscii(runtime, propName),
260
- 1, // key
261
- [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
262
- size_t count) -> jsi::Value {
263
- if (count != 1 || !arguments[0].isString()) [[unlikely]] {
264
- throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
265
- }
266
-
267
- std::string keyName = arguments[0].getString(runtime).utf8(runtime);
268
- instance->removeValueForKey(keyName);
269
- return jsi::Value::undefined();
270
- });
271
- }
272
-
273
- if (propName == "getAllKeys") {
274
- // MMKV.getAllKeys()
275
- return jsi::Function::createFromHostFunction(
276
- runtime, jsi::PropNameID::forAscii(runtime, propName), 0,
277
- [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
278
- size_t count) -> jsi::Value {
279
- std::vector<std::string> keys = instance->allKeys();
280
- jsi::Array array(runtime, keys.size());
281
- for (int i = 0; i < keys.size(); i++) {
282
- array.setValueAtIndex(runtime, i, keys[i]);
283
- }
284
- return array;
285
- });
286
- }
287
-
288
- if (propName == "clearAll") {
289
- // MMKV.clearAll()
290
- return jsi::Function::createFromHostFunction(
291
- runtime, jsi::PropNameID::forAscii(runtime, propName), 0,
292
- [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
293
- size_t count) -> jsi::Value {
294
- instance->clearAll();
295
- return jsi::Value::undefined();
296
- });
297
- }
298
-
299
- if (propName == "recrypt") {
300
- // MMKV.recrypt(encryptionKey)
301
- return jsi::Function::createFromHostFunction(
302
- runtime, jsi::PropNameID::forAscii(runtime, propName),
303
- 1, // encryptionKey
304
- [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
305
- size_t count) -> jsi::Value {
306
- if (count != 1) [[unlikely]] {
307
- throw jsi::JSError(runtime, "Expected 1 argument (encryptionKey), but received " +
308
- std::to_string(count) + "!");
309
- }
310
-
311
- bool successful = false;
312
- if (arguments[0].isUndefined()) {
313
- // reset encryption key to "no encryption"
314
- successful = instance->reKey(std::string());
315
- } else if (arguments[0].isString()) {
316
- // reKey(..) with new encryption-key
317
- std::string encryptionKey = arguments[0].getString(runtime).utf8(runtime);
318
- successful = instance->reKey(encryptionKey);
319
- } else [[unlikely]] {
320
- // Invalid argument (maybe object?)
321
- throw jsi::JSError(
322
- runtime,
323
- "First argument ('encryptionKey') has to be of type string (or undefined)!");
324
- }
325
-
326
- if (!successful) [[unlikely]] {
327
- throw jsi::JSError(runtime, "Failed to recrypt MMKV instance!");
328
- }
329
-
330
- return jsi::Value::undefined();
331
- });
332
- }
333
-
334
- if (propName == "trim") {
335
- // MMKV.trim()
336
- return jsi::Function::createFromHostFunction(
337
- runtime, jsi::PropNameID::forAscii(runtime, propName), 0,
338
- [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
339
- size_t count) -> jsi::Value {
340
- instance->clearMemoryCache();
341
- instance->trim();
342
-
343
- return jsi::Value::undefined();
344
- });
345
- }
346
-
347
- if (propName == "size") {
348
- // MMKV.size
349
- size_t size = instance->actualSize();
350
- return jsi::Value(static_cast<int>(size));
351
- }
352
-
353
- if (propName == "isReadOnly") {
354
- // MMKV.isReadOnly
355
- bool isReadOnly = instance->isReadOnly();
356
- return jsi::Value(isReadOnly);
357
- }
358
-
359
- return jsi::Value::undefined();
360
- }
@@ -1,31 +0,0 @@
1
- //
2
- // MmkvHostObject.h
3
- // Mmkv
4
- //
5
- // Created by Marc Rousavy on 03.09.21.
6
- // Copyright © 2021 Facebook. All rights reserved.
7
- //
8
-
9
- #pragma once
10
-
11
- #include "MmkvTypes.h" // IWYU pragma: keep
12
- #include "NativeMmkvModule.h"
13
- #include <jsi/jsi.h>
14
-
15
- using namespace facebook;
16
-
17
- class MmkvHostObject : public jsi::HostObject {
18
- public:
19
- MmkvHostObject(const facebook::react::MMKVConfig& config);
20
- ~MmkvHostObject();
21
-
22
- public:
23
- jsi::Value get(jsi::Runtime&, const jsi::PropNameID& name) override;
24
- std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& rt) override;
25
-
26
- private:
27
- static MMKVMode getMMKVMode(const facebook::react::MMKVConfig& config);
28
-
29
- private:
30
- MMKV* instance;
31
- };
package/cpp/MmkvLogger.h DELETED
@@ -1,35 +0,0 @@
1
- //
2
- // MmkvLogger.h
3
- // react-native-mmkv
4
- //
5
- // Created by Marc Rousavy on 25.03.24.
6
- //
7
-
8
- #include <string>
9
-
10
- class MmkvLogger {
11
- private:
12
- MmkvLogger() = delete;
13
-
14
- private:
15
- template <typename... Args>
16
- static std::string string_format(const std::string& format, Args... args) {
17
- int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0'
18
- if (size_s <= 0) {
19
- throw std::runtime_error("Failed to format string!");
20
- }
21
- auto size = static_cast<size_t>(size_s);
22
- std::unique_ptr<char[]> buf(new char[size]);
23
- std::snprintf(buf.get(), size, format.c_str(), args...);
24
- return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
25
- }
26
-
27
- public:
28
- static void log(const std::string& tag, const std::string& message);
29
-
30
- template <typename... Args>
31
- inline static void log(const std::string& tag, const std::string& formatString, Args&&... args) {
32
- std::string formattedString = string_format(formatString, std::forward<Args>(args)...);
33
- log(tag, formattedString);
34
- }
35
- };
package/cpp/MmkvTypes.h DELETED
@@ -1,50 +0,0 @@
1
- //
2
- // MmkvTypes.h
3
- // react-native-mmkv
4
- //
5
- // Created by Brad Anderson on 10.08.2025.
6
- // Platform-specific MMKV type unification header
7
- //
8
-
9
- #pragma once
10
-
11
- // Platform-specific MMKV includes
12
- #ifdef __ANDROID__
13
- #include <MMKV/MMKV.h>
14
-
15
- // On Android, bring global namespace types into mmkv namespace for consistency
16
- namespace mmkv {
17
- using MMKV = ::MMKV;
18
- using MMKVMode = ::MMKVMode;
19
- using MMKVLogLevel = ::MMKVLogLevel;
20
-
21
- // Constants - bring into mmkv namespace
22
- constexpr auto MMKVLogDebug = ::MMKVLogDebug;
23
- constexpr auto MMKVLogInfo = ::MMKVLogInfo;
24
- constexpr auto MMKVLogWarning = ::MMKVLogWarning;
25
- constexpr auto MMKVLogError = ::MMKVLogError;
26
- constexpr auto MMKVLogNone = ::MMKVLogNone;
27
-
28
- constexpr auto MMKV_SINGLE_PROCESS = ::MMKV_SINGLE_PROCESS;
29
- constexpr auto MMKV_MULTI_PROCESS = ::MMKV_MULTI_PROCESS;
30
- constexpr auto MMKV_READ_ONLY = ::MMKVMode::MMKV_READ_ONLY;
31
- } // namespace mmkv
32
-
33
- #else
34
- #include <MMKVCore/MMKV.h>
35
- // iOS already has everything in mmkv:: namespace
36
- #endif
37
-
38
- /**
39
- * Unified MMKV namespace usage for cross-platform compatibility.
40
- *
41
- * After including this header, use:
42
- * - mmkv::MMKV for the main class
43
- * - mmkv::MMKVMode for mode enum
44
- * - mmkv::MMKVLogLevel for log level enum
45
- * - mmkv::MMBuffer for buffer type
46
- * - mmkv::MMKV_SINGLE_PROCESS / mmkv::MMKV_MULTI_PROCESS for modes
47
- * - mmkv::MMKVLogDebug, etc. for log levels
48
- */
49
-
50
- using namespace mmkv;
@@ -1,43 +0,0 @@
1
- //
2
- // NativeMmkvModule.cpp
3
- // react-native-mmkv
4
- //
5
- // Created by Marc Rousavy on 25.03.2024.
6
- //
7
-
8
- #include "NativeMmkvModule.h"
9
- #include "MmkvHostObject.h"
10
- #include "MmkvLogger.h"
11
- #include "MmkvTypes.h" // IWYU pragma: keep
12
-
13
- namespace facebook::react {
14
-
15
- NativeMmkvModule::NativeMmkvModule(std::shared_ptr<CallInvoker> jsInvoker)
16
- : NativeMmkvCxxSpec(jsInvoker) {}
17
-
18
- bool NativeMmkvModule::initialize(jsi::Runtime& runtime, std::string basePath) {
19
- if (basePath.empty()) {
20
- throw jsi::JSError(runtime, "Path cannot be empty!");
21
- }
22
-
23
- MmkvLogger::log("RNMMKV", "Initializing MMKV at %s...", basePath.c_str());
24
-
25
- #ifdef DEBUG
26
- MMKVLogLevel logLevel = mmkv::MMKVLogDebug;
27
- #else
28
- MMKVLogLevel logLevel = mmkv::MMKVLogWarning;
29
- #endif
30
-
31
- MMKV::initializeMMKV(basePath, logLevel);
32
-
33
- return true;
34
- }
35
-
36
- NativeMmkvModule::~NativeMmkvModule() {}
37
-
38
- jsi::Object NativeMmkvModule::createMMKV(jsi::Runtime& runtime, MMKVConfig config) {
39
- auto instance = std::make_shared<MmkvHostObject>(config);
40
- return jsi::Object::createFromHostObject(runtime, instance);
41
- }
42
-
43
- } // namespace facebook::react
@@ -1,31 +0,0 @@
1
- //
2
- // NativeMmkvModule.h
3
- // react-native-mmkv
4
- //
5
- // Created by Marc Rousavy on 25.03.2024.
6
- //
7
-
8
- #pragma once
9
-
10
- #include <RNMmkvSpecJSI.h>
11
- #include <string>
12
-
13
- namespace facebook::react {
14
-
15
- // The MMKVConfiguration type from JS
16
- using MMKVConfig =
17
- NativeMmkvConfiguration<std::string, std::optional<std::string>, std::optional<std::string>,
18
- std::optional<NativeMmkvMode>, std::optional<bool>>;
19
- template <> struct Bridging<MMKVConfig> : NativeMmkvConfigurationBridging<MMKVConfig> {};
20
-
21
- // The TurboModule itself
22
- class NativeMmkvModule : public NativeMmkvCxxSpec<NativeMmkvModule> {
23
- public:
24
- NativeMmkvModule(std::shared_ptr<CallInvoker> jsInvoker);
25
- ~NativeMmkvModule();
26
-
27
- bool initialize(jsi::Runtime& runtime, std::string basePath);
28
- jsi::Object createMMKV(jsi::Runtime& runtime, MMKVConfig config);
29
- };
30
-
31
- } // namespace facebook::react
@@ -1,16 +0,0 @@
1
- //
2
- // AppleMmkvLogger.m
3
- // react-native-mmkv
4
- //
5
- // Created by Marc Rousavy on 25.03.24.
6
- //
7
-
8
- #import "MmkvLogger.h"
9
- #import <Foundation/Foundation.h>
10
-
11
- void MmkvLogger::log(const std::string& tag, const std::string& message) {
12
- #pragma clang diagnostic push
13
- #pragma clang diagnostic ignored "-Wformat-security"
14
- NSLog(@"[%s]: %s", tag.c_str(), message.c_str());
15
- #pragma clang diagnostic pop
16
- }
package/ios/MmkvOnLoad.mm DELETED
@@ -1,25 +0,0 @@
1
- //
2
- // MmkvOnLoad.mm
3
- // react-native-mmkv
4
- //
5
- // Created by Marc Rousavy on 27.03.24.
6
- //
7
-
8
- #import "NativeMmkvModule.h"
9
- #import <Foundation/Foundation.h>
10
- #import <ReactCommon/CxxTurboModuleUtils.h>
11
-
12
- @interface MMKVOnLoad : NSObject
13
- @end
14
-
15
- @implementation MMKVOnLoad
16
-
17
- + (void)load {
18
- facebook::react::registerCxxModuleToGlobalModuleMap(
19
- std::string(facebook::react::NativeMmkvModule::kModuleName),
20
- [&](std::shared_ptr<facebook::react::CallInvoker> jsInvoker) {
21
- return std::make_shared<facebook::react::NativeMmkvModule>(jsInvoker);
22
- });
23
- }
24
-
25
- @end
@@ -1,19 +0,0 @@
1
- //
2
- // RTNMmkvPlatformContext.h
3
- // Pods
4
- //
5
- // Created by Marc Rousavy on 27.03.24.
6
- //
7
-
8
- #pragma once
9
-
10
- #import <Foundation/Foundation.h>
11
- #import <RNMmkvSpec/RNMmkvSpec.h>
12
-
13
- NS_ASSUME_NONNULL_BEGIN
14
-
15
- @interface MmkvPlatformContext : NSObject <NativeMmkvPlatformContextSpec>
16
-
17
- @end
18
-
19
- NS_ASSUME_NONNULL_END
@@ -1,55 +0,0 @@
1
- //
2
- // AppleMmkvPlatformContext.m
3
- // react-native-mmkv
4
- //
5
- // Created by Marc Rousavy on 25.03.24.
6
- //
7
-
8
- #import "MmkvPlatformContext.h"
9
- #import <Foundation/Foundation.h>
10
-
11
- @implementation MmkvPlatformContext
12
-
13
- RCT_EXPORT_MODULE()
14
-
15
- - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
16
- (const facebook::react::ObjCTurboModule::InitParams&)params {
17
- return std::make_shared<facebook::react::NativeMmkvPlatformContextSpecJSI>(params);
18
- }
19
-
20
- - (NSString*)getBaseDirectory {
21
- #if TARGET_OS_TV
22
- NSArray* paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
23
- #else
24
- NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
25
- #endif
26
- NSString* documentPath = (NSString*)[paths firstObject];
27
- if (documentPath.length > 0) {
28
- NSString* basePath = [documentPath stringByAppendingPathComponent:@"mmkv"];
29
- return basePath;
30
- } else {
31
- @throw [NSException exceptionWithName:@"BasePathNotFound"
32
- reason:@"Cannot find base-path to store MMKV files!"
33
- userInfo:nil];
34
- }
35
- }
36
-
37
- - (NSString*)getAppGroupDirectory {
38
- NSString* appGroup = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"AppGroup"];
39
- if (appGroup == nil) {
40
- // No AppGroup set in Info.plist.
41
- return nil;
42
- }
43
- NSURL* groupDir =
44
- [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:appGroup];
45
- if (groupDir == nil) {
46
- // We have an AppGroup set in Info.plist, but the path is not readable!
47
- @throw [NSException exceptionWithName:@"AppGroupNotAccessible"
48
- reason:@"An AppGroup was set in Info.plist, but it is not "
49
- @"accessible via NSFileManager!"
50
- userInfo:@{@"appGroup" : appGroup}];
51
- }
52
- return groupDir.path;
53
- }
54
-
55
- @end