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.
- package/LICENSE +219 -0
- package/MMKV/CHANGELOG.md +553 -0
- package/MMKV/Core/CMakeLists.txt +153 -0
- package/MMKV/Core/CodedInputData.cpp +228 -0
- package/MMKV/Core/CodedInputData.h +83 -0
- package/MMKV/Core/CodedInputDataCrypt.cpp +280 -0
- package/MMKV/Core/CodedInputDataCrypt.h +87 -0
- package/MMKV/Core/CodedInputDataCrypt_OSX.cpp +62 -0
- package/MMKV/Core/CodedInputData_OSX.cpp +92 -0
- package/MMKV/Core/CodedOutputData.cpp +174 -0
- package/MMKV/Core/CodedOutputData.h +82 -0
- package/MMKV/Core/Core.xcodeproj/project.pbxproj +702 -0
- package/MMKV/Core/Core.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/MMKV/Core/Core.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/Core.xcscheme +67 -0
- package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/MMKVWatchCore.xcscheme +67 -0
- package/MMKV/Core/InterProcessLock.cpp +186 -0
- package/MMKV/Core/InterProcessLock.h +119 -0
- package/MMKV/Core/InterProcessLock_Android.cpp +103 -0
- package/MMKV/Core/InterProcessLock_Win32.cpp +108 -0
- package/MMKV/Core/KeyValueHolder.cpp +236 -0
- package/MMKV/Core/KeyValueHolder.h +118 -0
- package/MMKV/Core/MMBuffer.cpp +185 -0
- package/MMKV/Core/MMBuffer.h +107 -0
- package/MMKV/Core/MMKV.cpp +1418 -0
- package/MMKV/Core/MMKV.h +386 -0
- package/MMKV/Core/MMKVLog.cpp +127 -0
- package/MMKV/Core/MMKVLog.h +86 -0
- package/MMKV/Core/MMKVLog_Android.cpp +79 -0
- package/MMKV/Core/MMKVMetaInfo.hpp +81 -0
- package/MMKV/Core/MMKVPredef.h +245 -0
- package/MMKV/Core/MMKV_Android.cpp +259 -0
- package/MMKV/Core/MMKV_IO.cpp +1119 -0
- package/MMKV/Core/MMKV_IO.h +57 -0
- package/MMKV/Core/MMKV_OSX.cpp +347 -0
- package/MMKV/Core/MMKV_OSX.h +51 -0
- package/MMKV/Core/MemoryFile.cpp +537 -0
- package/MMKV/Core/MemoryFile.h +182 -0
- package/MMKV/Core/MemoryFile_Android.cpp +211 -0
- package/MMKV/Core/MemoryFile_Linux.cpp +120 -0
- package/MMKV/Core/MemoryFile_OSX.cpp +142 -0
- package/MMKV/Core/MemoryFile_Win32.cpp +536 -0
- package/MMKV/Core/MiniPBCoder.cpp +366 -0
- package/MMKV/Core/MiniPBCoder.h +129 -0
- package/MMKV/Core/MiniPBCoder_OSX.cpp +228 -0
- package/MMKV/Core/PBEncodeItem.hpp +86 -0
- package/MMKV/Core/PBUtility.cpp +61 -0
- package/MMKV/Core/PBUtility.h +153 -0
- package/MMKV/Core/ScopedLock.hpp +69 -0
- package/MMKV/Core/ThreadLock.cpp +68 -0
- package/MMKV/Core/ThreadLock.h +78 -0
- package/MMKV/Core/ThreadLock_Win32.cpp +89 -0
- package/MMKV/Core/aes/AESCrypt.cpp +256 -0
- package/MMKV/Core/aes/AESCrypt.h +107 -0
- package/MMKV/Core/aes/openssl/openssl_aes-armv4.S +1231 -0
- package/MMKV/Core/aes/openssl/openssl_aes.h +118 -0
- package/MMKV/Core/aes/openssl/openssl_aes_core.cpp +1044 -0
- package/MMKV/Core/aes/openssl/openssl_aes_locl.h +38 -0
- package/MMKV/Core/aes/openssl/openssl_aesv8-armx.S +308 -0
- package/MMKV/Core/aes/openssl/openssl_arm_arch.h +84 -0
- package/MMKV/Core/aes/openssl/openssl_cfb128.cpp +97 -0
- package/MMKV/Core/aes/openssl/openssl_md32_common.h +254 -0
- package/MMKV/Core/aes/openssl/openssl_md5.h +49 -0
- package/MMKV/Core/aes/openssl/openssl_md5_dgst.cpp +166 -0
- package/MMKV/Core/aes/openssl/openssl_md5_locl.h +75 -0
- package/MMKV/Core/aes/openssl/openssl_md5_one.cpp +30 -0
- package/MMKV/Core/aes/openssl/openssl_opensslconf.h +271 -0
- package/MMKV/Core/core.vcxproj +186 -0
- package/MMKV/Core/core.vcxproj.filters +150 -0
- package/MMKV/Core/crc32/Checksum.h +67 -0
- package/MMKV/Core/crc32/crc32_armv8.cpp +132 -0
- package/MMKV/Core/crc32/zlib/crc32.cpp +55 -0
- package/MMKV/Core/crc32/zlib/crc32.h +48 -0
- package/MMKV/Core/crc32/zlib/zconf.h +380 -0
- package/MMKV/Core/crc32/zlib/zutil.h +25 -0
- package/MMKV/LICENSE.TXT +193 -0
- package/MMKV/README.md +288 -0
- package/README.md +221 -0
- package/android/CMakeLists.txt +71 -0
- package/android/build.gradle +371 -0
- package/android/gradle.properties +4 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/cpp/MmkvHostObject.cpp +302 -0
- package/android/src/main/cpp/MmkvHostObject.h +26 -0
- package/android/src/main/cpp/cpp-adapter.cpp +65 -0
- package/android/src/main/java/com/reactnativemmkv/MmkvModule.java +49 -0
- package/android/src/main/java/com/reactnativemmkv/MmkvPackage.java +26 -0
- package/cpp/TypedArray.cpp +341 -0
- package/cpp/TypedArray.h +175 -0
- package/ios/JSIUtils.h +50 -0
- package/ios/JSIUtils.mm +194 -0
- package/ios/Mmkv.xcodeproj/project.pbxproj +291 -0
- package/ios/MmkvHostObject.h +27 -0
- package/ios/MmkvHostObject.mm +299 -0
- package/ios/MmkvModule.h +5 -0
- package/ios/MmkvModule.mm +73 -0
- package/lib/commonjs/MMKV.js +146 -0
- package/lib/commonjs/MMKV.js.map +1 -0
- package/lib/commonjs/PlatformChecker.js +16 -0
- package/lib/commonjs/PlatformChecker.js.map +1 -0
- package/lib/commonjs/createMMKV.js +66 -0
- package/lib/commonjs/createMMKV.js.map +1 -0
- package/lib/commonjs/createMMKV.mock.js +40 -0
- package/lib/commonjs/createMMKV.mock.js.map +1 -0
- package/lib/commonjs/createMMKV.web.js +77 -0
- package/lib/commonjs/createMMKV.web.js.map +1 -0
- package/lib/commonjs/createTextEncoder.js +24 -0
- package/lib/commonjs/createTextEncoder.js.map +1 -0
- package/lib/commonjs/hooks.js +200 -0
- package/lib/commonjs/hooks.js.map +1 -0
- package/lib/commonjs/index.js +32 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/module/MMKV.js +134 -0
- package/lib/module/MMKV.js.map +1 -0
- package/lib/module/PlatformChecker.js +9 -0
- package/lib/module/PlatformChecker.js.map +1 -0
- package/lib/module/createMMKV.js +55 -0
- package/lib/module/createMMKV.js.map +1 -0
- package/lib/module/createMMKV.mock.js +31 -0
- package/lib/module/createMMKV.mock.js.map +1 -0
- package/lib/module/createMMKV.web.js +67 -0
- package/lib/module/createMMKV.web.js.map +1 -0
- package/lib/module/createTextEncoder.js +17 -0
- package/lib/module/createTextEncoder.js.map +1 -0
- package/lib/module/hooks.js +181 -0
- package/lib/module/hooks.js.map +1 -0
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -0
- package/lib/typescript/MMKV.d.ts +137 -0
- package/lib/typescript/PlatformChecker.d.ts +1 -0
- package/lib/typescript/createMMKV.d.ts +6 -0
- package/lib/typescript/createMMKV.mock.d.ts +2 -0
- package/lib/typescript/createMMKV.web.d.ts +2 -0
- package/lib/typescript/createTextEncoder.d.ts +1 -0
- package/lib/typescript/hooks.d.ts +81 -0
- package/lib/typescript/index.d.ts +2 -0
- package/package.json +168 -0
- 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
|
+
}
|