react-native-mmkv-dz 2.5.1

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 (138) hide show
  1. package/LICENSE +219 -0
  2. package/MMKV/CHANGELOG.md +553 -0
  3. package/MMKV/Core/CMakeLists.txt +153 -0
  4. package/MMKV/Core/CodedInputData.cpp +228 -0
  5. package/MMKV/Core/CodedInputData.h +83 -0
  6. package/MMKV/Core/CodedInputDataCrypt.cpp +280 -0
  7. package/MMKV/Core/CodedInputDataCrypt.h +87 -0
  8. package/MMKV/Core/CodedInputDataCrypt_OSX.cpp +62 -0
  9. package/MMKV/Core/CodedInputData_OSX.cpp +92 -0
  10. package/MMKV/Core/CodedOutputData.cpp +174 -0
  11. package/MMKV/Core/CodedOutputData.h +82 -0
  12. package/MMKV/Core/Core.xcodeproj/project.pbxproj +702 -0
  13. package/MMKV/Core/Core.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  14. package/MMKV/Core/Core.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  15. package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/Core.xcscheme +67 -0
  16. package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/MMKVWatchCore.xcscheme +67 -0
  17. package/MMKV/Core/InterProcessLock.cpp +186 -0
  18. package/MMKV/Core/InterProcessLock.h +119 -0
  19. package/MMKV/Core/InterProcessLock_Android.cpp +103 -0
  20. package/MMKV/Core/InterProcessLock_Win32.cpp +108 -0
  21. package/MMKV/Core/KeyValueHolder.cpp +236 -0
  22. package/MMKV/Core/KeyValueHolder.h +118 -0
  23. package/MMKV/Core/MMBuffer.cpp +185 -0
  24. package/MMKV/Core/MMBuffer.h +107 -0
  25. package/MMKV/Core/MMKV.cpp +1418 -0
  26. package/MMKV/Core/MMKV.h +386 -0
  27. package/MMKV/Core/MMKVLog.cpp +127 -0
  28. package/MMKV/Core/MMKVLog.h +86 -0
  29. package/MMKV/Core/MMKVLog_Android.cpp +79 -0
  30. package/MMKV/Core/MMKVMetaInfo.hpp +81 -0
  31. package/MMKV/Core/MMKVPredef.h +245 -0
  32. package/MMKV/Core/MMKV_Android.cpp +259 -0
  33. package/MMKV/Core/MMKV_IO.cpp +1119 -0
  34. package/MMKV/Core/MMKV_IO.h +57 -0
  35. package/MMKV/Core/MMKV_OSX.cpp +347 -0
  36. package/MMKV/Core/MMKV_OSX.h +51 -0
  37. package/MMKV/Core/MemoryFile.cpp +537 -0
  38. package/MMKV/Core/MemoryFile.h +182 -0
  39. package/MMKV/Core/MemoryFile_Android.cpp +211 -0
  40. package/MMKV/Core/MemoryFile_Linux.cpp +120 -0
  41. package/MMKV/Core/MemoryFile_OSX.cpp +142 -0
  42. package/MMKV/Core/MemoryFile_Win32.cpp +536 -0
  43. package/MMKV/Core/MiniPBCoder.cpp +366 -0
  44. package/MMKV/Core/MiniPBCoder.h +129 -0
  45. package/MMKV/Core/MiniPBCoder_OSX.cpp +228 -0
  46. package/MMKV/Core/PBEncodeItem.hpp +86 -0
  47. package/MMKV/Core/PBUtility.cpp +61 -0
  48. package/MMKV/Core/PBUtility.h +153 -0
  49. package/MMKV/Core/ScopedLock.hpp +69 -0
  50. package/MMKV/Core/ThreadLock.cpp +68 -0
  51. package/MMKV/Core/ThreadLock.h +78 -0
  52. package/MMKV/Core/ThreadLock_Win32.cpp +89 -0
  53. package/MMKV/Core/aes/AESCrypt.cpp +256 -0
  54. package/MMKV/Core/aes/AESCrypt.h +107 -0
  55. package/MMKV/Core/aes/openssl/openssl_aes-armv4.S +1231 -0
  56. package/MMKV/Core/aes/openssl/openssl_aes.h +118 -0
  57. package/MMKV/Core/aes/openssl/openssl_aes_core.cpp +1044 -0
  58. package/MMKV/Core/aes/openssl/openssl_aes_locl.h +38 -0
  59. package/MMKV/Core/aes/openssl/openssl_aesv8-armx.S +308 -0
  60. package/MMKV/Core/aes/openssl/openssl_arm_arch.h +84 -0
  61. package/MMKV/Core/aes/openssl/openssl_cfb128.cpp +97 -0
  62. package/MMKV/Core/aes/openssl/openssl_md32_common.h +254 -0
  63. package/MMKV/Core/aes/openssl/openssl_md5.h +49 -0
  64. package/MMKV/Core/aes/openssl/openssl_md5_dgst.cpp +166 -0
  65. package/MMKV/Core/aes/openssl/openssl_md5_locl.h +75 -0
  66. package/MMKV/Core/aes/openssl/openssl_md5_one.cpp +30 -0
  67. package/MMKV/Core/aes/openssl/openssl_opensslconf.h +271 -0
  68. package/MMKV/Core/core.vcxproj +186 -0
  69. package/MMKV/Core/core.vcxproj.filters +150 -0
  70. package/MMKV/Core/crc32/Checksum.h +67 -0
  71. package/MMKV/Core/crc32/crc32_armv8.cpp +132 -0
  72. package/MMKV/Core/crc32/zlib/crc32.cpp +55 -0
  73. package/MMKV/Core/crc32/zlib/crc32.h +48 -0
  74. package/MMKV/Core/crc32/zlib/zconf.h +380 -0
  75. package/MMKV/Core/crc32/zlib/zutil.h +25 -0
  76. package/MMKV/LICENSE.TXT +193 -0
  77. package/MMKV/README.md +288 -0
  78. package/README.md +221 -0
  79. package/android/CMakeLists.txt +71 -0
  80. package/android/build.gradle +371 -0
  81. package/android/gradle.properties +4 -0
  82. package/android/src/main/AndroidManifest.xml +4 -0
  83. package/android/src/main/cpp/MmkvHostObject.cpp +302 -0
  84. package/android/src/main/cpp/MmkvHostObject.h +26 -0
  85. package/android/src/main/cpp/cpp-adapter.cpp +65 -0
  86. package/android/src/main/java/com/reactnativemmkv/MmkvModule.java +49 -0
  87. package/android/src/main/java/com/reactnativemmkv/MmkvPackage.java +26 -0
  88. package/cpp/TypedArray.cpp +341 -0
  89. package/cpp/TypedArray.h +175 -0
  90. package/ios/JSIUtils.h +50 -0
  91. package/ios/JSIUtils.mm +194 -0
  92. package/ios/Mmkv.xcodeproj/project.pbxproj +291 -0
  93. package/ios/MmkvHostObject.h +27 -0
  94. package/ios/MmkvHostObject.mm +299 -0
  95. package/ios/MmkvModule.h +5 -0
  96. package/ios/MmkvModule.mm +73 -0
  97. package/lib/commonjs/MMKV.js +146 -0
  98. package/lib/commonjs/MMKV.js.map +1 -0
  99. package/lib/commonjs/PlatformChecker.js +16 -0
  100. package/lib/commonjs/PlatformChecker.js.map +1 -0
  101. package/lib/commonjs/createMMKV.js +66 -0
  102. package/lib/commonjs/createMMKV.js.map +1 -0
  103. package/lib/commonjs/createMMKV.mock.js +40 -0
  104. package/lib/commonjs/createMMKV.mock.js.map +1 -0
  105. package/lib/commonjs/createMMKV.web.js +77 -0
  106. package/lib/commonjs/createMMKV.web.js.map +1 -0
  107. package/lib/commonjs/createTextEncoder.js +24 -0
  108. package/lib/commonjs/createTextEncoder.js.map +1 -0
  109. package/lib/commonjs/hooks.js +200 -0
  110. package/lib/commonjs/hooks.js.map +1 -0
  111. package/lib/commonjs/index.js +32 -0
  112. package/lib/commonjs/index.js.map +1 -0
  113. package/lib/module/MMKV.js +134 -0
  114. package/lib/module/MMKV.js.map +1 -0
  115. package/lib/module/PlatformChecker.js +9 -0
  116. package/lib/module/PlatformChecker.js.map +1 -0
  117. package/lib/module/createMMKV.js +55 -0
  118. package/lib/module/createMMKV.js.map +1 -0
  119. package/lib/module/createMMKV.mock.js +31 -0
  120. package/lib/module/createMMKV.mock.js.map +1 -0
  121. package/lib/module/createMMKV.web.js +67 -0
  122. package/lib/module/createMMKV.web.js.map +1 -0
  123. package/lib/module/createTextEncoder.js +17 -0
  124. package/lib/module/createTextEncoder.js.map +1 -0
  125. package/lib/module/hooks.js +181 -0
  126. package/lib/module/hooks.js.map +1 -0
  127. package/lib/module/index.js +3 -0
  128. package/lib/module/index.js.map +1 -0
  129. package/lib/typescript/MMKV.d.ts +137 -0
  130. package/lib/typescript/PlatformChecker.d.ts +1 -0
  131. package/lib/typescript/createMMKV.d.ts +6 -0
  132. package/lib/typescript/createMMKV.mock.d.ts +2 -0
  133. package/lib/typescript/createMMKV.web.d.ts +2 -0
  134. package/lib/typescript/createTextEncoder.d.ts +1 -0
  135. package/lib/typescript/hooks.d.ts +81 -0
  136. package/lib/typescript/index.d.ts +2 -0
  137. package/package.json +168 -0
  138. package/react-native-mmkv.podspec +32 -0
