react-native-mmkv 4.2.0 → 4.3.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/NitroMmkv.podspec +9 -2
- package/android/CMakeLists.txt +5 -0
- package/android/build.gradle +8 -3
- package/cpp/HybridMMKV.cpp +44 -51
- package/cpp/HybridMMKVFactory.cpp +1 -5
- package/cpp/MMKVTypes.hpp +12 -0
- package/cpp/ManagedMMBuffer.hpp +1 -1
- package/lib/createMMKV/createMMKV.web.js +1 -1
- package/lib/createMMKV/createMockMMKV.js +1 -1
- package/lib/specs/MMKV.nitro.d.ts +1 -1
- package/lib/specs/MMKVFactory.nitro.d.ts +8 -0
- package/nitrogen/generated/shared/c++/Configuration.hpp +6 -2
- package/package.json +1 -1
- package/src/createMMKV/createMMKV.web.ts +1 -1
- package/src/createMMKV/createMockMMKV.ts +1 -1
- package/src/specs/MMKV.nitro.ts +1 -1
- package/src/specs/MMKVFactory.nitro.ts +8 -0
package/NitroMmkv.podspec
CHANGED
|
@@ -24,13 +24,20 @@ Pod::Spec.new do |s|
|
|
|
24
24
|
|
|
25
25
|
# Add MMKV Core dependency
|
|
26
26
|
s.compiler_flags = '-x objective-c++'
|
|
27
|
-
s.dependency 'MMKVCore', '2.
|
|
27
|
+
s.dependency 'MMKVCore', '2.4.0'
|
|
28
|
+
|
|
29
|
+
# Optionally configure MMKV log level via Podfile ($MMKVLogLevel) or env var (MMKV_LOG_LEVEL)
|
|
30
|
+
mmkv_log_level = $MMKVLogLevel || ENV['MMKV_LOG_LEVEL']
|
|
31
|
+
gcc_preprocessor_defs = "$(inherited) FOLLY_NO_CONFIG FOLLY_CFG_NO_COROUTINES"
|
|
32
|
+
if mmkv_log_level != nil && mmkv_log_level.to_s != ""
|
|
33
|
+
gcc_preprocessor_defs += " MMKV_LOG_LEVEL=#{mmkv_log_level}"
|
|
34
|
+
end
|
|
28
35
|
|
|
29
36
|
# TODO: Remove when no one uses RN 0.79 anymore
|
|
30
37
|
# Add support for React Native 0.79 or below
|
|
31
38
|
s.pod_target_xcconfig = {
|
|
32
39
|
"HEADER_SEARCH_PATHS" => ["${PODS_ROOT}/RCT-Folly"],
|
|
33
|
-
"GCC_PREPROCESSOR_DEFINITIONS" =>
|
|
40
|
+
"GCC_PREPROCESSOR_DEFINITIONS" => gcc_preprocessor_defs,
|
|
34
41
|
"OTHER_CPLUSPLUSFLAGS" => "$(inherited) -DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"
|
|
35
42
|
}
|
|
36
43
|
|
package/android/CMakeLists.txt
CHANGED
|
@@ -5,6 +5,11 @@ set (PACKAGE_NAME NitroMmkv)
|
|
|
5
5
|
set (CMAKE_VERBOSE_MAKEFILE ON)
|
|
6
6
|
set (CMAKE_CXX_STANDARD 20)
|
|
7
7
|
|
|
8
|
+
# Optionally configure MMKV log level (passed from Gradle as -DMMKV_LOG_LEVEL=<0-4>)
|
|
9
|
+
if(DEFINED MMKV_LOG_LEVEL)
|
|
10
|
+
add_definitions(-DMMKV_LOG_LEVEL=${MMKV_LOG_LEVEL})
|
|
11
|
+
endif()
|
|
12
|
+
|
|
8
13
|
# Find all C++ files (shared and platform specifics)
|
|
9
14
|
file(GLOB_RECURSE shared_files RELATIVE ${CMAKE_SOURCE_DIR}
|
|
10
15
|
"../cpp/**.cpp"
|
package/android/build.gradle
CHANGED
|
@@ -5,7 +5,7 @@ buildscript {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
dependencies {
|
|
8
|
-
classpath "com.android.tools.build:gradle:9.
|
|
8
|
+
classpath "com.android.tools.build:gradle:9.1.0"
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -49,7 +49,12 @@ android {
|
|
|
49
49
|
externalNativeBuild {
|
|
50
50
|
cmake {
|
|
51
51
|
cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all"
|
|
52
|
-
|
|
52
|
+
def mmkvLogLevel = rootProject.hasProperty("MMKV_logLevel") ? rootProject.property("MMKV_logLevel") : null
|
|
53
|
+
if (mmkvLogLevel != null && mmkvLogLevel != "") {
|
|
54
|
+
arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON", "-DMMKV_LOG_LEVEL=${mmkvLogLevel}"
|
|
55
|
+
} else {
|
|
56
|
+
arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
|
|
57
|
+
}
|
|
53
58
|
abiFilters (*reactNativeArchitectures())
|
|
54
59
|
|
|
55
60
|
buildTypes {
|
|
@@ -140,6 +145,6 @@ dependencies {
|
|
|
140
145
|
implementation project(":react-native-nitro-modules")
|
|
141
146
|
|
|
142
147
|
// Add a dependency on mmkv core (this ships a C++ prefab)
|
|
143
|
-
implementation "io.github.zhongwuzw:mmkv:2.
|
|
148
|
+
implementation "io.github.zhongwuzw:mmkv:2.4.0"
|
|
144
149
|
}
|
|
145
150
|
|
package/cpp/HybridMMKV.cpp
CHANGED
|
@@ -14,31 +14,32 @@
|
|
|
14
14
|
namespace margelo::nitro::mmkv {
|
|
15
15
|
|
|
16
16
|
HybridMMKV::HybridMMKV(const Configuration& config) : HybridObject(TAG) {
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
MMKVMode mmkvMode = getMMKVMode(config);
|
|
18
|
+
if (config.readOnly.value_or(false)) {
|
|
19
|
+
mmkvMode = mmkvMode | MMKVMode::MMKV_READ_ONLY;
|
|
20
|
+
}
|
|
21
|
+
bool useAes256Encryption = config.encryptionType.value_or(EncryptionType::AES_128) == EncryptionType::AES_256;
|
|
22
|
+
std::string encryptionKey = config.encryptionKey.value_or("");
|
|
23
|
+
std::string* encryptionKeyPtr = encryptionKey.size() > 0 ? &encryptionKey : nullptr;
|
|
24
|
+
std::string rootPath = config.path.value_or("");
|
|
25
|
+
std::string* rootPathPtr = rootPath.size() > 0 ? &rootPath : nullptr;
|
|
26
|
+
bool compareBeforeSet = config.compareBeforeSet.value_or(false);
|
|
27
|
+
|
|
28
|
+
MMKVConfig mmkvConfig{.mode = mmkvMode,
|
|
29
|
+
.aes256 = useAes256Encryption,
|
|
30
|
+
.cryptKey = encryptionKeyPtr,
|
|
31
|
+
.rootPath = rootPathPtr,
|
|
32
|
+
.enableCompareBeforeSet = compareBeforeSet};
|
|
33
|
+
|
|
19
34
|
bool hasEncryptionKey = encryptionKey.size() > 0;
|
|
20
|
-
Logger::log(LogLevel::Info, TAG, "Creating MMKV instance \"%s\"... (Path: %s, Encrypted: %s)", config.id.c_str(),
|
|
35
|
+
Logger::log(LogLevel::Info, TAG, "Creating MMKV instance \"%s\"... (Path: %s, Encrypted: %s)", config.id.c_str(), rootPath.c_str(),
|
|
21
36
|
hasEncryptionKey ? "true" : "false");
|
|
22
37
|
|
|
23
|
-
|
|
24
|
-
std::string* encryptionKeyPtr = encryptionKey.size() > 0 ? &encryptionKey : nullptr;
|
|
25
|
-
size_t defaultExpectedCapacity = 0;
|
|
26
|
-
bool useAes256Encryption = config.encryptionType.has_value() && config.encryptionType.value() == EncryptionType::AES_256;
|
|
27
|
-
MMKVMode mode = getMMKVMode(config);
|
|
28
|
-
if (config.readOnly.has_value() && config.readOnly.value()) {
|
|
29
|
-
Logger::log(LogLevel::Info, TAG, "Instance is read-only!");
|
|
30
|
-
mode = mode | ::mmkv::MMKV_READ_ONLY;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
#ifdef __APPLE__
|
|
34
|
-
instance = MMKV::mmkvWithID(config.id, mode, encryptionKeyPtr, pathPtr, defaultExpectedCapacity, useAes256Encryption);
|
|
35
|
-
#else
|
|
36
|
-
instance = MMKV::mmkvWithID(config.id, DEFAULT_MMAP_SIZE, mode, encryptionKeyPtr, pathPtr, defaultExpectedCapacity, useAes256Encryption);
|
|
37
|
-
#endif
|
|
38
|
+
instance = MMKV::mmkvWithID(config.id, mmkvConfig);
|
|
38
39
|
|
|
39
40
|
if (instance == nullptr) [[unlikely]] {
|
|
40
41
|
// Check if instanceId is invalid
|
|
41
|
-
if (config.id.empty())
|
|
42
|
+
if (config.id.empty()) {
|
|
42
43
|
throw std::runtime_error("Failed to create MMKV instance! `id` cannot be empty!");
|
|
43
44
|
}
|
|
44
45
|
|
|
@@ -57,7 +58,7 @@ HybridMMKV::HybridMMKV(const Configuration& config) : HybridObject(TAG) {
|
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
// Check if path is maybe invalid
|
|
60
|
-
if (
|
|
61
|
+
if (rootPath.empty()) [[unlikely]] {
|
|
61
62
|
throw std::runtime_error("Failed to create MMKV instance! `path` cannot be empty!");
|
|
62
63
|
}
|
|
63
64
|
|
|
@@ -103,25 +104,25 @@ void HybridMMKV::set(const std::string& key, const std::variant<bool, std::share
|
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
// Pattern-match each potential value in std::variant
|
|
106
|
-
bool
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (!
|
|
107
|
+
bool successful = std::visit(overloaded{[&](bool b) {
|
|
108
|
+
// boolean
|
|
109
|
+
return instance->set(b, key);
|
|
110
|
+
},
|
|
111
|
+
[&](const std::shared_ptr<ArrayBuffer>& buf) {
|
|
112
|
+
// ArrayBuffer
|
|
113
|
+
MMBuffer buffer(buf->data(), buf->size(), MMBufferCopyFlag::MMBufferNoCopy);
|
|
114
|
+
return instance->set(std::move(buffer), key);
|
|
115
|
+
},
|
|
116
|
+
[&](const std::string& string) {
|
|
117
|
+
// string
|
|
118
|
+
return instance->set(string, key);
|
|
119
|
+
},
|
|
120
|
+
[&](double number) {
|
|
121
|
+
// number
|
|
122
|
+
return instance->set(number, key);
|
|
123
|
+
}},
|
|
124
|
+
value);
|
|
125
|
+
if (!successful) [[unlikely]] {
|
|
125
126
|
throw std::runtime_error("Failed to set value for key \"" + key + "\"!");
|
|
126
127
|
}
|
|
127
128
|
|
|
@@ -161,14 +162,7 @@ std::optional<double> HybridMMKV::getNumber(const std::string& key) {
|
|
|
161
162
|
|
|
162
163
|
std::optional<std::shared_ptr<ArrayBuffer>> HybridMMKV::getBuffer(const std::string& key) {
|
|
163
164
|
MMBuffer result;
|
|
164
|
-
#ifdef __APPLE__
|
|
165
|
-
// iOS: Convert std::string to NSString* for MMKVCore pod compatibility
|
|
166
|
-
bool hasValue = instance->getBytes(@(key.c_str()), result);
|
|
167
|
-
#else
|
|
168
|
-
// Android/other platforms: Use std::string directly (converts to
|
|
169
|
-
// std::string_view)
|
|
170
165
|
bool hasValue = instance->getBytes(key, result);
|
|
171
|
-
#endif
|
|
172
166
|
if (hasValue) {
|
|
173
167
|
return std::make_shared<ManagedMMBuffer>(std::move(result));
|
|
174
168
|
} else {
|
|
@@ -220,7 +214,7 @@ void HybridMMKV::encrypt(const std::string& key, std::optional<EncryptionType> e
|
|
|
220
214
|
|
|
221
215
|
void HybridMMKV::decrypt() {
|
|
222
216
|
bool successful = instance->reKey("");
|
|
223
|
-
if (!successful) {
|
|
217
|
+
if (!successful) [[unlikely]] {
|
|
224
218
|
throw std::runtime_error("Failed to decrypt MMKV instance!");
|
|
225
219
|
}
|
|
226
220
|
}
|
|
@@ -233,7 +227,7 @@ void HybridMMKV::trim() {
|
|
|
233
227
|
Listener HybridMMKV::addOnValueChangedListener(const std::function<void(const std::string& /* key */)>& onValueChanged) {
|
|
234
228
|
// Add listener
|
|
235
229
|
auto mmkvID = instance->mmapID();
|
|
236
|
-
auto listenerID = MMKVValueChangedListenerRegistry::addListener(
|
|
230
|
+
auto listenerID = MMKVValueChangedListenerRegistry::addListener(mmkvID, onValueChanged);
|
|
237
231
|
|
|
238
232
|
return Listener([=]() {
|
|
239
233
|
// remove()
|
|
@@ -250,14 +244,13 @@ MMKVMode HybridMMKV::getMMKVMode(const Configuration& config) {
|
|
|
250
244
|
return ::mmkv::MMKV_SINGLE_PROCESS;
|
|
251
245
|
case Mode::MULTI_PROCESS:
|
|
252
246
|
return ::mmkv::MMKV_MULTI_PROCESS;
|
|
253
|
-
default:
|
|
254
|
-
[[unlikely]] throw std::runtime_error("Invalid MMKV Mode value!");
|
|
255
247
|
}
|
|
248
|
+
throw std::runtime_error("Invalid MMKV Mode value!");
|
|
256
249
|
}
|
|
257
250
|
|
|
258
251
|
double HybridMMKV::importAllFrom(const std::shared_ptr<HybridMMKVSpec>& other) {
|
|
259
252
|
auto hybridMMKV = std::dynamic_pointer_cast<HybridMMKV>(other);
|
|
260
|
-
if (hybridMMKV == nullptr) {
|
|
253
|
+
if (hybridMMKV == nullptr) [[unlikely]] {
|
|
261
254
|
throw std::runtime_error("The given `MMKV` instance is not of type `HybridMMKV`!");
|
|
262
255
|
}
|
|
263
256
|
|
|
@@ -18,11 +18,7 @@ std::string HybridMMKVFactory::getDefaultMMKVInstanceId() {
|
|
|
18
18
|
void HybridMMKVFactory::initializeMMKV(const std::string& rootPath) {
|
|
19
19
|
Logger::log(LogLevel::Info, TAG, "Initializing MMKV with rootPath=%s", rootPath.c_str());
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
MMKVLogLevel logLevel = ::mmkv::MMKVLogDebug;
|
|
23
|
-
#else
|
|
24
|
-
MMKVLogLevel logLevel = ::mmkv::MMKVLogWarning;
|
|
25
|
-
#endif
|
|
21
|
+
MMKVLogLevel logLevel = static_cast<MMKVLogLevel>(MMKV_LOG_LEVEL);
|
|
26
22
|
MMKV::initializeMMKV(rootPath, logLevel);
|
|
27
23
|
}
|
|
28
24
|
|
package/cpp/MMKVTypes.hpp
CHANGED
|
@@ -48,3 +48,15 @@ constexpr auto MMKV_READ_ONLY = ::MMKVMode::MMKV_READ_ONLY;
|
|
|
48
48
|
*/
|
|
49
49
|
|
|
50
50
|
using namespace mmkv;
|
|
51
|
+
|
|
52
|
+
// Default MMKV log level if not configured at build time
|
|
53
|
+
#ifndef MMKV_LOG_LEVEL
|
|
54
|
+
#ifdef NITRO_DEBUG
|
|
55
|
+
#define MMKV_LOG_LEVEL 0
|
|
56
|
+
#else
|
|
57
|
+
#define MMKV_LOG_LEVEL 3
|
|
58
|
+
#endif
|
|
59
|
+
#endif
|
|
60
|
+
#if MMKV_LOG_LEVEL < 0 || MMKV_LOG_LEVEL > 4
|
|
61
|
+
#error "MMKV_LOG_LEVEL must be between 0 (Debug) and 4 (None)"
|
|
62
|
+
#endif
|
package/cpp/ManagedMMBuffer.hpp
CHANGED
|
@@ -15,7 +15,7 @@ namespace margelo::nitro::mmkv {
|
|
|
15
15
|
/**
|
|
16
16
|
An ArrayBuffer subclass that manages MMBuffer memory (by ownership).
|
|
17
17
|
*/
|
|
18
|
-
class ManagedMMBuffer : public ArrayBuffer {
|
|
18
|
+
class ManagedMMBuffer final : public ArrayBuffer {
|
|
19
19
|
public:
|
|
20
20
|
explicit ManagedMMBuffer(MMBuffer&& buffer) : _buffer(std::move(buffer)) {}
|
|
21
21
|
|
|
@@ -99,7 +99,7 @@ export interface MMKV extends HybridObject<{
|
|
|
99
99
|
recrypt(key: string | undefined): void;
|
|
100
100
|
/**
|
|
101
101
|
* Encrypts the data in this MMKV instance with the
|
|
102
|
-
* given {@linkcode key} and {@linkcode
|
|
102
|
+
* given {@linkcode key} and {@linkcode encryptionType}.
|
|
103
103
|
*
|
|
104
104
|
* If this MMKV instance is already encrypted ({@linkcode isEncrypted}),
|
|
105
105
|
* it will re-encrypt the data.
|
|
@@ -83,6 +83,14 @@ export interface Configuration {
|
|
|
83
83
|
* @default false
|
|
84
84
|
*/
|
|
85
85
|
readOnly?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* If `true`, MMKV will internally compare a value for equality before writing to
|
|
88
|
+
* disk, and if the new value is equal to what is already stored, it will skip
|
|
89
|
+
* the file write.
|
|
90
|
+
* Treat this as an optional performance optimization.
|
|
91
|
+
* @default false
|
|
92
|
+
*/
|
|
93
|
+
compareBeforeSet?: boolean;
|
|
86
94
|
}
|
|
87
95
|
export interface MMKVFactory extends HybridObject<{
|
|
88
96
|
ios: 'c++';
|
|
@@ -51,10 +51,11 @@ namespace margelo::nitro::mmkv {
|
|
|
51
51
|
std::optional<EncryptionType> encryptionType SWIFT_PRIVATE;
|
|
52
52
|
std::optional<Mode> mode SWIFT_PRIVATE;
|
|
53
53
|
std::optional<bool> readOnly SWIFT_PRIVATE;
|
|
54
|
+
std::optional<bool> compareBeforeSet SWIFT_PRIVATE;
|
|
54
55
|
|
|
55
56
|
public:
|
|
56
57
|
Configuration() = default;
|
|
57
|
-
explicit Configuration(std::string id, std::optional<std::string> path, std::optional<std::string> encryptionKey, std::optional<EncryptionType> encryptionType, std::optional<Mode> mode, std::optional<bool> readOnly): id(id), path(path), encryptionKey(encryptionKey), encryptionType(encryptionType), mode(mode), readOnly(readOnly) {}
|
|
58
|
+
explicit Configuration(std::string id, std::optional<std::string> path, std::optional<std::string> encryptionKey, std::optional<EncryptionType> encryptionType, std::optional<Mode> mode, std::optional<bool> readOnly, std::optional<bool> compareBeforeSet): id(id), path(path), encryptionKey(encryptionKey), encryptionType(encryptionType), mode(mode), readOnly(readOnly), compareBeforeSet(compareBeforeSet) {}
|
|
58
59
|
|
|
59
60
|
public:
|
|
60
61
|
friend bool operator==(const Configuration& lhs, const Configuration& rhs) = default;
|
|
@@ -75,7 +76,8 @@ namespace margelo::nitro {
|
|
|
75
76
|
JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "encryptionKey"))),
|
|
76
77
|
JSIConverter<std::optional<margelo::nitro::mmkv::EncryptionType>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "encryptionType"))),
|
|
77
78
|
JSIConverter<std::optional<margelo::nitro::mmkv::Mode>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "mode"))),
|
|
78
|
-
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "readOnly")))
|
|
79
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "readOnly"))),
|
|
80
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "compareBeforeSet")))
|
|
79
81
|
);
|
|
80
82
|
}
|
|
81
83
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::mmkv::Configuration& arg) {
|
|
@@ -86,6 +88,7 @@ namespace margelo::nitro {
|
|
|
86
88
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "encryptionType"), JSIConverter<std::optional<margelo::nitro::mmkv::EncryptionType>>::toJSI(runtime, arg.encryptionType));
|
|
87
89
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "mode"), JSIConverter<std::optional<margelo::nitro::mmkv::Mode>>::toJSI(runtime, arg.mode));
|
|
88
90
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "readOnly"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.readOnly));
|
|
91
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "compareBeforeSet"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.compareBeforeSet));
|
|
89
92
|
return obj;
|
|
90
93
|
}
|
|
91
94
|
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
@@ -102,6 +105,7 @@ namespace margelo::nitro {
|
|
|
102
105
|
if (!JSIConverter<std::optional<margelo::nitro::mmkv::EncryptionType>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "encryptionType")))) return false;
|
|
103
106
|
if (!JSIConverter<std::optional<margelo::nitro::mmkv::Mode>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "mode")))) return false;
|
|
104
107
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "readOnly")))) return false;
|
|
108
|
+
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "compareBeforeSet")))) return false;
|
|
105
109
|
return true;
|
|
106
110
|
}
|
|
107
111
|
};
|
package/package.json
CHANGED
package/src/specs/MMKV.nitro.ts
CHANGED
|
@@ -98,7 +98,7 @@ export interface MMKV extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
|
|
|
98
98
|
recrypt(key: string | undefined): void
|
|
99
99
|
/**
|
|
100
100
|
* Encrypts the data in this MMKV instance with the
|
|
101
|
-
* given {@linkcode key} and {@linkcode
|
|
101
|
+
* given {@linkcode key} and {@linkcode encryptionType}.
|
|
102
102
|
*
|
|
103
103
|
* If this MMKV instance is already encrypted ({@linkcode isEncrypted}),
|
|
104
104
|
* it will re-encrypt the data.
|
|
@@ -86,6 +86,14 @@ export interface Configuration {
|
|
|
86
86
|
* @default false
|
|
87
87
|
*/
|
|
88
88
|
readOnly?: boolean
|
|
89
|
+
/**
|
|
90
|
+
* If `true`, MMKV will internally compare a value for equality before writing to
|
|
91
|
+
* disk, and if the new value is equal to what is already stored, it will skip
|
|
92
|
+
* the file write.
|
|
93
|
+
* Treat this as an optional performance optimization.
|
|
94
|
+
* @default false
|
|
95
|
+
*/
|
|
96
|
+
compareBeforeSet?: boolean
|
|
89
97
|
}
|
|
90
98
|
|
|
91
99
|
export interface MMKVFactory
|