react-native-mmkv 2.10.2 → 2.12.0
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/MMKV/Core/CodedInputData.cpp +28 -4
- package/MMKV/Core/CodedInputData.h +5 -1
- package/MMKV/Core/CodedOutputData.cpp +12 -0
- package/MMKV/Core/CodedOutputData.h +6 -0
- package/MMKV/Core/MMBuffer.cpp +7 -0
- package/MMKV/Core/MMBuffer.h +3 -0
- package/MMKV/Core/MMKV.cpp +114 -19
- package/MMKV/Core/MMKV.h +69 -33
- package/MMKV/Core/MMKVPredef.h +1 -1
- package/MMKV/Core/MMKV_Android.cpp +10 -8
- package/MMKV/Core/MMKV_IO.cpp +386 -60
- package/MMKV/Core/MMKV_OSX.cpp +51 -30
- package/MMKV/Core/MMKV_OSX.h +10 -4
- package/MMKV/Core/MemoryFile.cpp +31 -11
- package/MMKV/Core/MemoryFile.h +8 -3
- package/MMKV/Core/MemoryFile_Android.cpp +2 -2
- package/MMKV/Core/MemoryFile_OSX.cpp +2 -3
- package/MMKV/Core/MemoryFile_Win32.cpp +8 -5
- package/MMKV/Core/MiniPBCoder.cpp +11 -0
- package/MMKV/Core/MiniPBCoder.h +3 -0
- package/MMKV/Core/MiniPBCoder_OSX.cpp +8 -0
- package/MMKV/Core/ThreadLock.cpp +5 -0
- package/MMKV/Core/ThreadLock.h +4 -0
- package/MMKV/Core/aes/openssl/openssl_aes-armv4.S +8 -0
- package/MMKV/Core/core.vcxproj +3 -3
- package/MMKV/README.md +3 -3
- package/README.md +9 -1
- package/android/build.gradle +21 -1
- package/android/src/hasNamespace/AndroidManifest.xml +3 -0
- package/android/src/main/cpp/MmkvHostObject.cpp +191 -204
- package/android/src/main/cpp/MmkvHostObject.h +2 -2
- package/android/src/main/cpp/cpp-adapter.cpp +62 -49
- package/cpp/TypedArray.cpp +69 -76
- package/cpp/TypedArray.h +66 -91
- package/img/banner-dark.png +0 -0
- package/img/banner-light.png +0 -0
- package/ios/JSIUtils.h +27 -39
- package/ios/JSIUtils.mm +110 -138
- package/ios/MmkvHostObject.h +2 -2
- package/ios/MmkvHostObject.mm +188 -205
- package/ios/MmkvModule.mm +68 -52
- package/lib/commonjs/createMMKV.web.js +1 -1
- package/lib/commonjs/createMMKV.web.js.map +1 -1
- package/lib/commonjs/hooks.js +16 -13
- package/lib/commonjs/hooks.js.map +1 -1
- package/lib/module/createMMKV.web.js +1 -1
- package/lib/module/createMMKV.web.js.map +1 -1
- package/lib/module/hooks.js +16 -13
- package/lib/module/hooks.js.map +1 -1
- package/lib/typescript/createMMKV.web.d.ts.map +1 -1
- package/lib/typescript/hooks.d.ts.map +1 -1
- package/package.json +13 -3
- package/react-native-mmkv.podspec +1 -1
- package/src/createMMKV.web.ts +4 -2
- package/src/hooks.ts +19 -16
- package/MMKV/LICENSE.TXT +0 -193
|
@@ -13,12 +13,16 @@
|
|
|
13
13
|
#include <string>
|
|
14
14
|
#include <vector>
|
|
15
15
|
|
|
16
|
-
MmkvHostObject::MmkvHostObject(const std::string& instanceId, std::string path,
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
MmkvHostObject::MmkvHostObject(const std::string& instanceId, std::string path,
|
|
17
|
+
std::string cryptKey) {
|
|
18
|
+
bool hasEncryptionKey = cryptKey.size() > 0;
|
|
19
|
+
__android_log_print(ANDROID_LOG_INFO, "RNMMKV",
|
|
20
|
+
"Creating MMKV instance \"%s\"... (Path: %s, Encrypted: %b)",
|
|
21
|
+
instanceId.c_str(), path.c_str(), hasEncryptionKey);
|
|
19
22
|
std::string* pathPtr = path.size() > 0 ? &path : nullptr;
|
|
20
23
|
std::string* cryptKeyPtr = cryptKey.size() > 0 ? &cryptKey : nullptr;
|
|
21
|
-
instance = MMKV::mmkvWithID(instanceId, mmkv::DEFAULT_MMAP_SIZE, MMKV_SINGLE_PROCESS, cryptKeyPtr,
|
|
24
|
+
instance = MMKV::mmkvWithID(instanceId, mmkv::DEFAULT_MMAP_SIZE, MMKV_SINGLE_PROCESS, cryptKeyPtr,
|
|
25
|
+
pathPtr);
|
|
22
26
|
|
|
23
27
|
if (instance == nullptr) {
|
|
24
28
|
// Check if instanceId is invalid
|
|
@@ -28,7 +32,8 @@ MmkvHostObject::MmkvHostObject(const std::string& instanceId, std::string path,
|
|
|
28
32
|
|
|
29
33
|
// Check if encryptionKey is invalid
|
|
30
34
|
if (cryptKey.size() > 16) {
|
|
31
|
-
throw std::runtime_error(
|
|
35
|
+
throw std::runtime_error(
|
|
36
|
+
"Failed to create MMKV instance! `encryptionKey` cannot be longer than 16 bytes!");
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
throw std::runtime_error("Failed to create MMKV instance!");
|
|
@@ -56,247 +61,229 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
56
61
|
|
|
57
62
|
if (propName == "set") {
|
|
58
63
|
// MMKV.set(key: string, value: string | number | bool | Uint8Array)
|
|
59
|
-
return jsi::Function::createFromHostFunction(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
64
|
+
return jsi::Function::createFromHostFunction(
|
|
65
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
66
|
+
2, // key, value
|
|
67
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
68
|
+
size_t count) -> jsi::Value {
|
|
69
|
+
if (!arguments[0].isString()) {
|
|
70
|
+
throw jsi::JSError(runtime,
|
|
71
|
+
"MMKV::set: First argument ('key') has to be of type string!");
|
|
72
|
+
}
|
|
69
73
|
|
|
70
|
-
|
|
74
|
+
auto keyName = arguments[0].getString(runtime).utf8(runtime);
|
|
71
75
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
76
|
+
if (arguments[1].isBool()) {
|
|
77
|
+
// bool
|
|
78
|
+
instance->set(arguments[1].getBool(), keyName);
|
|
79
|
+
} else if (arguments[1].isNumber()) {
|
|
80
|
+
// number
|
|
81
|
+
instance->set(arguments[1].getNumber(), keyName);
|
|
82
|
+
} else if (arguments[1].isString()) {
|
|
83
|
+
// string
|
|
84
|
+
auto stringValue = arguments[1].getString(runtime).utf8(runtime);
|
|
85
|
+
instance->set(stringValue, keyName);
|
|
86
|
+
} else if (arguments[1].isObject()) {
|
|
87
|
+
// object
|
|
88
|
+
auto object = arguments[1].asObject(runtime);
|
|
89
|
+
if (isTypedArray(runtime, object)) {
|
|
90
|
+
// Uint8Array
|
|
91
|
+
auto typedArray = getTypedArray(runtime, object);
|
|
92
|
+
auto bufferValue = typedArray.getBuffer(runtime);
|
|
93
|
+
mmkv::MMBuffer buffer(bufferValue.data(runtime), bufferValue.size(runtime),
|
|
94
|
+
mmkv::MMBufferCopyFlag::MMBufferNoCopy);
|
|
95
|
+
instance->set(buffer, keyName);
|
|
96
|
+
} else {
|
|
97
|
+
// unknown object
|
|
98
|
+
throw jsi::JSError(
|
|
99
|
+
runtime, "MMKV::set: 'value' argument is an object, but not of type Uint8Array!");
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
// unknown type
|
|
103
|
+
throw jsi::JSError(
|
|
104
|
+
runtime,
|
|
105
|
+
"MMKV::set: 'value' argument is not of type bool, number, string or buffer!");
|
|
106
|
+
}
|
|
101
107
|
|
|
102
|
-
|
|
103
|
-
|
|
108
|
+
return jsi::Value::undefined();
|
|
109
|
+
});
|
|
104
110
|
}
|
|
105
111
|
|
|
106
112
|
if (propName == "getBoolean") {
|
|
107
113
|
// MMKV.getBoolean(key: string)
|
|
108
|
-
return jsi::Function::createFromHostFunction(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
117
|
-
}
|
|
114
|
+
return jsi::Function::createFromHostFunction(
|
|
115
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
116
|
+
1, // key
|
|
117
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
118
|
+
size_t count) -> jsi::Value {
|
|
119
|
+
if (!arguments[0].isString()) {
|
|
120
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
121
|
+
}
|
|
118
122
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
123
|
+
auto keyName = arguments[0].getString(runtime).utf8(runtime);
|
|
124
|
+
bool hasValue;
|
|
125
|
+
auto value = instance->getBool(keyName, false, &hasValue);
|
|
126
|
+
if (hasValue) {
|
|
127
|
+
return jsi::Value(value);
|
|
128
|
+
} else {
|
|
129
|
+
return jsi::Value::undefined();
|
|
130
|
+
}
|
|
131
|
+
});
|
|
128
132
|
}
|
|
129
133
|
|
|
130
134
|
if (propName == "getString") {
|
|
131
135
|
// MMKV.getString(key: string)
|
|
132
|
-
return jsi::Function::createFromHostFunction(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
141
|
-
}
|
|
136
|
+
return jsi::Function::createFromHostFunction(
|
|
137
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
138
|
+
1, // key
|
|
139
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
140
|
+
size_t count) -> jsi::Value {
|
|
141
|
+
if (!arguments[0].isString()) {
|
|
142
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
143
|
+
}
|
|
142
144
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
145
|
+
auto keyName = arguments[0].getString(runtime).utf8(runtime);
|
|
146
|
+
std::string result;
|
|
147
|
+
bool hasValue = instance->getString(keyName, result);
|
|
148
|
+
if (hasValue) {
|
|
149
|
+
return jsi::Value(runtime, jsi::String::createFromUtf8(runtime, result));
|
|
150
|
+
} else {
|
|
151
|
+
return jsi::Value::undefined();
|
|
152
|
+
}
|
|
153
|
+
});
|
|
152
154
|
}
|
|
153
155
|
|
|
154
156
|
if (propName == "getNumber") {
|
|
155
157
|
// MMKV.getNumber(key: string)
|
|
156
|
-
return jsi::Function::createFromHostFunction(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
165
|
-
}
|
|
158
|
+
return jsi::Function::createFromHostFunction(
|
|
159
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
160
|
+
1, // key
|
|
161
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
162
|
+
size_t count) -> jsi::Value {
|
|
163
|
+
if (!arguments[0].isString()) {
|
|
164
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
165
|
+
}
|
|
166
166
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
167
|
+
auto keyName = arguments[0].getString(runtime).utf8(runtime);
|
|
168
|
+
bool hasValue;
|
|
169
|
+
auto value = instance->getDouble(keyName, 0.0, &hasValue);
|
|
170
|
+
if (hasValue) {
|
|
171
|
+
return jsi::Value(value);
|
|
172
|
+
} else {
|
|
173
|
+
return jsi::Value::undefined();
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
if (propName == "getBuffer") {
|
|
179
|
+
// MMKV.getBuffer(key: string)
|
|
180
|
+
return jsi::Function::createFromHostFunction(
|
|
181
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
182
|
+
1, // key
|
|
183
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
184
|
+
size_t count) -> jsi::Value {
|
|
185
|
+
if (!arguments[0].isString()) {
|
|
186
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
187
|
+
}
|
|
178
188
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
if (hasValue) {
|
|
196
|
-
auto length = buffer.length();
|
|
197
|
-
TypedArray<TypedArrayKind::Uint8Array> array(runtime, length);
|
|
198
|
-
auto data = static_cast<const unsigned char*>(buffer.getPtr());
|
|
199
|
-
std::vector<unsigned char> vector(length);
|
|
200
|
-
vector.assign(data, data + length);
|
|
201
|
-
array.update(runtime, vector);
|
|
202
|
-
return array;
|
|
203
|
-
} else {
|
|
204
|
-
return jsi::Value::undefined();
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
}
|
|
189
|
+
auto keyName = arguments[0].getString(runtime).utf8(runtime);
|
|
190
|
+
mmkv::MMBuffer buffer;
|
|
191
|
+
bool hasValue = instance->getBytes(keyName, buffer);
|
|
192
|
+
if (hasValue) {
|
|
193
|
+
auto length = buffer.length();
|
|
194
|
+
TypedArray<TypedArrayKind::Uint8Array> array(runtime, length);
|
|
195
|
+
auto data = static_cast<const unsigned char*>(buffer.getPtr());
|
|
196
|
+
std::vector<unsigned char> vector(length);
|
|
197
|
+
vector.assign(data, data + length);
|
|
198
|
+
array.update(runtime, vector);
|
|
199
|
+
return array;
|
|
200
|
+
} else {
|
|
201
|
+
return jsi::Value::undefined();
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
208
205
|
|
|
209
206
|
if (propName == "contains") {
|
|
210
207
|
// MMKV.contains(key: string)
|
|
211
|
-
return jsi::Function::createFromHostFunction(
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
220
|
-
}
|
|
208
|
+
return jsi::Function::createFromHostFunction(
|
|
209
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
210
|
+
1, // key
|
|
211
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
212
|
+
size_t count) -> jsi::Value {
|
|
213
|
+
if (!arguments[0].isString()) {
|
|
214
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
215
|
+
}
|
|
221
216
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
217
|
+
auto keyName = arguments[0].getString(runtime).utf8(runtime);
|
|
218
|
+
bool containsKey = instance->containsKey(keyName);
|
|
219
|
+
return jsi::Value(containsKey);
|
|
220
|
+
});
|
|
226
221
|
}
|
|
227
222
|
|
|
228
223
|
if (propName == "delete") {
|
|
229
224
|
// MMKV.delete(key: string)
|
|
230
|
-
return jsi::Function::createFromHostFunction(
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
239
|
-
}
|
|
225
|
+
return jsi::Function::createFromHostFunction(
|
|
226
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
227
|
+
1, // key
|
|
228
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
229
|
+
size_t count) -> jsi::Value {
|
|
230
|
+
if (!arguments[0].isString()) {
|
|
231
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
232
|
+
}
|
|
240
233
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
234
|
+
auto keyName = arguments[0].getString(runtime).utf8(runtime);
|
|
235
|
+
instance->removeValueForKey(keyName);
|
|
236
|
+
return jsi::Value::undefined();
|
|
237
|
+
});
|
|
245
238
|
}
|
|
246
239
|
|
|
247
240
|
if (propName == "getAllKeys") {
|
|
248
241
|
// MMKV.getAllKeys()
|
|
249
|
-
return jsi::Function::createFromHostFunction(
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
return array;
|
|
262
|
-
});
|
|
242
|
+
return jsi::Function::createFromHostFunction(
|
|
243
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName), 0,
|
|
244
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
245
|
+
size_t count) -> jsi::Value {
|
|
246
|
+
auto keys = instance->allKeys();
|
|
247
|
+
auto array = jsi::Array(runtime, keys.size());
|
|
248
|
+
for (int i = 0; i < keys.size(); i++) {
|
|
249
|
+
array.setValueAtIndex(runtime, i, keys[i]);
|
|
250
|
+
}
|
|
251
|
+
return array;
|
|
252
|
+
});
|
|
263
253
|
}
|
|
264
254
|
|
|
265
255
|
if (propName == "clearAll") {
|
|
266
256
|
// MMKV.clearAll()
|
|
267
|
-
return jsi::Function::createFromHostFunction(
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
instance->clearAll();
|
|
275
|
-
return jsi::Value::undefined();
|
|
276
|
-
});
|
|
257
|
+
return jsi::Function::createFromHostFunction(
|
|
258
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName), 0,
|
|
259
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
260
|
+
size_t count) -> jsi::Value {
|
|
261
|
+
instance->clearAll();
|
|
262
|
+
return jsi::Value::undefined();
|
|
263
|
+
});
|
|
277
264
|
}
|
|
278
265
|
|
|
279
266
|
if (propName == "recrypt") {
|
|
280
267
|
// MMKV.recrypt(encryptionKey)
|
|
281
|
-
return jsi::Function::createFromHostFunction(
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
268
|
+
return jsi::Function::createFromHostFunction(
|
|
269
|
+
runtime, jsi::PropNameID::forAscii(runtime, funcName),
|
|
270
|
+
1, // encryptionKey
|
|
271
|
+
[this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments,
|
|
272
|
+
size_t count) -> jsi::Value {
|
|
273
|
+
if (arguments[0].isUndefined()) {
|
|
274
|
+
// reset encryption key to "no encryption"
|
|
275
|
+
instance->reKey(std::string());
|
|
276
|
+
} else if (arguments[0].isString()) {
|
|
277
|
+
// reKey(..) with new encryption-key
|
|
278
|
+
auto encryptionKey = arguments[0].getString(runtime).utf8(runtime);
|
|
279
|
+
instance->reKey(encryptionKey);
|
|
280
|
+
} else {
|
|
281
|
+
throw jsi::JSError(
|
|
282
|
+
runtime,
|
|
283
|
+
"First argument ('encryptionKey') has to be of type string (or undefined)!");
|
|
284
|
+
}
|
|
285
|
+
return jsi::Value::undefined();
|
|
286
|
+
});
|
|
300
287
|
}
|
|
301
288
|
|
|
302
289
|
return jsi::Value::undefined();
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
|
|
9
9
|
#pragma once
|
|
10
10
|
|
|
11
|
-
#include <jsi/jsi.h>
|
|
12
11
|
#include <MMKV.h>
|
|
12
|
+
#include <jsi/jsi.h>
|
|
13
13
|
|
|
14
14
|
using namespace facebook;
|
|
15
15
|
|
|
16
|
-
class JSI_EXPORT MmkvHostObject: public jsi::HostObject {
|
|
16
|
+
class JSI_EXPORT MmkvHostObject : public jsi::HostObject {
|
|
17
17
|
public:
|
|
18
18
|
MmkvHostObject(const std::string& instanceId, std::string path, std::string cryptKey);
|
|
19
19
|
|
|
@@ -1,70 +1,83 @@
|
|
|
1
|
-
#include <jni.h>
|
|
2
|
-
#include <jsi/jsi.h>
|
|
3
|
-
#include <MMKV.h>
|
|
4
1
|
#include "MmkvHostObject.h"
|
|
5
2
|
#include "TypedArray.h"
|
|
3
|
+
#include <MMKV.h>
|
|
4
|
+
#include <jni.h>
|
|
5
|
+
#include <jsi/jsi.h>
|
|
6
6
|
|
|
7
7
|
using namespace facebook;
|
|
8
8
|
|
|
9
|
-
std::string getPropertyAsStringOrEmptyFromObject(jsi::Object& object,
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
std::string getPropertyAsStringOrEmptyFromObject(jsi::Object& object,
|
|
10
|
+
const std::string& propertyName,
|
|
11
|
+
jsi::Runtime& runtime) {
|
|
12
|
+
jsi::Value value = object.getProperty(runtime, propertyName.c_str());
|
|
13
|
+
return value.isString() ? value.asString(runtime).utf8(runtime) : "";
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
void install(jsi::Runtime& jsiRuntime) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
throw jsi::JSError(runtime, "MMKV.createNewInstance(..) expects one argument (object)!");
|
|
25
|
-
}
|
|
26
|
-
jsi::Object config = arguments[0].asObject(runtime);
|
|
17
|
+
// MMKV.createNewInstance()
|
|
18
|
+
auto mmkvCreateNewInstance = jsi::Function::createFromHostFunction(
|
|
19
|
+
jsiRuntime, jsi::PropNameID::forAscii(jsiRuntime, "mmkvCreateNewInstance"), 1,
|
|
20
|
+
[](jsi::Runtime& runtime, const jsi::Value& thisValue, 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);
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
std::string instanceId = getPropertyAsStringOrEmptyFromObject(config, "id", runtime);
|
|
28
|
+
std::string path = getPropertyAsStringOrEmptyFromObject(config, "path", runtime);
|
|
29
|
+
std::string encryptionKey =
|
|
30
|
+
getPropertyAsStringOrEmptyFromObject(config, "encryptionKey", runtime);
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
auto instance = std::make_shared<MmkvHostObject>(instanceId, path, encryptionKey);
|
|
33
|
+
return jsi::Object::createFromHostObject(runtime, instance);
|
|
34
|
+
});
|
|
35
|
+
jsiRuntime.global().setProperty(jsiRuntime, "mmkvCreateNewInstance",
|
|
36
|
+
std::move(mmkvCreateNewInstance));
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
// Adds the PropNameIDCache object to the Runtime. If the Runtime gets destroyed, the Object gets
|
|
39
|
+
// destroyed and the cache gets invalidated.
|
|
40
|
+
auto propNameIdCache = std::make_shared<InvalidateCacheOnDestroy>(jsiRuntime);
|
|
41
|
+
jsiRuntime.global().setProperty(jsiRuntime, "mmkvArrayBufferPropNameIdCache",
|
|
42
|
+
jsi::Object::createFromHostObject(jsiRuntime, propNameIdCache));
|
|
40
43
|
}
|
|
41
44
|
|
|
42
|
-
std::string jstringToStdString(JNIEnv
|
|
43
|
-
|
|
45
|
+
std::string jstringToStdString(JNIEnv* env, jstring jStr) {
|
|
46
|
+
if (!jStr)
|
|
47
|
+
return "";
|
|
44
48
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
const auto stringClass = env->GetObjectClass(jStr);
|
|
50
|
+
const auto getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
|
|
51
|
+
const auto stringJbytes =
|
|
52
|
+
(jbyteArray)env->CallObjectMethod(jStr, getBytes, env->NewStringUTF("UTF-8"));
|
|
48
53
|
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
auto length = (size_t)env->GetArrayLength(stringJbytes);
|
|
55
|
+
auto pBytes = env->GetByteArrayElements(stringJbytes, nullptr);
|
|
51
56
|
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
std::string ret = std::string((char*)pBytes, length);
|
|
58
|
+
env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
60
|
+
env->DeleteLocalRef(stringJbytes);
|
|
61
|
+
env->DeleteLocalRef(stringClass);
|
|
62
|
+
return ret;
|
|
58
63
|
}
|
|
59
64
|
|
|
60
|
-
extern "C"
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
extern "C" JNIEXPORT void JNICALL Java_com_reactnativemmkv_MmkvModule_nativeInstall(JNIEnv* env,
|
|
66
|
+
jobject clazz,
|
|
67
|
+
jlong jsiPtr,
|
|
68
|
+
jstring path) {
|
|
69
|
+
#if DEBUG
|
|
70
|
+
MMKVLogLevel logLevel = MMKVLogDebug;
|
|
71
|
+
#else
|
|
72
|
+
MMKVLogLevel logLevel = MMKVLogError;
|
|
73
|
+
#endif
|
|
74
|
+
std::string storageDirectory = jstringToStdString(env, path);
|
|
75
|
+
MMKV::initializeMMKV(storageDirectory, logLevel);
|
|
64
76
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
77
|
+
auto runtime = reinterpret_cast<jsi::Runtime*>(jsiPtr);
|
|
78
|
+
if (runtime) {
|
|
79
|
+
install(*runtime);
|
|
80
|
+
}
|
|
81
|
+
// if runtime was nullptr, MMKV will not be installed. This should only happen while Remote
|
|
82
|
+
// Debugging (Chrome), but will be weird either way.
|
|
70
83
|
}
|