@@ -0,0 +1,302 @@
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 "TypedArray.h"
11
+ #include <MMKV.h>
12
+ #include <android/log.h>
13
+ #include <string>
14
+ #include <vector>
15
+
16
+ MmkvHostObject::MmkvHostObject(const std::string& instanceId, std::string path, std::string cryptKey) {
17
+ __android_log_print(ANDROID_LOG_INFO, "RNMMKV", "Creating MMKV instance \"%s\"... (Path: %s, Encryption-Key: %s)",
18
+ instanceId.c_str(), path.c_str(), cryptKey.c_str());
19
+ std::string* pathPtr = path.size() > 0 ? &path : nullptr;
20
+ std::string* cryptKeyPtr = cryptKey.size() > 0 ? &cryptKey : nullptr;
21
+ instance = MMKV::mmkvWithID(instanceId, mmkv::DEFAULT_MMAP_SIZE, MMKV_SINGLE_PROCESS, cryptKeyPtr, pathPtr);
22
+
23
+ if (instance == nullptr) {
24
+ // Check if instanceId is invalid
25
+ if (instanceId.empty()) {
26
+ throw std::runtime_error("Failed to create MMKV instance! `id` cannot be empty!");
27
+ }
28
+
29
+ // Check if encryptionKey is invalid
30
+ if (cryptKey.size() > 16) {
31
+ throw std::runtime_error("Failed to create MMKV instance! `encryptionKey` cannot be longer than 16 bytes!");
32
+ }
33
+
34
+ throw std::runtime_error("Failed to create MMKV instance!");
35
+ }
36
+ }
37
+
38
+ std::vector<jsi::PropNameID> MmkvHostObject::getPropertyNames(jsi::Runtime& rt) {
39
+ std::vector<jsi::PropNameID> result;
40
+ result.push_back(jsi::PropNameID::forUtf8(rt, std::string("set")));
41
+ result.push_back(jsi::PropNameID::forUtf8(rt, std::string("getBoolean")));
42
+ result.push_back(jsi::PropNameID::forUtf8(rt, std::string("getString")));
43
+ result.push_back(jsi::PropNameID::forUtf8(rt, std::string("getNumber")));
44
+ result.push_back(jsi::PropNameID::forUtf8(rt, std::string("contains")));
45
+ result.push_back(jsi::PropNameID::forUtf8(rt, std::string("delete")));
46
+ result.push_back(jsi::PropNameID::forUtf8(rt, std::string("getAllKeys")));
47
+ result.push_back(jsi::PropNameID::forUtf8(rt, std::string("deleteAll")));
48
+ result.push_back(jsi::PropNameID::forUtf8(rt, std::string("recrypt")));
49
+ return result;
50
+ }
51
+
52
+ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& propNameId) {
53
+ auto propName = propNameId.utf8(runtime);
54
+ auto funcName = "MMKV." + propName;
55
+
56
+ if (propName == "set") {
57
+ // MMKV.set(key: string, value: string | number | bool)
58
+ return jsi::Function::createFromHostFunction(runtime,
59
+ jsi::PropNameID::forAscii(runtime, funcName),
60
+ 2, // key, value
61
+ [this](jsi::Runtime& runtime,
62
+ const jsi::Value& thisValue,
63
+ const jsi::Value* arguments,
64
+ size_t count) -> jsi::Value {
65
+ if (!arguments[0].isString()) {
66
+ throw jsi::JSError(runtime, "MMKV::set: First argument ('key') has to be of type string!");
67
+ }
68
+
69
+ auto keyName = arguments[0].getString(runtime).utf8(runtime);
70
+
71
+ if (arguments[1].isBool()) {
72
+ // bool
73
+ instance->set(arguments[1].getBool(), keyName);
74
+ } else if (arguments[1].isNumber()) {
75
+ // number
76
+ instance->set(arguments[1].getNumber(), keyName);
77
+ } else if (arguments[1].isString()) {
78
+ // string
79
+ auto stringValue = arguments[1].getString(runtime).utf8(runtime);
80
+ instance->set(stringValue, keyName);
81
+ } else if (arguments[1].isObject()) {
82
+ // object
83
+ auto object = arguments[1].asObject(runtime);
84
+ if (isTypedArray(runtime, object)) {
85
+ // Uint8Array
86
+ auto typedArray = getTypedArray(runtime, object);
87
+ auto bufferValue = typedArray.getBuffer(runtime);
88
+ mmkv::MMBuffer buffer(bufferValue.data(runtime),
89
+ bufferValue.size(runtime),
90
+ mmkv::MMBufferCopyFlag::MMBufferNoCopy);
91
+ instance->set(buffer, keyName);
92
+ } else {
93
+ // unknown object
94
+ throw jsi::JSError(runtime, "MMKV::set: 'value' argument is an object, but not of type Uint8Array!");
95
+ }
96
+ } else {
97
+ // unknown type
98
+ throw jsi::JSError(runtime, "MMKV::set: 'value' argument is not of type bool, number, string or buffer!");
99
+ }
100
+
101
+ return jsi::Value::undefined();
102
+ });
103
+ }
104
+
105
+ if (propName == "getBoolean") {
106
+ // MMKV.getBoolean(key: string)
107
+ return jsi::Function::createFromHostFunction(runtime,
108
+ jsi::PropNameID::forAscii(runtime, funcName),
109
+ 1, // key
110
+ [this](jsi::Runtime& runtime,
111
+ const jsi::Value& thisValue,
112
+ const jsi::Value* arguments,
113
+ size_t count) -> jsi::Value {
114
+ if (!arguments[0].isString()) {
115
+ throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
116
+ }
117
+
118
+ auto keyName = arguments[0].getString(runtime).utf8(runtime);
119
+ bool hasValue;
120
+ auto value = instance->getBool(keyName, false, &hasValue);
121
+ if (hasValue) {
122
+ return jsi::Value(value);
123
+ } else {
124
+ return jsi::Value::undefined();
125
+ }
126
+ });
127
+ }
128
+
129
+ if (propName == "getString") {
130
+ // MMKV.getString(key: string)
131
+ return jsi::Function::createFromHostFunction(runtime,
132
+ jsi::PropNameID::forAscii(runtime, funcName),
133
+ 1, // key
134
+ [this](jsi::Runtime& runtime,
135
+ const jsi::Value& thisValue,
136
+ const jsi::Value* arguments,
137
+ size_t count) -> jsi::Value {
138
+ if (!arguments[0].isString()) {
139
+ throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
140
+ }
141
+
142
+ auto keyName = arguments[0].getString(runtime).utf8(runtime);
143
+ std::string result;
144
+ bool hasValue = instance->getString(keyName, result);
145
+ if (hasValue) {
146
+ return jsi::Value(runtime, jsi::String::createFromUtf8(runtime, result));
147
+ } else {
148
+ return jsi::Value::undefined();
149
+ }
150
+ });
151
+ }
152
+
153
+ if (propName == "getNumber") {
154
+ // MMKV.getNumber(key: string)
155
+ return jsi::Function::createFromHostFunction(runtime,
156
+ jsi::PropNameID::forAscii(runtime, funcName),
157
+ 1, // key
158
+ [this](jsi::Runtime& runtime,
159
+ const jsi::Value& thisValue,
160
+ const jsi::Value* arguments,
161
+ size_t count) -> jsi::Value {
162
+ if (!arguments[0].isString()) {
163
+ throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
164
+ }
165
+
166
+ auto keyName = arguments[0].getString(runtime).utf8(runtime);
167
+ bool hasValue;
168
+ auto value = instance->getDouble(keyName, 0.0, &hasValue);
169
+ if (hasValue) {
170
+ return jsi::Value(value);
171
+ } else {
172
+ return jsi::Value::undefined();
173
+ }
174
+ });
175
+ }
176
+
177
+
178
+ if (propName == "getBuffer") {
179
+ // MMKV.getBuffer(key: string)
180
+ return jsi::Function::createFromHostFunction(runtime,
181
+ jsi::PropNameID::forAscii(runtime, funcName),
182
+ 1, // key
183
+ [this](jsi::Runtime& runtime,
184
+ const jsi::Value& thisValue,
185
+ const jsi::Value* arguments,
186
+ size_t count) -> jsi::Value {
187
+ if (!arguments[0].isString()) {
188
+ throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
189
+ }
190
+
191
+ auto keyName = arguments[0].getString(runtime).utf8(runtime);
192
+ mmkv::MMBuffer buffer;
193
+ bool hasValue = instance->getBytes(keyName, buffer);
194
+ if (hasValue) {
195
+ auto length = buffer.length();
196
+ TypedArray<TypedArrayKind::Uint8Array> array(runtime, length);
197
+ auto data = static_cast<const unsigned char*>(buffer.getPtr());
198
+ std::vector<unsigned char> vector(length);
199
+ vector.assign(data, data + length);
200
+ array.update(runtime, vector);
201
+ return array;
202
+ } else {
203
+ return jsi::Value::undefined();
204
+ }
205
+ });
206
+ }
207
+
208
+ if (propName == "contains") {
209
+ // MMKV.contains(key: string)
210
+ return jsi::Function::createFromHostFunction(runtime,
211
+ jsi::PropNameID::forAscii(runtime, funcName),
212
+ 1, // key
213
+ [this](jsi::Runtime& runtime,
214
+ const jsi::Value& thisValue,
215
+ const jsi::Value* arguments,
216
+ size_t count) -> jsi::Value {
217
+ if (!arguments[0].isString()) {
218
+ throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
219
+ }
220
+
221
+ auto keyName = arguments[0].getString(runtime).utf8(runtime);
222
+ bool containsKey = instance->containsKey(keyName);
223
+ return jsi::Value(containsKey);
224
+ });
225
+ }
226
+
227
+ if (propName == "delete") {
228
+ // MMKV.delete(key: string)
229
+ return jsi::Function::createFromHostFunction(runtime,
230
+ jsi::PropNameID::forAscii(runtime, funcName),
231
+ 1, // key
232
+ [this](jsi::Runtime& runtime,
233
+ const jsi::Value& thisValue,
234
+ const jsi::Value* arguments,
235
+ size_t count) -> jsi::Value {
236
+ if (!arguments[0].isString()) {
237
+ throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
238
+ }
239
+
240
+ auto keyName = arguments[0].getString(runtime).utf8(runtime);
241
+ instance->removeValueForKey(keyName);
242
+ return jsi::Value::undefined();
243
+ });
244
+ }
245
+
246
+ if (propName == "getAllKeys") {
247
+ // MMKV.getAllKeys()
248
+ return jsi::Function::createFromHostFunction(runtime,
249
+ jsi::PropNameID::forAscii(runtime, funcName),
250
+ 0,
251
+ [this](jsi::Runtime& runtime,
252
+ const jsi::Value& thisValue,
253
+ const jsi::Value* arguments,
254
+ size_t count) -> jsi::Value {
255
+ auto keys = instance->allKeys();
256
+ auto array = jsi::Array(runtime, keys.size());
257
+ for (int i = 0; i < keys.size(); i++) {
258
+ array.setValueAtIndex(runtime, i, keys[i]);
259
+ }
260
+ return array;
261
+ });
262
+ }
263
+
264
+ if (propName == "clearAll") {
265
+ // MMKV.clearAll()
266
+ return jsi::Function::createFromHostFunction(runtime,
267
+ jsi::PropNameID::forAscii(runtime, funcName),
268
+ 0,
269
+ [this](jsi::Runtime& runtime,
270
+ const jsi::Value& thisValue,
271
+ const jsi::Value* arguments,
272
+ size_t count) -> jsi::Value {
273
+ instance->clearAll();
274
+ return jsi::Value::undefined();
275
+ });
276
+ }
277
+
278
+ if (propName == "recrypt") {
279
+ // MMKV.recrypt(encryptionKey)
280
+ return jsi::Function::createFromHostFunction(runtime,
281
+ jsi::PropNameID::forAscii(runtime, funcName),
282
+ 1, // encryptionKey
283
+ [this](jsi::Runtime& runtime,
284
+ const jsi::Value& thisValue,
285
+ const jsi::Value* arguments,
286
+ size_t count) -> jsi::Value {
287
+ if (arguments[0].isUndefined()) {
288
+ // reset encryption key to "no encryption"
289
+ instance->reKey(std::string());
290
+ } else if (arguments[0].isString()) {
291
+ // reKey(..) with new encryption-key
292
+ auto encryptionKey = arguments[0].getString(runtime).utf8(runtime);
293
+ instance->reKey(encryptionKey);
294
+ } else {
295
+ throw jsi::JSError(runtime, "First argument ('encryptionKey') has to be of type string (or undefined)!");
296
+ }
297
+ return jsi::Value::undefined();
298
+ });
299
+ }
300
+
301
+ return jsi::Value::undefined();
302
+ }
@@ -0,0 +1,26 @@
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 <jsi/jsi.h>
12
+ #include <MMKV.h>
13
+
14
+ using namespace facebook;
15
+
16
+ class JSI_EXPORT MmkvHostObject: public jsi::HostObject {
17
+ public:
18
+ MmkvHostObject(const std::string& instanceId, std::string path, std::string cryptKey);
19
+
20
+ public:
21
+ jsi::Value get(jsi::Runtime&, const jsi::PropNameID& name) override;
22
+ std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& rt) override;
23
+
24
+ private:
25
+ MMKV* instance;
26
+ };
@@ -0,0 +1,65 @@
1
+ #include <jni.h>
2
+ #include <jsi/jsi.h>
3
+ #include <MMKV.h>
4
+ #include "MmkvHostObject.h"
5
+
6
+ using namespace facebook;
7
+
8
+ std::string getPropertyAsStringOrEmptyFromObject(jsi::Object& object, const std::string& propertyName, jsi::Runtime& runtime) {
9
+ jsi::Value value = object.getProperty(runtime, propertyName.c_str());
10
+ return value.isString() ? value.asString(runtime).utf8(runtime) : "";
11
+ }
12
+
13
+ void install(jsi::Runtime& jsiRuntime) {
14
+ // MMKV.createNewInstance()
15
+ auto mmkvCreateNewInstance = jsi::Function::createFromHostFunction(jsiRuntime,
16
+ jsi::PropNameID::forAscii(jsiRuntime, "mmkvCreateNewInstance"),
17
+ 1,
18
+ [](jsi::Runtime& runtime,
19
+ const jsi::Value& thisValue,
20
+ const jsi::Value* arguments,
21
+ size_t count) -> jsi::Value {
22
+ if (count != 1) {
23
+ throw jsi::JSError(runtime, "MMKV.createNewInstance(..) expects one argument (object)!");
24
+ }
25
+ jsi::Object config = arguments[0].asObject(runtime);
26
+
27
+ std::string instanceId = getPropertyAsStringOrEmptyFromObject(config, "id", runtime);
28
+ std::string path = getPropertyAsStringOrEmptyFromObject(config, "path", runtime);
29
+ std::string encryptionKey = getPropertyAsStringOrEmptyFromObject(config, "encryptionKey", runtime);
30
+
31
+ auto instance = std::make_shared<MmkvHostObject>(instanceId, path, encryptionKey);
32
+ return jsi::Object::createFromHostObject(runtime, instance);
33
+ });
34
+ jsiRuntime.global().setProperty(jsiRuntime, "mmkvCreateNewInstance", std::move(mmkvCreateNewInstance));
35
+ }
36
+
37
+ std::string jstringToStdString(JNIEnv *env, jstring jStr) {
38
+ if (!jStr) return "";
39
+
40
+ const auto stringClass = env->GetObjectClass(jStr);
41
+ const auto getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
42
+ const auto stringJbytes = (jbyteArray) env->CallObjectMethod(jStr, getBytes, env->NewStringUTF("UTF-8"));
43
+
44
+ auto length = (size_t) env->GetArrayLength(stringJbytes);
45
+ auto pBytes = env->GetByteArrayElements(stringJbytes, nullptr);
46
+
47
+ std::string ret = std::string((char *)pBytes, length);
48
+ env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
49
+
50
+ env->DeleteLocalRef(stringJbytes);
51
+ env->DeleteLocalRef(stringClass);
52
+ return ret;
53
+ }
54
+
55
+ extern "C"
56
+ JNIEXPORT void JNICALL
57
+ Java_com_reactnativemmkv_MmkvModule_nativeInstall(JNIEnv *env, jobject clazz, jlong jsiPtr, jstring path) {
58
+ MMKV::initializeMMKV(jstringToStdString(env, path));
59
+
60
+ auto runtime = reinterpret_cast<jsi::Runtime*>(jsiPtr);
61
+ if (runtime) {
62
+ install(*runtime);
63
+ }
64
+ // if runtime was nullptr, MMKV will not be installed. This should only happen while Remote Debugging (Chrome), but will be weird either way.
65
+ }
@@ -0,0 +1,49 @@
1
+ package com.reactnativemmkv;
2
+
3
+ import android.util.Log;
4
+
5
+ import androidx.annotation.NonNull;
6
+ import androidx.annotation.Nullable;
7
+
8
+ import com.facebook.react.bridge.JavaScriptContextHolder;
9
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
10
+ import com.facebook.react.bridge.ReactApplicationContext;
11
+ import com.facebook.react.bridge.ReactMethod;
12
+ import com.facebook.react.module.annotations.ReactModule;
13
+
14
+ @ReactModule(name = MmkvModule.NAME)
15
+ public class MmkvModule extends ReactContextBaseJavaModule {
16
+ public static final String NAME = "MMKV";
17
+
18
+ public MmkvModule(ReactApplicationContext reactContext) {
19
+ super(reactContext);
20
+ }
21
+
22
+ @NonNull
23
+ @Override
24
+ public String getName() {
25
+ return NAME;
26
+ }
27
+
28
+ @ReactMethod(isBlockingSynchronousMethod = true)
29
+ public boolean install(@Nullable String rootDirectory) {
30
+ try {
31
+ Log.i(NAME, "Loading C++ library...");
32
+ System.loadLibrary("reactnativemmkv");
33
+
34
+ JavaScriptContextHolder jsContext = getReactApplicationContext().getJavaScriptContextHolder();
35
+ if (rootDirectory == null) {
36
+ rootDirectory = getReactApplicationContext().getFilesDir().getAbsolutePath() + "/mmkv";
37
+ }
38
+ Log.i(NAME, "Installing MMKV JSI Bindings for MMKV root directory: " + rootDirectory);
39
+ nativeInstall(jsContext.get(), rootDirectory);
40
+ Log.i(NAME, "Successfully installed MMKV JSI Bindings!");
41
+ return true;
42
+ } catch (Exception exception) {
43
+ Log.e(NAME, "Failed to install MMKV JSI Bindings!", exception);
44
+ return false;
45
+ }
46
+ }
47
+
48
+ private static native void nativeInstall(long jsiPtr, String path);
49
+ }
@@ -0,0 +1,26 @@
1
+ package com.reactnativemmkv;
2
+
3
+ import androidx.annotation.NonNull;
4
+
5
+ import com.facebook.react.ReactPackage;
6
+ import com.facebook.react.bridge.NativeModule;
7
+ import com.facebook.react.bridge.ReactApplicationContext;
8
+ import com.facebook.react.uimanager.ViewManager;
9
+
10
+ import java.util.Collections;
11
+ import java.util.List;
12
+
13
+
14
+ public class MmkvPackage implements ReactPackage {
15
+ @NonNull
16
+ @Override
17
+ public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
18
+ return Collections.singletonList(new MmkvModule(reactContext));
19
+ }
20
+
21
+ @NonNull
22
+ @Override
23
+ public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
24
+ return Collections.emptyList();
25
+ }
26
+ }