react-native-mmkv 4.0.0-beta.8 → 4.0.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 -1
- package/android/build.gradle +3 -3
- package/cpp/HybridMMKV.cpp +38 -10
- package/cpp/HybridMMKV.hpp +2 -2
- package/lib/createMMKV/createMMKV.js +1 -1
- package/lib/createMMKV/createMMKV.web.d.ts +1 -1
- package/lib/createMMKV/createMMKV.web.js +14 -2
- package/lib/createMMKV/{createMMKV.mock.js → createMockMMKV.js} +3 -0
- package/lib/specs/MMKV.nitro.d.ts +5 -3
- package/nitrogen/generated/android/NitroMmkv+autolinking.cmake +7 -4
- package/nitrogen/generated/android/NitroMmkvOnLoad.cpp +1 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/mmkv/HybridMMKVPlatformContextSpec.kt +2 -2
- package/nitrogen/generated/ios/NitroMmkv-Swift-Cxx-Bridge.cpp +2 -2
- package/nitrogen/generated/ios/NitroMmkv-Swift-Cxx-Bridge.hpp +2 -2
- package/nitrogen/generated/shared/c++/Configuration.hpp +8 -0
- package/nitrogen/generated/shared/c++/HybridMMKVSpec.hpp +2 -4
- package/nitrogen/generated/shared/c++/Listener.hpp +8 -0
- package/package.json +8 -8
- package/src/createMMKV/createMMKV.ts +1 -1
- package/src/createMMKV/createMMKV.web.ts +15 -2
- package/src/createMMKV/{createMMKV.mock.ts → createMockMMKV.ts} +2 -0
- package/src/specs/MMKV.nitro.ts +5 -3
- package/app.plugin.js +0 -1
- package/lib/expo-plugin/withMMKV.d.ts +0 -3
- package/lib/expo-plugin/withMMKV.js +0 -17
- package/src/expo-plugin/withMMKV.ts +0 -23
- /package/lib/createMMKV/{createMMKV.mock.d.ts → createMockMMKV.d.ts} +0 -0
package/NitroMmkv.podspec
CHANGED
|
@@ -25,7 +25,15 @@ Pod::Spec.new do |s|
|
|
|
25
25
|
# Add MMKV Core dependency
|
|
26
26
|
s.compiler_flags = '-x objective-c++'
|
|
27
27
|
s.libraries = 'z', 'c++'
|
|
28
|
-
s.dependency 'MMKVCore', '
|
|
28
|
+
s.dependency 'MMKVCore', '2.2.4'
|
|
29
|
+
|
|
30
|
+
# TODO: Remove when no one uses RN 0.79 anymore
|
|
31
|
+
# Add support for React Native 0.79 or below
|
|
32
|
+
s.pod_target_xcconfig = {
|
|
33
|
+
"HEADER_SEARCH_PATHS" => ["${PODS_ROOT}/RCT-Folly"],
|
|
34
|
+
"GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) FOLLY_NO_CONFIG FOLLY_CFG_NO_COROUTINES",
|
|
35
|
+
"OTHER_CPLUSPLUSFLAGS" => "$(inherited) -DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1"
|
|
36
|
+
}
|
|
29
37
|
|
|
30
38
|
load 'nitrogen/generated/ios/NitroMmkv+autolinking.rb'
|
|
31
39
|
add_nitrogen_files(s)
|
package/android/build.gradle
CHANGED
|
@@ -5,13 +5,13 @@ buildscript {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
dependencies {
|
|
8
|
-
classpath "com.android.tools.build:gradle:8.
|
|
8
|
+
classpath "com.android.tools.build:gradle:8.13.0"
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
def reactNativeArchitectures() {
|
|
13
13
|
def value = rootProject.getProperties().get("reactNativeArchitectures")
|
|
14
|
-
return value ? value.split(",") : ["x86_64", "arm64-v8a"]
|
|
14
|
+
return value ? value.split(",") : ["x86", "x86_64", "armeabi-v7a", "arm64-v8a"]
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
def isNewArchitectureEnabled() {
|
|
@@ -139,6 +139,6 @@ dependencies {
|
|
|
139
139
|
implementation project(":react-native-nitro-modules")
|
|
140
140
|
|
|
141
141
|
// Add a dependency on mmkv core (this ships a C++ prefab)
|
|
142
|
-
implementation "
|
|
142
|
+
implementation "io.github.zhongwuzw:mmkv:2.2.4"
|
|
143
143
|
}
|
|
144
144
|
|
package/cpp/HybridMMKV.cpp
CHANGED
|
@@ -70,15 +70,33 @@ struct overloaded : Ts... {
|
|
|
70
70
|
template <class... Ts>
|
|
71
71
|
overloaded(Ts...) -> overloaded<Ts...>;
|
|
72
72
|
|
|
73
|
-
void HybridMMKV::set(const std::string& key, const std::variant<
|
|
73
|
+
void HybridMMKV::set(const std::string& key, const std::variant<bool, std::shared_ptr<ArrayBuffer>, std::string, double>& value) {
|
|
74
|
+
if (key.empty()) [[unlikely]] {
|
|
75
|
+
throw std::runtime_error("Cannot set a value for an empty key!");
|
|
76
|
+
}
|
|
77
|
+
|
|
74
78
|
// Pattern-match each potential value in std::variant
|
|
75
|
-
std::visit(overloaded{[&](
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
bool didSet = std::visit(overloaded{[&](bool b) {
|
|
80
|
+
// boolean
|
|
81
|
+
return instance->set(b, key);
|
|
82
|
+
},
|
|
83
|
+
[&](const std::shared_ptr<ArrayBuffer>& buf) {
|
|
84
|
+
// ArrayBuffer
|
|
85
|
+
MMBuffer buffer(buf->data(), buf->size(), MMBufferCopyFlag::MMBufferNoCopy);
|
|
86
|
+
return instance->set(std::move(buffer), key);
|
|
87
|
+
},
|
|
88
|
+
[&](const std::string& string) {
|
|
89
|
+
// string
|
|
90
|
+
return instance->set(string, key);
|
|
91
|
+
},
|
|
92
|
+
[&](double number) {
|
|
93
|
+
// number
|
|
94
|
+
return instance->set(number, key);
|
|
95
|
+
}},
|
|
96
|
+
value);
|
|
97
|
+
if (!didSet) {
|
|
98
|
+
throw std::runtime_error("Failed to set value for key \"" + key + "\"!");
|
|
99
|
+
}
|
|
82
100
|
|
|
83
101
|
// Notify on changed
|
|
84
102
|
MMKVValueChangedListenerRegistry::notifyOnValueChanged(instance->mmapID(), key);
|
|
@@ -129,14 +147,24 @@ std::optional<std::shared_ptr<ArrayBuffer>> HybridMMKV::getBuffer(const std::str
|
|
|
129
147
|
bool HybridMMKV::contains(const std::string& key) {
|
|
130
148
|
return instance->containsKey(key);
|
|
131
149
|
}
|
|
132
|
-
|
|
133
|
-
instance->removeValueForKey(key);
|
|
150
|
+
bool HybridMMKV::remove(const std::string& key) {
|
|
151
|
+
bool wasRemoved = instance->removeValueForKey(key);
|
|
152
|
+
if (wasRemoved) {
|
|
153
|
+
// Notify on changed
|
|
154
|
+
MMKVValueChangedListenerRegistry::notifyOnValueChanged(instance->mmapID(), key);
|
|
155
|
+
}
|
|
156
|
+
return wasRemoved;
|
|
134
157
|
}
|
|
135
158
|
std::vector<std::string> HybridMMKV::getAllKeys() {
|
|
136
159
|
return instance->allKeys();
|
|
137
160
|
}
|
|
138
161
|
void HybridMMKV::clearAll() {
|
|
162
|
+
auto keysBefore = getAllKeys();
|
|
139
163
|
instance->clearAll();
|
|
164
|
+
for (const auto& key : keysBefore) {
|
|
165
|
+
// Notify on changed
|
|
166
|
+
MMKVValueChangedListenerRegistry::notifyOnValueChanged(instance->mmapID(), key);
|
|
167
|
+
}
|
|
140
168
|
}
|
|
141
169
|
void HybridMMKV::recrypt(const std::optional<std::string>& key) {
|
|
142
170
|
bool successful = false;
|
package/cpp/HybridMMKV.hpp
CHANGED
|
@@ -24,13 +24,13 @@ public:
|
|
|
24
24
|
|
|
25
25
|
public:
|
|
26
26
|
// Methods
|
|
27
|
-
void set(const std::string& key, const std::variant<
|
|
27
|
+
void set(const std::string& key, const std::variant<bool, std::shared_ptr<ArrayBuffer>, std::string, double>& value) override;
|
|
28
28
|
std::optional<bool> getBoolean(const std::string& key) override;
|
|
29
29
|
std::optional<std::string> getString(const std::string& key) override;
|
|
30
30
|
std::optional<double> getNumber(const std::string& key) override;
|
|
31
31
|
std::optional<std::shared_ptr<ArrayBuffer>> getBuffer(const std::string& key) override;
|
|
32
32
|
bool contains(const std::string& key) override;
|
|
33
|
-
|
|
33
|
+
bool remove(const std::string& key) override;
|
|
34
34
|
std::vector<std::string> getAllKeys() override;
|
|
35
35
|
void clearAll() override;
|
|
36
36
|
void recrypt(const std::optional<std::string>& key) override;
|
|
@@ -2,7 +2,7 @@ import { NitroModules } from 'react-native-nitro-modules';
|
|
|
2
2
|
import { Platform } from 'react-native';
|
|
3
3
|
import { addMemoryWarningListener } from '../addMemoryWarningListener/addMemoryWarningListener';
|
|
4
4
|
import { isTest } from '../isTest';
|
|
5
|
-
import { createMockMMKV } from './
|
|
5
|
+
import { createMockMMKV } from './createMockMMKV';
|
|
6
6
|
let factory;
|
|
7
7
|
let platformContext;
|
|
8
8
|
export function createMMKV(configuration) {
|
|
@@ -12,7 +12,7 @@ const hasAccessToLocalStorage = () => {
|
|
|
12
12
|
};
|
|
13
13
|
const KEY_WILDCARD = '\\';
|
|
14
14
|
const inMemoryStorage = new Map();
|
|
15
|
-
export function createMMKV(config) {
|
|
15
|
+
export function createMMKV(config = { id: 'mmkv.default' }) {
|
|
16
16
|
if (config.encryptionKey != null) {
|
|
17
17
|
throw new Error("MMKV: 'encryptionKey' is not supported on Web!");
|
|
18
18
|
}
|
|
@@ -55,18 +55,30 @@ export function createMMKV(config) {
|
|
|
55
55
|
}
|
|
56
56
|
return `${keyPrefix}${key}`;
|
|
57
57
|
};
|
|
58
|
+
const callListeners = (key) => {
|
|
59
|
+
listeners.forEach((l) => l(key));
|
|
60
|
+
};
|
|
58
61
|
return {
|
|
59
62
|
clearAll: () => {
|
|
60
63
|
const keys = Object.keys(storage());
|
|
61
64
|
for (const key of keys) {
|
|
62
65
|
if (key.startsWith(keyPrefix)) {
|
|
63
66
|
storage().removeItem(key);
|
|
67
|
+
callListeners(key);
|
|
64
68
|
}
|
|
65
69
|
}
|
|
66
70
|
},
|
|
67
|
-
remove: (key) =>
|
|
71
|
+
remove: (key) => {
|
|
72
|
+
const wasRemoved = storage().removeItem(prefixedKey(key)) ?? false;
|
|
73
|
+
if (wasRemoved)
|
|
74
|
+
callListeners(key);
|
|
75
|
+
return wasRemoved;
|
|
76
|
+
},
|
|
68
77
|
set: (key, value) => {
|
|
78
|
+
if (key === '')
|
|
79
|
+
throw new Error('Cannot set a value for an empty key!');
|
|
69
80
|
storage().setItem(prefixedKey(key), value.toString());
|
|
81
|
+
callListeners(key);
|
|
70
82
|
},
|
|
71
83
|
getString: (key) => storage().getItem(prefixedKey(key)) ?? undefined,
|
|
72
84
|
getNumber: (key) => {
|
|
@@ -23,8 +23,11 @@ export function createMockMMKV() {
|
|
|
23
23
|
if (deleted) {
|
|
24
24
|
notifyListeners(key);
|
|
25
25
|
}
|
|
26
|
+
return deleted;
|
|
26
27
|
},
|
|
27
28
|
set: (key, value) => {
|
|
29
|
+
if (key === '')
|
|
30
|
+
throw new Error('Cannot set a value for an empty key!');
|
|
28
31
|
storage.set(key, value);
|
|
29
32
|
notifyListeners(key);
|
|
30
33
|
},
|
|
@@ -7,9 +7,10 @@ export interface MMKV extends HybridObject<{
|
|
|
7
7
|
android: 'c++';
|
|
8
8
|
}> {
|
|
9
9
|
/**
|
|
10
|
-
* Set a value for the given
|
|
10
|
+
* Set a {@linkcode value} for the given {@linkcode key}.
|
|
11
11
|
*
|
|
12
|
-
* @throws an Error if the
|
|
12
|
+
* @throws an Error if the {@linkcode key} is empty.
|
|
13
|
+
* @throws an Error if the {@linkcode value} cannot be set.
|
|
13
14
|
*/
|
|
14
15
|
set(key: string, value: boolean | string | number | ArrayBuffer): void;
|
|
15
16
|
/**
|
|
@@ -42,8 +43,9 @@ export interface MMKV extends HybridObject<{
|
|
|
42
43
|
contains(key: string): boolean;
|
|
43
44
|
/**
|
|
44
45
|
* Removes the given `key`.
|
|
46
|
+
* @returns true if the key was removed, false otherwise
|
|
45
47
|
*/
|
|
46
|
-
remove(key: string):
|
|
48
|
+
remove(key: string): boolean;
|
|
47
49
|
/**
|
|
48
50
|
* Get all keys.
|
|
49
51
|
*
|
|
@@ -13,6 +13,12 @@
|
|
|
13
13
|
# include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/NitroMmkv+autolinking.cmake)
|
|
14
14
|
# ```
|
|
15
15
|
|
|
16
|
+
# Define a flag to check if we are building properly
|
|
17
|
+
add_definitions(-DBUILDING_NITROMMKV_WITH_GENERATED_CMAKE_PROJECT)
|
|
18
|
+
|
|
19
|
+
# Enable Raw Props parsing in react-native (for Nitro Views)
|
|
20
|
+
add_definitions(-DRN_SERIALIZABLE_STATE)
|
|
21
|
+
|
|
16
22
|
# Add all headers that were generated by Nitrogen
|
|
17
23
|
include_directories(
|
|
18
24
|
"../nitrogen/generated/shared/c++"
|
|
@@ -34,12 +40,9 @@ target_sources(
|
|
|
34
40
|
../nitrogen/generated/android/c++/JHybridMMKVPlatformContextSpec.cpp
|
|
35
41
|
)
|
|
36
42
|
|
|
37
|
-
# Define a flag to check if we are building properly
|
|
38
|
-
add_definitions(-DBUILDING_NITROMMKV_WITH_GENERATED_CMAKE_PROJECT)
|
|
39
|
-
|
|
40
43
|
# From node_modules/react-native/ReactAndroid/cmake-utils/folly-flags.cmake
|
|
41
44
|
# Used in node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake
|
|
42
|
-
|
|
45
|
+
target_compile_definitions(
|
|
43
46
|
NitroMmkv PRIVATE
|
|
44
47
|
-DFOLLY_NO_CONFIG=1
|
|
45
48
|
-DFOLLY_HAVE_CLOCK_GETTIME=1
|
|
@@ -45,8 +45,7 @@ int initialize(JavaVM* vm) {
|
|
|
45
45
|
[]() -> std::shared_ptr<HybridObject> {
|
|
46
46
|
static DefaultConstructableObject<JHybridMMKVPlatformContextSpec::javaobject> object("com/margelo/nitro/mmkv/HybridMMKVPlatformContext");
|
|
47
47
|
auto instance = object.create();
|
|
48
|
-
|
|
49
|
-
return globalRef->cthis()->shared();
|
|
48
|
+
return instance->cthis()->shared();
|
|
50
49
|
}
|
|
51
50
|
);
|
|
52
51
|
});
|
package/nitrogen/generated/android/kotlin/com/margelo/nitro/mmkv/HybridMMKVPlatformContextSpec.kt
CHANGED
|
@@ -10,7 +10,7 @@ package com.margelo.nitro.mmkv
|
|
|
10
10
|
import androidx.annotation.Keep
|
|
11
11
|
import com.facebook.jni.HybridData
|
|
12
12
|
import com.facebook.proguard.annotations.DoNotStrip
|
|
13
|
-
import com.margelo.nitro.core
|
|
13
|
+
import com.margelo.nitro.core.HybridObject
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* A Kotlin class representing the MMKVPlatformContext HybridObject.
|
|
@@ -51,6 +51,6 @@ abstract class HybridMMKVPlatformContextSpec: HybridObject() {
|
|
|
51
51
|
private external fun initHybrid(): HybridData
|
|
52
52
|
|
|
53
53
|
companion object {
|
|
54
|
-
|
|
54
|
+
protected const val TAG = "HybridMMKVPlatformContextSpec"
|
|
55
55
|
}
|
|
56
56
|
}
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
namespace margelo::nitro::mmkv::bridge::swift {
|
|
15
15
|
|
|
16
16
|
// pragma MARK: std::shared_ptr<HybridMMKVPlatformContextSpec>
|
|
17
|
-
std::shared_ptr<HybridMMKVPlatformContextSpec> create_std__shared_ptr_HybridMMKVPlatformContextSpec_(void*
|
|
17
|
+
std::shared_ptr<HybridMMKVPlatformContextSpec> create_std__shared_ptr_HybridMMKVPlatformContextSpec_(void* NON_NULL swiftUnsafePointer) noexcept {
|
|
18
18
|
NitroMmkv::HybridMMKVPlatformContextSpec_cxx swiftPart = NitroMmkv::HybridMMKVPlatformContextSpec_cxx::fromUnsafe(swiftUnsafePointer);
|
|
19
19
|
return std::make_shared<margelo::nitro::mmkv::HybridMMKVPlatformContextSpecSwift>(swiftPart);
|
|
20
20
|
}
|
|
21
|
-
void*
|
|
21
|
+
void* NON_NULL get_std__shared_ptr_HybridMMKVPlatformContextSpec_(std__shared_ptr_HybridMMKVPlatformContextSpec_ cppType) {
|
|
22
22
|
std::shared_ptr<margelo::nitro::mmkv::HybridMMKVPlatformContextSpecSwift> swiftWrapper = std::dynamic_pointer_cast<margelo::nitro::mmkv::HybridMMKVPlatformContextSpecSwift>(cppType);
|
|
23
23
|
#ifdef NITRO_DEBUG
|
|
24
24
|
if (swiftWrapper == nullptr) [[unlikely]] {
|
|
@@ -49,8 +49,8 @@ namespace margelo::nitro::mmkv::bridge::swift {
|
|
|
49
49
|
* Specialized version of `std::shared_ptr<HybridMMKVPlatformContextSpec>`.
|
|
50
50
|
*/
|
|
51
51
|
using std__shared_ptr_HybridMMKVPlatformContextSpec_ = std::shared_ptr<HybridMMKVPlatformContextSpec>;
|
|
52
|
-
std::shared_ptr<HybridMMKVPlatformContextSpec> create_std__shared_ptr_HybridMMKVPlatformContextSpec_(void*
|
|
53
|
-
void*
|
|
52
|
+
std::shared_ptr<HybridMMKVPlatformContextSpec> create_std__shared_ptr_HybridMMKVPlatformContextSpec_(void* NON_NULL swiftUnsafePointer) noexcept;
|
|
53
|
+
void* NON_NULL get_std__shared_ptr_HybridMMKVPlatformContextSpec_(std__shared_ptr_HybridMMKVPlatformContextSpec_ cppType);
|
|
54
54
|
|
|
55
55
|
// pragma MARK: std::weak_ptr<HybridMMKVPlatformContextSpec>
|
|
56
56
|
using std__weak_ptr_HybridMMKVPlatformContextSpec_ = std::weak_ptr<HybridMMKVPlatformContextSpec>;
|
|
@@ -17,6 +17,11 @@
|
|
|
17
17
|
#else
|
|
18
18
|
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
19
|
#endif
|
|
20
|
+
#if __has_include(<NitroModules/JSIHelpers.hpp>)
|
|
21
|
+
#include <NitroModules/JSIHelpers.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
20
25
|
|
|
21
26
|
// Forward declaration of `Mode` to properly resolve imports.
|
|
22
27
|
namespace margelo::nitro::mmkv { enum class Mode; }
|
|
@@ -74,6 +79,9 @@ namespace margelo::nitro {
|
|
|
74
79
|
return false;
|
|
75
80
|
}
|
|
76
81
|
jsi::Object obj = value.getObject(runtime);
|
|
82
|
+
if (!nitro::isPlainObject(runtime, obj)) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
77
85
|
if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, "id"))) return false;
|
|
78
86
|
if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "path"))) return false;
|
|
79
87
|
if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, "encryptionKey"))) return false;
|
|
@@ -13,8 +13,6 @@
|
|
|
13
13
|
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
14
|
#endif
|
|
15
15
|
|
|
16
|
-
// Forward declaration of `ArrayBuffer` to properly resolve imports.
|
|
17
|
-
namespace NitroModules { class ArrayBuffer; }
|
|
18
16
|
// Forward declaration of `Listener` to properly resolve imports.
|
|
19
17
|
namespace margelo::nitro::mmkv { struct Listener; }
|
|
20
18
|
|
|
@@ -58,13 +56,13 @@ namespace margelo::nitro::mmkv {
|
|
|
58
56
|
|
|
59
57
|
public:
|
|
60
58
|
// Methods
|
|
61
|
-
virtual void set(const std::string& key, const std::variant<
|
|
59
|
+
virtual void set(const std::string& key, const std::variant<bool, std::shared_ptr<ArrayBuffer>, std::string, double>& value) = 0;
|
|
62
60
|
virtual std::optional<bool> getBoolean(const std::string& key) = 0;
|
|
63
61
|
virtual std::optional<std::string> getString(const std::string& key) = 0;
|
|
64
62
|
virtual std::optional<double> getNumber(const std::string& key) = 0;
|
|
65
63
|
virtual std::optional<std::shared_ptr<ArrayBuffer>> getBuffer(const std::string& key) = 0;
|
|
66
64
|
virtual bool contains(const std::string& key) = 0;
|
|
67
|
-
virtual
|
|
65
|
+
virtual bool remove(const std::string& key) = 0;
|
|
68
66
|
virtual std::vector<std::string> getAllKeys() = 0;
|
|
69
67
|
virtual void clearAll() = 0;
|
|
70
68
|
virtual void recrypt(const std::optional<std::string>& key) = 0;
|
|
@@ -17,6 +17,11 @@
|
|
|
17
17
|
#else
|
|
18
18
|
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
19
|
#endif
|
|
20
|
+
#if __has_include(<NitroModules/JSIHelpers.hpp>)
|
|
21
|
+
#include <NitroModules/JSIHelpers.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
20
25
|
|
|
21
26
|
|
|
22
27
|
|
|
@@ -59,6 +64,9 @@ namespace margelo::nitro {
|
|
|
59
64
|
return false;
|
|
60
65
|
}
|
|
61
66
|
jsi::Object obj = value.getObject(runtime);
|
|
67
|
+
if (!nitro::isPlainObject(runtime, obj)) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
62
70
|
if (!JSIConverter<std::function<void()>>::canConvert(runtime, obj.getProperty(runtime, "remove"))) return false;
|
|
63
71
|
return true;
|
|
64
72
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-mmkv",
|
|
3
|
-
"version": "4.0.0
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
|
+
"description": "⚡️ The fastest key/value storage for React Native.",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"module": "lib/index",
|
|
7
7
|
"types": "lib/index.d.ts",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"lint": "eslint \"**/*.{js,ts,tsx}\" --fix",
|
|
38
38
|
"lint-ci": "eslint \"**/*.{js,ts,tsx}\" -f @jamesacarr/github-actions",
|
|
39
39
|
"typescript": "tsc",
|
|
40
|
-
"specs": "tsc &&
|
|
40
|
+
"specs": "tsc && nitrogen --logLevel=\"debug\"",
|
|
41
41
|
"build": "tsc --noEmit false",
|
|
42
42
|
"release": "release-it",
|
|
43
43
|
"test": "jest"
|
|
@@ -61,18 +61,18 @@
|
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@expo/config-plugins": "^10.1.2",
|
|
64
|
-
"@react-native/eslint-config": "0.
|
|
64
|
+
"@react-native/eslint-config": "0.82.0",
|
|
65
65
|
"@testing-library/react-native": "^13.3.1",
|
|
66
66
|
"@types/jest": "^29.5.12",
|
|
67
67
|
"@types/react": "^19.0.6",
|
|
68
68
|
"eslint": "^8.57.0",
|
|
69
69
|
"eslint-config-prettier": "^9.1.0",
|
|
70
70
|
"eslint-plugin-prettier": "^5.2.1",
|
|
71
|
-
"
|
|
71
|
+
"nitrogen": "0.31.0",
|
|
72
72
|
"prettier": "^3.3.3",
|
|
73
|
-
"react": "19.1.
|
|
74
|
-
"react-native": "0.
|
|
75
|
-
"react-native-nitro-modules": "
|
|
73
|
+
"react": "19.1.1",
|
|
74
|
+
"react-native": "0.82.0",
|
|
75
|
+
"react-native-nitro-modules": "0.31.0",
|
|
76
76
|
"typescript": "^5.8.3"
|
|
77
77
|
},
|
|
78
78
|
"peerDependencies": {
|
|
@@ -5,7 +5,7 @@ import type { MMKVPlatformContext } from '../specs/MMKVPlatformContext.nitro'
|
|
|
5
5
|
import { Platform } from 'react-native'
|
|
6
6
|
import { addMemoryWarningListener } from '../addMemoryWarningListener/addMemoryWarningListener'
|
|
7
7
|
import { isTest } from '../isTest'
|
|
8
|
-
import { createMockMMKV } from './
|
|
8
|
+
import { createMockMMKV } from './createMockMMKV'
|
|
9
9
|
|
|
10
10
|
let factory: MMKVFactory | undefined
|
|
11
11
|
let platformContext: MMKVPlatformContext | undefined
|
|
@@ -19,7 +19,9 @@ const hasAccessToLocalStorage = () => {
|
|
|
19
19
|
const KEY_WILDCARD = '\\'
|
|
20
20
|
const inMemoryStorage = new Map<string, string>()
|
|
21
21
|
|
|
22
|
-
export function createMMKV(
|
|
22
|
+
export function createMMKV(
|
|
23
|
+
config: Configuration = { id: 'mmkv.default' }
|
|
24
|
+
): MMKV {
|
|
23
25
|
if (config.encryptionKey != null) {
|
|
24
26
|
throw new Error("MMKV: 'encryptionKey' is not supported on Web!")
|
|
25
27
|
}
|
|
@@ -78,18 +80,29 @@ export function createMMKV(config: Configuration): MMKV {
|
|
|
78
80
|
return `${keyPrefix}${key}`
|
|
79
81
|
}
|
|
80
82
|
|
|
83
|
+
const callListeners = (key: string) => {
|
|
84
|
+
listeners.forEach((l) => l(key))
|
|
85
|
+
}
|
|
86
|
+
|
|
81
87
|
return {
|
|
82
88
|
clearAll: () => {
|
|
83
89
|
const keys = Object.keys(storage())
|
|
84
90
|
for (const key of keys) {
|
|
85
91
|
if (key.startsWith(keyPrefix)) {
|
|
86
92
|
storage().removeItem(key)
|
|
93
|
+
callListeners(key)
|
|
87
94
|
}
|
|
88
95
|
}
|
|
89
96
|
},
|
|
90
|
-
remove: (key) =>
|
|
97
|
+
remove: (key) => {
|
|
98
|
+
const wasRemoved = storage().removeItem(prefixedKey(key)) ?? false
|
|
99
|
+
if (wasRemoved) callListeners(key)
|
|
100
|
+
return wasRemoved
|
|
101
|
+
},
|
|
91
102
|
set: (key, value) => {
|
|
103
|
+
if (key === '') throw new Error('Cannot set a value for an empty key!')
|
|
92
104
|
storage().setItem(prefixedKey(key), value.toString())
|
|
105
|
+
callListeners(key)
|
|
93
106
|
},
|
|
94
107
|
getString: (key) => storage().getItem(prefixedKey(key)) ?? undefined,
|
|
95
108
|
getNumber: (key) => {
|
|
@@ -27,8 +27,10 @@ export function createMockMMKV(): MMKV {
|
|
|
27
27
|
if (deleted) {
|
|
28
28
|
notifyListeners(key)
|
|
29
29
|
}
|
|
30
|
+
return deleted
|
|
30
31
|
},
|
|
31
32
|
set: (key, value) => {
|
|
33
|
+
if (key === '') throw new Error('Cannot set a value for an empty key!')
|
|
32
34
|
storage.set(key, value)
|
|
33
35
|
notifyListeners(key)
|
|
34
36
|
},
|
package/src/specs/MMKV.nitro.ts
CHANGED
|
@@ -6,9 +6,10 @@ export interface Listener {
|
|
|
6
6
|
|
|
7
7
|
export interface MMKV extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
|
|
8
8
|
/**
|
|
9
|
-
* Set a value for the given
|
|
9
|
+
* Set a {@linkcode value} for the given {@linkcode key}.
|
|
10
10
|
*
|
|
11
|
-
* @throws an Error if the
|
|
11
|
+
* @throws an Error if the {@linkcode key} is empty.
|
|
12
|
+
* @throws an Error if the {@linkcode value} cannot be set.
|
|
12
13
|
*/
|
|
13
14
|
set(key: string, value: boolean | string | number | ArrayBuffer): void
|
|
14
15
|
/**
|
|
@@ -41,8 +42,9 @@ export interface MMKV extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
|
|
|
41
42
|
contains(key: string): boolean
|
|
42
43
|
/**
|
|
43
44
|
* Removes the given `key`.
|
|
45
|
+
* @returns true if the key was removed, false otherwise
|
|
44
46
|
*/
|
|
45
|
-
remove(key: string):
|
|
47
|
+
remove(key: string): boolean
|
|
46
48
|
/**
|
|
47
49
|
* Get all keys.
|
|
48
50
|
*
|
package/app.plugin.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = require('./lib/commonjs/expo-plugin/withMMKV')
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { createRunOncePlugin, withGradleProperties } from '@expo/config-plugins';
|
|
2
|
-
const pkg = require('../../package.json');
|
|
3
|
-
const withMMKV = (config) => {
|
|
4
|
-
// remove 32-bit architectures from gradle.properties
|
|
5
|
-
return withGradleProperties(config, (cfg) => {
|
|
6
|
-
// Drop any existing entry…
|
|
7
|
-
cfg.modResults = cfg.modResults.filter((p) => !(p.type === 'property' && p.key === 'reactNativeArchitectures'));
|
|
8
|
-
// …and force 64-bit only.
|
|
9
|
-
cfg.modResults.push({
|
|
10
|
-
type: 'property',
|
|
11
|
-
key: 'reactNativeArchitectures',
|
|
12
|
-
value: 'arm64-v8a,x86_64',
|
|
13
|
-
});
|
|
14
|
-
return cfg;
|
|
15
|
-
});
|
|
16
|
-
};
|
|
17
|
-
export default createRunOncePlugin(withMMKV, pkg.name, pkg.version);
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { ConfigPlugin } from '@expo/config-plugins'
|
|
2
|
-
import { createRunOncePlugin, withGradleProperties } from '@expo/config-plugins'
|
|
3
|
-
|
|
4
|
-
const pkg = require('../../package.json')
|
|
5
|
-
|
|
6
|
-
const withMMKV: ConfigPlugin<{}> = (config) => {
|
|
7
|
-
// remove 32-bit architectures from gradle.properties
|
|
8
|
-
return withGradleProperties(config, (cfg) => {
|
|
9
|
-
// Drop any existing entry…
|
|
10
|
-
cfg.modResults = cfg.modResults.filter(
|
|
11
|
-
(p) => !(p.type === 'property' && p.key === 'reactNativeArchitectures')
|
|
12
|
-
)
|
|
13
|
-
// …and force 64-bit only.
|
|
14
|
-
cfg.modResults.push({
|
|
15
|
-
type: 'property',
|
|
16
|
-
key: 'reactNativeArchitectures',
|
|
17
|
-
value: 'arm64-v8a,x86_64',
|
|
18
|
-
})
|
|
19
|
-
return cfg
|
|
20
|
-
})
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export default createRunOncePlugin(withMMKV, pkg.name, pkg.version)
|
|
File without changes
|