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,299 @@
|
|
|
1
|
+
//
|
|
2
|
+
// MmkvHostObject.mm
|
|
3
|
+
// Mmkv
|
|
4
|
+
//
|
|
5
|
+
// Created by Marc Rousavy on 03.09.21.
|
|
6
|
+
// Copyright © 2021 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import <Foundation/Foundation.h>
|
|
10
|
+
#import "MmkvHostObject.h"
|
|
11
|
+
#import "JSIUtils.h"
|
|
12
|
+
#import "../cpp/TypedArray.h"
|
|
13
|
+
#import <vector>
|
|
14
|
+
|
|
15
|
+
MmkvHostObject::MmkvHostObject(NSString* instanceId, NSString* path, NSString* cryptKey)
|
|
16
|
+
{
|
|
17
|
+
NSData* cryptData = cryptKey == nil ? nil : [cryptKey dataUsingEncoding:NSUTF8StringEncoding];
|
|
18
|
+
instance = [MMKV mmkvWithID:instanceId cryptKey:cryptData rootPath:path];
|
|
19
|
+
|
|
20
|
+
if (instance == nil) {
|
|
21
|
+
// Check if instanceId is invalid
|
|
22
|
+
if ([instanceId length] == 0) {
|
|
23
|
+
throw std::runtime_error("Failed to create MMKV instance! `id` cannot be empty!");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Check if encryptionKey is invalid
|
|
27
|
+
if (cryptData != nil && [cryptData length] > 16) {
|
|
28
|
+
throw std::runtime_error("Failed to create MMKV instance! `encryptionKey` cannot be longer than 16 bytes!");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Check if path is invalid
|
|
32
|
+
NSFileManager* fileManager = [[NSFileManager alloc] init];
|
|
33
|
+
bool pathExists = [fileManager fileExistsAtPath:path isDirectory:nil];
|
|
34
|
+
if (!pathExists) {
|
|
35
|
+
throw std::runtime_error("Failed to create MMKV instance! The given Storage Path does not exist!");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
throw std::runtime_error("Failed to create MMKV instance!");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
std::vector<jsi::PropNameID> MmkvHostObject::getPropertyNames(jsi::Runtime& rt)
|
|
43
|
+
{
|
|
44
|
+
std::vector<jsi::PropNameID> result;
|
|
45
|
+
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("set")));
|
|
46
|
+
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("getBoolean")));
|
|
47
|
+
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("getString")));
|
|
48
|
+
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("getNumber")));
|
|
49
|
+
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("contains")));
|
|
50
|
+
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("delete")));
|
|
51
|
+
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("getAllKeys")));
|
|
52
|
+
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("deleteAll")));
|
|
53
|
+
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("recrypt")));
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& propNameId)
|
|
58
|
+
{
|
|
59
|
+
auto propName = propNameId.utf8(runtime);
|
|
60
|
+
auto funcName = "MMKV." + propName;
|
|
61
|
+
|
|
62
|
+
if (propName == "set") {
|
|
63
|
+
// MMKV.set(key: string, value: string | number | bool)
|
|
64
|
+
return jsi::Function::createFromHostFunction(runtime,
|
|
65
|
+
jsi::PropNameID::forAscii(runtime, funcName),
|
|
66
|
+
2, // key, value
|
|
67
|
+
[this](jsi::Runtime& runtime,
|
|
68
|
+
const jsi::Value& thisValue,
|
|
69
|
+
const jsi::Value* arguments,
|
|
70
|
+
size_t count) -> jsi::Value {
|
|
71
|
+
if (!arguments[0].isString()) {
|
|
72
|
+
throw jsi::JSError(runtime, "MMKV::set: First argument ('key') has to be of type string!");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
76
|
+
if (arguments[1].isBool()) {
|
|
77
|
+
// Set as boolean
|
|
78
|
+
[instance setBool:arguments[1].getBool() forKey:keyName];
|
|
79
|
+
} else if (arguments[1].isNumber()) {
|
|
80
|
+
// Set as number (double in JS)
|
|
81
|
+
[instance setDouble:arguments[1].getNumber() forKey:keyName];
|
|
82
|
+
} else if (arguments[1].isString()) {
|
|
83
|
+
// Set as UTF-8 string
|
|
84
|
+
auto stringValue = convertJSIStringToNSString(runtime, arguments[1].getString(runtime));
|
|
85
|
+
[instance setString:stringValue forKey: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
|
+
auto data = [[NSData alloc] initWithBytes:bufferValue.data(runtime)
|
|
94
|
+
length:bufferValue.length(runtime)];
|
|
95
|
+
[instance setData:data forKey:keyName];
|
|
96
|
+
} else {
|
|
97
|
+
// unknown object
|
|
98
|
+
throw jsi::JSError(runtime, "MMKV::set: 'value' argument is an object, but not of type Uint8Array!");
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
// Invalid type
|
|
102
|
+
throw jsi::JSError(runtime, "Second argument ('value') has to be of type bool, number or string!");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return jsi::Value::undefined();
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (propName == "getBoolean") {
|
|
110
|
+
// MMKV.getBoolean(key: string)
|
|
111
|
+
return jsi::Function::createFromHostFunction(runtime,
|
|
112
|
+
jsi::PropNameID::forAscii(runtime, funcName),
|
|
113
|
+
1, // key
|
|
114
|
+
[this](jsi::Runtime& runtime,
|
|
115
|
+
const jsi::Value& thisValue,
|
|
116
|
+
const jsi::Value* arguments,
|
|
117
|
+
size_t count) -> jsi::Value {
|
|
118
|
+
if (!arguments[0].isString()) {
|
|
119
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
123
|
+
BOOL hasValue;
|
|
124
|
+
auto value = [instance getBoolForKey:keyName defaultValue:false hasValue:&hasValue];
|
|
125
|
+
if (hasValue) {
|
|
126
|
+
return jsi::Value(value == true);
|
|
127
|
+
} else {
|
|
128
|
+
return jsi::Value::undefined();
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (propName == "getString") {
|
|
134
|
+
// MMKV.getString(key: string)
|
|
135
|
+
return jsi::Function::createFromHostFunction(runtime,
|
|
136
|
+
jsi::PropNameID::forAscii(runtime, funcName),
|
|
137
|
+
1, // key
|
|
138
|
+
[this](jsi::Runtime& runtime,
|
|
139
|
+
const jsi::Value& thisValue,
|
|
140
|
+
const jsi::Value* arguments,
|
|
141
|
+
size_t count) -> jsi::Value {
|
|
142
|
+
if (!arguments[0].isString()) {
|
|
143
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
147
|
+
auto value = [instance getStringForKey:keyName];
|
|
148
|
+
if (value != nil) {
|
|
149
|
+
return convertNSStringToJSIString(runtime, value);
|
|
150
|
+
} else {
|
|
151
|
+
return jsi::Value::undefined();
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (propName == "getNumber") {
|
|
157
|
+
// MMKV.getNumber(key: string)
|
|
158
|
+
return jsi::Function::createFromHostFunction(runtime,
|
|
159
|
+
jsi::PropNameID::forAscii(runtime, funcName),
|
|
160
|
+
1, // key
|
|
161
|
+
[this](jsi::Runtime& runtime,
|
|
162
|
+
const jsi::Value& thisValue,
|
|
163
|
+
const jsi::Value* arguments,
|
|
164
|
+
size_t count) -> jsi::Value {
|
|
165
|
+
if (!arguments[0].isString()) {
|
|
166
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
170
|
+
BOOL hasValue;
|
|
171
|
+
auto value = [instance getDoubleForKey:keyName defaultValue:0.0 hasValue:&hasValue];
|
|
172
|
+
if (hasValue) {
|
|
173
|
+
return jsi::Value(value);
|
|
174
|
+
} else {
|
|
175
|
+
return jsi::Value::undefined();
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (propName == "getBuffer") {
|
|
181
|
+
// MMKV.getBuffer(key: string)
|
|
182
|
+
return jsi::Function::createFromHostFunction(runtime,
|
|
183
|
+
jsi::PropNameID::forAscii(runtime, funcName),
|
|
184
|
+
1, // key
|
|
185
|
+
[this](jsi::Runtime& runtime,
|
|
186
|
+
const jsi::Value& thisValue,
|
|
187
|
+
const jsi::Value* arguments,
|
|
188
|
+
size_t count) -> jsi::Value {
|
|
189
|
+
if (!arguments[0].isString()) {
|
|
190
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
194
|
+
auto data = [instance getDataForKey:keyName];
|
|
195
|
+
if (data != nil) {
|
|
196
|
+
TypedArray<TypedArrayKind::Uint8Array> array(runtime, data.length);
|
|
197
|
+
auto charArray = static_cast<const unsigned char*>([data bytes]);
|
|
198
|
+
std::vector<unsigned char> vector(data.length);
|
|
199
|
+
vector.assign(charArray, charArray + 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 = convertJSIStringToNSString(runtime, arguments[0].getString(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 = convertJSIStringToNSString(runtime, arguments[0].getString(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
|
+
return convertNSArrayToJSIArray(runtime, keys);
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (propName == "clearAll") {
|
|
261
|
+
// MMKV.clearAll()
|
|
262
|
+
return jsi::Function::createFromHostFunction(runtime,
|
|
263
|
+
jsi::PropNameID::forAscii(runtime, funcName),
|
|
264
|
+
0,
|
|
265
|
+
[this](jsi::Runtime& runtime,
|
|
266
|
+
const jsi::Value& thisValue,
|
|
267
|
+
const jsi::Value* arguments,
|
|
268
|
+
size_t count) -> jsi::Value {
|
|
269
|
+
[instance clearAll];
|
|
270
|
+
return jsi::Value::undefined();
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (propName == "recrypt") {
|
|
275
|
+
// MMKV.recrypt(encryptionKey)
|
|
276
|
+
return jsi::Function::createFromHostFunction(runtime,
|
|
277
|
+
jsi::PropNameID::forAscii(runtime, funcName),
|
|
278
|
+
1, // encryptionKey
|
|
279
|
+
[this](jsi::Runtime& runtime,
|
|
280
|
+
const jsi::Value& thisValue,
|
|
281
|
+
const jsi::Value* arguments,
|
|
282
|
+
size_t count) -> jsi::Value {
|
|
283
|
+
if (arguments[0].isUndefined()) {
|
|
284
|
+
// reset encryption key to "no encryption"
|
|
285
|
+
[instance reKey:nil];
|
|
286
|
+
} else if (arguments[0].isString()) {
|
|
287
|
+
// reKey(..) with new encryption-key
|
|
288
|
+
NSString* encryptionKey = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
289
|
+
NSData* encryptionKeyBytes = [encryptionKey dataUsingEncoding:NSUTF8StringEncoding];
|
|
290
|
+
[instance reKey:encryptionKeyBytes];
|
|
291
|
+
} else {
|
|
292
|
+
throw jsi::JSError(runtime, "First argument ('encryptionKey') has to be of type string (or undefined)!");
|
|
293
|
+
}
|
|
294
|
+
return jsi::Value::undefined();
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return jsi::Value::undefined();
|
|
299
|
+
}
|
package/ios/MmkvModule.h
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#import "MmkvModule.h"
|
|
2
|
+
#import "JSIUtils.h"
|
|
3
|
+
|
|
4
|
+
#import <React/RCTBridge+Private.h>
|
|
5
|
+
#import <React/RCTUtils.h>
|
|
6
|
+
#import <jsi/jsi.h>
|
|
7
|
+
|
|
8
|
+
#import <MMKV/MMKV.h>
|
|
9
|
+
#import "MmkvHostObject.h"
|
|
10
|
+
|
|
11
|
+
using namespace facebook;
|
|
12
|
+
|
|
13
|
+
@implementation MmkvModule
|
|
14
|
+
|
|
15
|
+
RCT_EXPORT_MODULE(MMKV)
|
|
16
|
+
|
|
17
|
+
+ (NSString*)getPropertyAsStringOrNilFromObject:(jsi::Object&)object
|
|
18
|
+
propertyName:(std::string)propertyName
|
|
19
|
+
runtime:(jsi::Runtime&)runtime
|
|
20
|
+
{
|
|
21
|
+
jsi::Value value = object.getProperty(runtime, propertyName.c_str());
|
|
22
|
+
std::string string = value.isString() ? value.asString(runtime).utf8(runtime) : "";
|
|
23
|
+
return string.length() > 0 ? [NSString stringWithUTF8String:string.c_str()] : nil;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install:(nullable NSString*)storageDirectory)
|
|
27
|
+
{
|
|
28
|
+
NSLog(@"Installing global.mmkvCreateNewInstance...");
|
|
29
|
+
RCTBridge* bridge = [RCTBridge currentBridge];
|
|
30
|
+
RCTCxxBridge* cxxBridge = (RCTCxxBridge*)bridge;
|
|
31
|
+
if (cxxBridge == nil) {
|
|
32
|
+
return @false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
using namespace facebook;
|
|
36
|
+
|
|
37
|
+
auto jsiRuntime = (jsi::Runtime*) cxxBridge.runtime;
|
|
38
|
+
if (jsiRuntime == nil) {
|
|
39
|
+
return @false;
|
|
40
|
+
}
|
|
41
|
+
auto& runtime = *jsiRuntime;
|
|
42
|
+
|
|
43
|
+
RCTUnsafeExecuteOnMainQueueSync(^{
|
|
44
|
+
[MMKV initializeMMKV:storageDirectory];
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// MMKV.createNewInstance()
|
|
48
|
+
auto mmkvCreateNewInstance = jsi::Function::createFromHostFunction(runtime,
|
|
49
|
+
jsi::PropNameID::forAscii(runtime, "mmkvCreateNewInstance"),
|
|
50
|
+
1,
|
|
51
|
+
[](jsi::Runtime& runtime,
|
|
52
|
+
const jsi::Value& thisValue,
|
|
53
|
+
const jsi::Value* arguments,
|
|
54
|
+
size_t count) -> jsi::Value {
|
|
55
|
+
if (count != 1) {
|
|
56
|
+
throw jsi::JSError(runtime, "MMKV.createNewInstance(..) expects one argument (object)!");
|
|
57
|
+
}
|
|
58
|
+
jsi::Object config = arguments[0].asObject(runtime);
|
|
59
|
+
|
|
60
|
+
NSString* instanceId = [MmkvModule getPropertyAsStringOrNilFromObject:config propertyName:"id" runtime:runtime];
|
|
61
|
+
NSString* path = [MmkvModule getPropertyAsStringOrNilFromObject:config propertyName:"path" runtime:runtime];
|
|
62
|
+
NSString* encryptionKey = [MmkvModule getPropertyAsStringOrNilFromObject:config propertyName:"encryptionKey" runtime:runtime];
|
|
63
|
+
|
|
64
|
+
auto instance = std::make_shared<MmkvHostObject>(instanceId, path, encryptionKey);
|
|
65
|
+
return jsi::Object::createFromHostObject(runtime, instance);
|
|
66
|
+
});
|
|
67
|
+
runtime.global().setProperty(runtime, "mmkvCreateNewInstance", std::move(mmkvCreateNewInstance));
|
|
68
|
+
|
|
69
|
+
NSLog(@"Installed global.mmkvCreateNewInstance!");
|
|
70
|
+
return @true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@end
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.MMKV = void 0;
|
|
7
|
+
|
|
8
|
+
var _createMMKV = require("./createMMKV");
|
|
9
|
+
|
|
10
|
+
var _createMMKV2 = require("./createMMKV.mock");
|
|
11
|
+
|
|
12
|
+
var _PlatformChecker = require("./PlatformChecker");
|
|
13
|
+
|
|
14
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
15
|
+
|
|
16
|
+
const onValueChangedListeners = new Map();
|
|
17
|
+
/**
|
|
18
|
+
* A single MMKV instance.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
class MMKV {
|
|
22
|
+
/**
|
|
23
|
+
* Creates a new MMKV instance with the given Configuration.
|
|
24
|
+
* If no custom `id` is supplied, `'mmkv.default'` will be used.
|
|
25
|
+
*/
|
|
26
|
+
constructor(configuration = {
|
|
27
|
+
id: 'mmkv.default'
|
|
28
|
+
}) {
|
|
29
|
+
_defineProperty(this, "nativeInstance", void 0);
|
|
30
|
+
|
|
31
|
+
_defineProperty(this, "functionCache", void 0);
|
|
32
|
+
|
|
33
|
+
_defineProperty(this, "id", void 0);
|
|
34
|
+
|
|
35
|
+
this.id = configuration.id;
|
|
36
|
+
this.nativeInstance = (0, _PlatformChecker.isJest)() ? (0, _createMMKV2.createMockMMKV)() : (0, _createMMKV.createMMKV)(configuration);
|
|
37
|
+
this.functionCache = {};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get onValueChangedListeners() {
|
|
41
|
+
if (!onValueChangedListeners.has(this.id)) {
|
|
42
|
+
onValueChangedListeners.set(this.id, []);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return onValueChangedListeners.get(this.id);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
getFunctionFromCache(functionName) {
|
|
49
|
+
if (this.functionCache[functionName] == null) {
|
|
50
|
+
this.functionCache[functionName] = this.nativeInstance[functionName];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return this.functionCache[functionName];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
onValuesChanged(keys) {
|
|
57
|
+
if (this.onValueChangedListeners.length === 0) return;
|
|
58
|
+
|
|
59
|
+
for (const key of keys) {
|
|
60
|
+
for (const listener of this.onValueChangedListeners) {
|
|
61
|
+
listener(key);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
set(key, value) {
|
|
67
|
+
const func = this.getFunctionFromCache('set');
|
|
68
|
+
func(key, value);
|
|
69
|
+
this.onValuesChanged([key]);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
getBoolean(key) {
|
|
73
|
+
const func = this.getFunctionFromCache('getBoolean');
|
|
74
|
+
return func(key);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
getString(key) {
|
|
78
|
+
const func = this.getFunctionFromCache('getString');
|
|
79
|
+
return func(key);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
getNumber(key) {
|
|
83
|
+
const func = this.getFunctionFromCache('getNumber');
|
|
84
|
+
return func(key);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
getBuffer(key) {
|
|
88
|
+
const func = this.getFunctionFromCache('getBuffer');
|
|
89
|
+
return func(key);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
contains(key) {
|
|
93
|
+
const func = this.getFunctionFromCache('contains');
|
|
94
|
+
return func(key);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
delete(key) {
|
|
98
|
+
const func = this.getFunctionFromCache('delete');
|
|
99
|
+
func(key);
|
|
100
|
+
this.onValuesChanged([key]);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
getAllKeys() {
|
|
104
|
+
const func = this.getFunctionFromCache('getAllKeys');
|
|
105
|
+
return func();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
clearAll() {
|
|
109
|
+
const keys = this.getAllKeys();
|
|
110
|
+
const func = this.getFunctionFromCache('clearAll');
|
|
111
|
+
func();
|
|
112
|
+
this.onValuesChanged(keys);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
recrypt(key) {
|
|
116
|
+
const func = this.getFunctionFromCache('recrypt');
|
|
117
|
+
return func(key);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
toString() {
|
|
121
|
+
return `MMKV (${this.id}): [${this.getAllKeys().join(', ')}]`;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
toJSON() {
|
|
125
|
+
return {
|
|
126
|
+
[this.id]: this.getAllKeys()
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
addOnValueChangedListener(onValueChanged) {
|
|
131
|
+
this.onValueChangedListeners.push(onValueChanged);
|
|
132
|
+
return {
|
|
133
|
+
remove: () => {
|
|
134
|
+
const index = this.onValueChangedListeners.indexOf(onValueChanged);
|
|
135
|
+
|
|
136
|
+
if (index !== -1) {
|
|
137
|
+
this.onValueChangedListeners.splice(index, 1);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
exports.MMKV = MMKV;
|
|
146
|
+
//# sourceMappingURL=MMKV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["MMKV.ts"],"names":["onValueChangedListeners","Map","MMKV","constructor","configuration","id","nativeInstance","functionCache","has","set","get","getFunctionFromCache","functionName","onValuesChanged","keys","length","key","listener","value","func","getBoolean","getString","getNumber","getBuffer","contains","delete","getAllKeys","clearAll","recrypt","toString","join","toJSON","addOnValueChangedListener","onValueChanged","push","remove","index","indexOf","splice"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;;;AA+HA,MAAMA,uBAAuB,GAAG,IAAIC,GAAJ,EAAhC;AAEA;AACA;AACA;;AACO,MAAMC,IAAN,CAAoC;AAKzC;AACF;AACA;AACA;AACEC,EAAAA,WAAW,CAACC,aAAgC,GAAG;AAAEC,IAAAA,EAAE,EAAE;AAAN,GAApC,EAA4D;AAAA;;AAAA;;AAAA;;AACrE,SAAKA,EAAL,GAAUD,aAAa,CAACC,EAAxB;AACA,SAAKC,cAAL,GAAsB,iCAClB,kCADkB,GAElB,4BAAWF,aAAX,CAFJ;AAGA,SAAKG,aAAL,GAAqB,EAArB;AACD;;AAEkC,MAAvBP,uBAAuB,GAAG;AACpC,QAAI,CAACA,uBAAuB,CAACQ,GAAxB,CAA4B,KAAKH,EAAjC,CAAL,EAA2C;AACzCL,MAAAA,uBAAuB,CAACS,GAAxB,CAA4B,KAAKJ,EAAjC,EAAqC,EAArC;AACD;;AACD,WAAOL,uBAAuB,CAACU,GAAxB,CAA4B,KAAKL,EAAjC,CAAP;AACD;;AAEOM,EAAAA,oBAAoB,CAC1BC,YAD0B,EAEX;AACf,QAAI,KAAKL,aAAL,CAAmBK,YAAnB,KAAoC,IAAxC,EAA8C;AAC5C,WAAKL,aAAL,CAAmBK,YAAnB,IAAmC,KAAKN,cAAL,CAAoBM,YAApB,CAAnC;AACD;;AACD,WAAO,KAAKL,aAAL,CAAmBK,YAAnB,CAAP;AACD;;AAEOC,EAAAA,eAAe,CAACC,IAAD,EAAiB;AACtC,QAAI,KAAKd,uBAAL,CAA6Be,MAA7B,KAAwC,CAA5C,EAA+C;;AAE/C,SAAK,MAAMC,GAAX,IAAkBF,IAAlB,EAAwB;AACtB,WAAK,MAAMG,QAAX,IAAuB,KAAKjB,uBAA5B,EAAqD;AACnDiB,QAAAA,QAAQ,CAACD,GAAD,CAAR;AACD;AACF;AACF;;AAEDP,EAAAA,GAAG,CAACO,GAAD,EAAcE,KAAd,EAAmE;AACpE,UAAMC,IAAI,GAAG,KAAKR,oBAAL,CAA0B,KAA1B,CAAb;AACAQ,IAAAA,IAAI,CAACH,GAAD,EAAME,KAAN,CAAJ;AAEA,SAAKL,eAAL,CAAqB,CAACG,GAAD,CAArB;AACD;;AACDI,EAAAA,UAAU,CAACJ,GAAD,EAAmC;AAC3C,UAAMG,IAAI,GAAG,KAAKR,oBAAL,CAA0B,YAA1B,CAAb;AACA,WAAOQ,IAAI,CAACH,GAAD,CAAX;AACD;;AACDK,EAAAA,SAAS,CAACL,GAAD,EAAkC;AACzC,UAAMG,IAAI,GAAG,KAAKR,oBAAL,CAA0B,WAA1B,CAAb;AACA,WAAOQ,IAAI,CAACH,GAAD,CAAX;AACD;;AACDM,EAAAA,SAAS,CAACN,GAAD,EAAkC;AACzC,UAAMG,IAAI,GAAG,KAAKR,oBAAL,CAA0B,WAA1B,CAAb;AACA,WAAOQ,IAAI,CAACH,GAAD,CAAX;AACD;;AACDO,EAAAA,SAAS,CAACP,GAAD,EAAsC;AAC7C,UAAMG,IAAI,GAAG,KAAKR,oBAAL,CAA0B,WAA1B,CAAb;AACA,WAAOQ,IAAI,CAACH,GAAD,CAAX;AACD;;AACDQ,EAAAA,QAAQ,CAACR,GAAD,EAAuB;AAC7B,UAAMG,IAAI,GAAG,KAAKR,oBAAL,CAA0B,UAA1B,CAAb;AACA,WAAOQ,IAAI,CAACH,GAAD,CAAX;AACD;;AACDS,EAAAA,MAAM,CAACT,GAAD,EAAoB;AACxB,UAAMG,IAAI,GAAG,KAAKR,oBAAL,CAA0B,QAA1B,CAAb;AACAQ,IAAAA,IAAI,CAACH,GAAD,CAAJ;AAEA,SAAKH,eAAL,CAAqB,CAACG,GAAD,CAArB;AACD;;AACDU,EAAAA,UAAU,GAAa;AACrB,UAAMP,IAAI,GAAG,KAAKR,oBAAL,CAA0B,YAA1B,CAAb;AACA,WAAOQ,IAAI,EAAX;AACD;;AACDQ,EAAAA,QAAQ,GAAS;AACf,UAAMb,IAAI,GAAG,KAAKY,UAAL,EAAb;AAEA,UAAMP,IAAI,GAAG,KAAKR,oBAAL,CAA0B,UAA1B,CAAb;AACAQ,IAAAA,IAAI;AAEJ,SAAKN,eAAL,CAAqBC,IAArB;AACD;;AACDc,EAAAA,OAAO,CAACZ,GAAD,EAAgC;AACrC,UAAMG,IAAI,GAAG,KAAKR,oBAAL,CAA0B,SAA1B,CAAb;AACA,WAAOQ,IAAI,CAACH,GAAD,CAAX;AACD;;AAEDa,EAAAA,QAAQ,GAAW;AACjB,WAAQ,SAAQ,KAAKxB,EAAG,OAAM,KAAKqB,UAAL,GAAkBI,IAAlB,CAAuB,IAAvB,CAA6B,GAA3D;AACD;;AACDC,EAAAA,MAAM,GAAW;AACf,WAAO;AACL,OAAC,KAAK1B,EAAN,GAAW,KAAKqB,UAAL;AADN,KAAP;AAGD;;AAEDM,EAAAA,yBAAyB,CAACC,cAAD,EAAkD;AACzE,SAAKjC,uBAAL,CAA6BkC,IAA7B,CAAkCD,cAAlC;AAEA,WAAO;AACLE,MAAAA,MAAM,EAAE,MAAM;AACZ,cAAMC,KAAK,GAAG,KAAKpC,uBAAL,CAA6BqC,OAA7B,CAAqCJ,cAArC,CAAd;;AACA,YAAIG,KAAK,KAAK,CAAC,CAAf,EAAkB;AAChB,eAAKpC,uBAAL,CAA6BsC,MAA7B,CAAoCF,KAApC,EAA2C,CAA3C;AACD;AACF;AANI,KAAP;AAQD;;AAhHwC","sourcesContent":["import { createMMKV } from './createMMKV';\nimport { createMockMMKV } from './createMMKV.mock';\nimport { isJest } from './PlatformChecker';\n\ninterface Listener {\n remove: () => void;\n}\n\n/**\n * Used for configuration of a single MMKV instance.\n */\nexport interface MMKVConfiguration {\n /**\n * The MMKV instance's ID. If you want to use multiple instances, make sure to use different IDs!\n *\n * @example\n * ```ts\n * const userStorage = new MMKV({ id: `user-${userId}-storage` })\n * const globalStorage = new MMKV({ id: 'global-app-storage' })\n * ```\n *\n * @default 'mmkv.default'\n */\n id: string;\n /**\n * The MMKV instance's root path. By default, MMKV stores file inside `$(Documents)/mmkv/`. You can customize MMKV's root directory on MMKV initialization:\n *\n * @example\n * ```ts\n * const temporaryStorage = new MMKV({ path: '/tmp/' })\n * ```\n */\n path?: string;\n /**\n * The MMKV instance's encryption/decryption key. By default, MMKV stores all key-values in plain text on file, relying on iOS's sandbox to make sure the file is encrypted. Should you worry about information leaking, you can choose to encrypt MMKV.\n *\n * Encryption keys can have a maximum length of 16 bytes.\n *\n * @example\n * ```ts\n * const secureStorage = new MMKV({ encryptionKey: 'my-encryption-key!' })\n * ```\n */\n encryptionKey?: string;\n}\n\n/**\n * Represents a single MMKV instance.\n */\ninterface MMKVInterface {\n /**\n * Set a value for the given `key`.\n */\n set: (key: string, value: boolean | string | number | Uint8Array) => void;\n /**\n * Get the boolean value for the given `key`, or `undefined` if it does not exist.\n *\n * @default undefined\n */\n getBoolean: (key: string) => boolean | undefined;\n /**\n * Get the string value for the given `key`, or `undefined` if it does not exist.\n *\n * @default undefined\n */\n getString: (key: string) => string | undefined;\n /**\n * Get the number value for the given `key`, or `undefined` if it does not exist.\n *\n * @default undefined\n */\n getNumber: (key: string) => number | undefined;\n /**\n * Get a raw buffer of unsigned 8-bit (0-255) data.\n *\n * @default undefined\n */\n getBuffer: (key: string) => Uint8Array | undefined;\n /**\n * Checks whether the given `key` is being stored in this MMKV instance.\n */\n contains: (key: string) => boolean;\n /**\n * Delete the given `key`.\n */\n delete: (key: string) => void;\n /**\n * Get all keys.\n *\n * @default []\n */\n getAllKeys: () => string[];\n /**\n * Delete all keys.\n */\n clearAll: () => void;\n /**\n * Sets (or updates) the encryption-key to encrypt all data in this MMKV instance with.\n *\n * To remove encryption, pass `undefined` as a key.\n *\n * Encryption keys can have a maximum length of 16 bytes.\n */\n recrypt: (key: string | undefined) => void;\n /**\n * Adds a value changed listener. The Listener will be called whenever any value\n * in this storage instance changes (set or delete).\n *\n * To unsubscribe from value changes, call `remove()` on the Listener.\n */\n addOnValueChangedListener: (\n onValueChanged: (key: string) => void\n ) => Listener;\n}\n\nexport type NativeMMKV = Pick<\n MMKVInterface,\n | 'clearAll'\n | 'contains'\n | 'delete'\n | 'getAllKeys'\n | 'getBoolean'\n | 'getNumber'\n | 'getString'\n | 'getBuffer'\n | 'set'\n | 'recrypt'\n>;\n\nconst onValueChangedListeners = new Map<string, ((key: string) => void)[]>();\n\n/**\n * A single MMKV instance.\n */\nexport class MMKV implements MMKVInterface {\n private nativeInstance: NativeMMKV;\n private functionCache: Partial<NativeMMKV>;\n private id: string;\n\n /**\n * Creates a new MMKV instance with the given Configuration.\n * If no custom `id` is supplied, `'mmkv.default'` will be used.\n */\n constructor(configuration: MMKVConfiguration = { id: 'mmkv.default' }) {\n this.id = configuration.id;\n this.nativeInstance = isJest()\n ? createMockMMKV()\n : createMMKV(configuration);\n this.functionCache = {};\n }\n\n private get onValueChangedListeners() {\n if (!onValueChangedListeners.has(this.id)) {\n onValueChangedListeners.set(this.id, []);\n }\n return onValueChangedListeners.get(this.id)!;\n }\n\n private getFunctionFromCache<T extends keyof NativeMMKV>(\n functionName: T\n ): NativeMMKV[T] {\n if (this.functionCache[functionName] == null) {\n this.functionCache[functionName] = this.nativeInstance[functionName];\n }\n return this.functionCache[functionName] as NativeMMKV[T];\n }\n\n private onValuesChanged(keys: string[]) {\n if (this.onValueChangedListeners.length === 0) return;\n\n for (const key of keys) {\n for (const listener of this.onValueChangedListeners) {\n listener(key);\n }\n }\n }\n\n set(key: string, value: boolean | string | number | Uint8Array): void {\n const func = this.getFunctionFromCache('set');\n func(key, value);\n\n this.onValuesChanged([key]);\n }\n getBoolean(key: string): boolean | undefined {\n const func = this.getFunctionFromCache('getBoolean');\n return func(key);\n }\n getString(key: string): string | undefined {\n const func = this.getFunctionFromCache('getString');\n return func(key);\n }\n getNumber(key: string): number | undefined {\n const func = this.getFunctionFromCache('getNumber');\n return func(key);\n }\n getBuffer(key: string): Uint8Array | undefined {\n const func = this.getFunctionFromCache('getBuffer');\n return func(key);\n }\n contains(key: string): boolean {\n const func = this.getFunctionFromCache('contains');\n return func(key);\n }\n delete(key: string): void {\n const func = this.getFunctionFromCache('delete');\n func(key);\n\n this.onValuesChanged([key]);\n }\n getAllKeys(): string[] {\n const func = this.getFunctionFromCache('getAllKeys');\n return func();\n }\n clearAll(): void {\n const keys = this.getAllKeys();\n\n const func = this.getFunctionFromCache('clearAll');\n func();\n\n this.onValuesChanged(keys);\n }\n recrypt(key: string | undefined): void {\n const func = this.getFunctionFromCache('recrypt');\n return func(key);\n }\n\n toString(): string {\n return `MMKV (${this.id}): [${this.getAllKeys().join(', ')}]`;\n }\n toJSON(): object {\n return {\n [this.id]: this.getAllKeys(),\n };\n }\n\n addOnValueChangedListener(onValueChanged: (key: string) => void): Listener {\n this.onValueChangedListeners.push(onValueChanged);\n\n return {\n remove: () => {\n const index = this.onValueChangedListeners.indexOf(onValueChanged);\n if (index !== -1) {\n this.onValueChangedListeners.splice(index, 1);\n }\n },\n };\n }\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isJest = isJest;
|
|
7
|
+
|
|
8
|
+
function isJest() {
|
|
9
|
+
if (global.process == null) {
|
|
10
|
+
// In a WebBrowser/Electron the `process` variable does not exist
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return process.env.JEST_WORKER_ID != null;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=PlatformChecker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["PlatformChecker.ts"],"names":["isJest","global","process","env","JEST_WORKER_ID"],"mappings":";;;;;;;AAAO,SAASA,MAAT,GAA2B;AAChC,MAAIC,MAAM,CAACC,OAAP,IAAkB,IAAtB,EAA4B;AAC1B;AACA,WAAO,KAAP;AACD;;AACD,SAAOA,OAAO,CAACC,GAAR,CAAYC,cAAZ,IAA8B,IAArC;AACD","sourcesContent":["export function isJest(): boolean {\n if (global.process == null) {\n // In a WebBrowser/Electron the `process` variable does not exist\n return false;\n }\n return process.env.JEST_WORKER_ID != null;\n}\n"]}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createMMKV = void 0;
|
|
7
|
+
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
|
|
10
|
+
// Root directory of all MMKV stores
|
|
11
|
+
const ROOT_DIRECTORY = null;
|
|
12
|
+
|
|
13
|
+
const createMMKV = config => {
|
|
14
|
+
// Check if the constructor exists. If not, try installing the JSI bindings.
|
|
15
|
+
if (global.mmkvCreateNewInstance == null) {
|
|
16
|
+
// Get the native MMKV ReactModule
|
|
17
|
+
const MMKVModule = _reactNative.NativeModules.MMKV;
|
|
18
|
+
|
|
19
|
+
if (MMKVModule == null) {
|
|
20
|
+
var _NativeModules$Native, _NativeModules$Native2;
|
|
21
|
+
|
|
22
|
+
let message = 'Failed to create a new MMKV instance: The native MMKV Module could not be found.';
|
|
23
|
+
message += '\n* Make sure react-native-mmkv is correctly autolinked (run `npx react-native config` to verify)';
|
|
24
|
+
|
|
25
|
+
if (_reactNative.Platform.OS === 'ios' || _reactNative.Platform.OS === 'macos') {
|
|
26
|
+
message += '\n* Make sure you ran `pod install` in the ios/ directory.';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (_reactNative.Platform.OS === 'android') {
|
|
30
|
+
message += '\n* Make sure gradle is synced.';
|
|
31
|
+
} // check if Expo
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
const ExpoConstants = (_NativeModules$Native = _reactNative.NativeModules.NativeUnimoduleProxy) === null || _NativeModules$Native === void 0 ? void 0 : (_NativeModules$Native2 = _NativeModules$Native.modulesConstants) === null || _NativeModules$Native2 === void 0 ? void 0 : _NativeModules$Native2.ExponentConstants;
|
|
35
|
+
|
|
36
|
+
if (ExpoConstants != null) {
|
|
37
|
+
if (ExpoConstants.appOwnership === 'expo') {
|
|
38
|
+
// We're running Expo Go
|
|
39
|
+
throw new Error('react-native-mmkv is not supported in Expo Go! Use EAS (`expo prebuild`) or eject to a bare workflow instead.');
|
|
40
|
+
} else {
|
|
41
|
+
// We're running Expo bare / standalone
|
|
42
|
+
message += '\n* Make sure you ran `expo prebuild`.';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
message += '\n* Make sure you rebuilt the app.';
|
|
47
|
+
throw new Error(message);
|
|
48
|
+
} // Check if we are running on-device (JSI)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
if (global.nativeCallSyncHook == null || MMKVModule.install == null) {
|
|
52
|
+
throw new Error('Failed to create a new MMKV instance: React Native is not running on-device. MMKV can only be used when synchronous method invocations (JSI) are possible. If you are using a remote debugger (e.g. Chrome), switch to an on-device debugger (e.g. Flipper) instead.');
|
|
53
|
+
} // Call the synchronous blocking install() function
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
const result = MMKVModule.install(ROOT_DIRECTORY);
|
|
57
|
+
if (result !== true) throw new Error(`Failed to create a new MMKV instance: The native MMKV Module could not be installed! Looks like something went wrong when installing JSI bindings: ${result}`); // Check again if the constructor now exists. If not, throw an error.
|
|
58
|
+
|
|
59
|
+
if (global.mmkvCreateNewInstance == null) throw new Error('Failed to create a new MMKV instance, the native initializer function does not exist. Are you trying to use MMKV from different JS Runtimes?');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return global.mmkvCreateNewInstance(config);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
exports.createMMKV = createMMKV;
|
|
66
|
+
//# sourceMappingURL=createMMKV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["createMMKV.ts"],"names":["ROOT_DIRECTORY","createMMKV","config","global","mmkvCreateNewInstance","MMKVModule","NativeModules","MMKV","message","Platform","OS","ExpoConstants","NativeUnimoduleProxy","modulesConstants","ExponentConstants","appOwnership","Error","nativeCallSyncHook","install","result"],"mappings":";;;;;;;AAAA;;AASA;AACA,MAAMA,cAA6B,GAAG,IAAtC;;AAEO,MAAMC,UAAU,GAAIC,MAAD,IAA2C;AACnE;AACA,MAAIC,MAAM,CAACC,qBAAP,IAAgC,IAApC,EAA0C;AACxC;AACA,UAAMC,UAAU,GAAGC,2BAAcC,IAAjC;;AACA,QAAIF,UAAU,IAAI,IAAlB,EAAwB;AAAA;;AACtB,UAAIG,OAAO,GACT,kFADF;AAEAA,MAAAA,OAAO,IACL,mGADF;;AAEA,UAAIC,sBAASC,EAAT,KAAgB,KAAhB,IAAyBD,sBAASC,EAAT,KAAgB,OAA7C,EAAsD;AACpDF,QAAAA,OAAO,IAAI,4DAAX;AACD;;AACD,UAAIC,sBAASC,EAAT,KAAgB,SAApB,EAA+B;AAC7BF,QAAAA,OAAO,IAAI,iCAAX;AACD,OAVqB,CAWtB;;;AACA,YAAMG,aAAa,4BACjBL,2BAAcM,oBADG,oFACjB,sBAAoCC,gBADnB,2DACjB,uBAAsDC,iBADxD;;AAEA,UAAIH,aAAa,IAAI,IAArB,EAA2B;AACzB,YAAIA,aAAa,CAACI,YAAd,KAA+B,MAAnC,EAA2C;AACzC;AACA,gBAAM,IAAIC,KAAJ,CACJ,+GADI,CAAN;AAGD,SALD,MAKO;AACL;AACAR,UAAAA,OAAO,IAAI,wCAAX;AACD;AACF;;AAEDA,MAAAA,OAAO,IAAI,oCAAX;AACA,YAAM,IAAIQ,KAAJ,CAAUR,OAAV,CAAN;AACD,KA/BuC,CAiCxC;;;AACA,QAAIL,MAAM,CAACc,kBAAP,IAA6B,IAA7B,IAAqCZ,UAAU,CAACa,OAAX,IAAsB,IAA/D,EAAqE;AACnE,YAAM,IAAIF,KAAJ,CACJ,sQADI,CAAN;AAGD,KAtCuC,CAwCxC;;;AACA,UAAMG,MAAM,GAAGd,UAAU,CAACa,OAAX,CAAmBlB,cAAnB,CAAf;AACA,QAAImB,MAAM,KAAK,IAAf,EACE,MAAM,IAAIH,KAAJ,CACH,sJAAqJG,MAAO,EADzJ,CAAN,CA3CsC,CA+CxC;;AACA,QAAIhB,MAAM,CAACC,qBAAP,IAAgC,IAApC,EACE,MAAM,IAAIY,KAAJ,CACJ,8IADI,CAAN;AAGH;;AAED,SAAOb,MAAM,CAACC,qBAAP,CAA6BF,MAA7B,CAAP;AACD,CAzDM","sourcesContent":["import { NativeModules, Platform } from 'react-native';\nimport type { MMKVConfiguration, NativeMMKV } from 'react-native-mmkv';\n\n// global func declaration for JSI functions\ndeclare global {\n function mmkvCreateNewInstance(configuration: MMKVConfiguration): NativeMMKV;\n function nativeCallSyncHook(): unknown;\n}\n\n// Root directory of all MMKV stores\nconst ROOT_DIRECTORY: string | null = null;\n\nexport const createMMKV = (config: MMKVConfiguration): NativeMMKV => {\n // Check if the constructor exists. If not, try installing the JSI bindings.\n if (global.mmkvCreateNewInstance == null) {\n // Get the native MMKV ReactModule\n const MMKVModule = NativeModules.MMKV;\n if (MMKVModule == null) {\n let message =\n 'Failed to create a new MMKV instance: The native MMKV Module could not be found.';\n message +=\n '\\n* Make sure react-native-mmkv is correctly autolinked (run `npx react-native config` to verify)';\n if (Platform.OS === 'ios' || Platform.OS === 'macos') {\n message += '\\n* Make sure you ran `pod install` in the ios/ directory.';\n }\n if (Platform.OS === 'android') {\n message += '\\n* Make sure gradle is synced.';\n }\n // check if Expo\n const ExpoConstants =\n NativeModules.NativeUnimoduleProxy?.modulesConstants?.ExponentConstants;\n if (ExpoConstants != null) {\n if (ExpoConstants.appOwnership === 'expo') {\n // We're running Expo Go\n throw new Error(\n 'react-native-mmkv is not supported in Expo Go! Use EAS (`expo prebuild`) or eject to a bare workflow instead.'\n );\n } else {\n // We're running Expo bare / standalone\n message += '\\n* Make sure you ran `expo prebuild`.';\n }\n }\n\n message += '\\n* Make sure you rebuilt the app.';\n throw new Error(message);\n }\n\n // Check if we are running on-device (JSI)\n if (global.nativeCallSyncHook == null || MMKVModule.install == null) {\n throw new Error(\n 'Failed to create a new MMKV instance: React Native is not running on-device. MMKV can only be used when synchronous method invocations (JSI) are possible. If you are using a remote debugger (e.g. Chrome), switch to an on-device debugger (e.g. Flipper) instead.'\n );\n }\n\n // Call the synchronous blocking install() function\n const result = MMKVModule.install(ROOT_DIRECTORY);\n if (result !== true)\n throw new Error(\n `Failed to create a new MMKV instance: The native MMKV Module could not be installed! Looks like something went wrong when installing JSI bindings: ${result}`\n );\n\n // Check again if the constructor now exists. If not, throw an error.\n if (global.mmkvCreateNewInstance == null)\n throw new Error(\n 'Failed to create a new MMKV instance, the native initializer function does not exist. Are you trying to use MMKV from different JS Runtimes?'\n );\n }\n\n return global.mmkvCreateNewInstance(config);\n};\n"]}
|