react-native-mmkv 2.2.0 → 2.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/MMKV/CHANGELOG.md +14 -0
- package/MMKV/Core/Core.xcodeproj/project.pbxproj +1 -1
- package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/Core.xcscheme +1 -1
- package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/MMKVWatchCore.xcscheme +1 -1
- package/MMKV/Core/MMKV.cpp +70 -7
- package/MMKV/Core/MMKV.h +9 -7
- package/MMKV/Core/MMKVPredef.h +1 -1
- package/MMKV/README.md +19 -19
- package/README.md +5 -1
- package/android/src/main/cpp/MmkvHostObject.cpp +79 -56
- package/ios/JSIUtils.mm +24 -25
- package/ios/MmkvHostObject.mm +44 -17
- package/ios/MmkvModule.mm +4 -1
- package/lib/commonjs/MMKV.js.map +1 -1
- package/lib/commonjs/hooks.js.map +1 -1
- package/lib/module/MMKV.js.map +1 -1
- package/lib/module/hooks.js.map +1 -1
- package/lib/typescript/MMKV.d.ts +9 -9
- package/lib/typescript/hooks.d.ts +2 -2
- package/package.json +1 -1
- package/react-native-mmkv.podspec +1 -1
package/MMKV/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# MMKV Change Log
|
|
2
2
|
|
|
3
|
+
## v1.2.13 / 2022-03-30
|
|
4
|
+
|
|
5
|
+
### Android
|
|
6
|
+
* Fix crash on using Ashmem while `MMKV_DISABLE_CRYPT` macro is defined.
|
|
7
|
+
|
|
8
|
+
### iOS
|
|
9
|
+
* Add ability to retrieve key existece while getting value, aka `-[MMKV getXXX:forKey:hasValue:]` methods.
|
|
10
|
+
|
|
11
|
+
### POSIX
|
|
12
|
+
* Add ability to retrieve key existece while getting value, aka `MMKV::getXXX(key, defaultValue, hasValue)` methods.
|
|
13
|
+
|
|
14
|
+
### Win32
|
|
15
|
+
* Add ability to retrieve key existece while getting value, aka `MMKV::getXXX(key, defaultValue, hasValue)` methods.
|
|
16
|
+
|
|
3
17
|
## v1.2.12 / 2022-01-17
|
|
4
18
|
### Changes for All platforms
|
|
5
19
|
* Fix a bug that a subsequential `clearAll()` call may fail to take effect in multi-process mode.
|
package/MMKV/Core/MMKV.cpp
CHANGED
|
@@ -607,8 +607,11 @@ bool MMKV::getVector(MMKVKey_t key, vector<string> &result) {
|
|
|
607
607
|
|
|
608
608
|
#endif // MMKV_APPLE
|
|
609
609
|
|
|
610
|
-
bool MMKV::getBool(MMKVKey_t key, bool defaultValue) {
|
|
610
|
+
bool MMKV::getBool(MMKVKey_t key, bool defaultValue, bool *hasValue) {
|
|
611
611
|
if (isKeyEmpty(key)) {
|
|
612
|
+
if (hasValue != nullptr) {
|
|
613
|
+
*hasValue = false;
|
|
614
|
+
}
|
|
612
615
|
return defaultValue;
|
|
613
616
|
}
|
|
614
617
|
SCOPED_LOCK(m_lock);
|
|
@@ -616,16 +619,25 @@ bool MMKV::getBool(MMKVKey_t key, bool defaultValue) {
|
|
|
616
619
|
if (data.length() > 0) {
|
|
617
620
|
try {
|
|
618
621
|
CodedInputData input(data.getPtr(), data.length());
|
|
622
|
+
if (hasValue != nullptr) {
|
|
623
|
+
*hasValue = true;
|
|
624
|
+
}
|
|
619
625
|
return input.readBool();
|
|
620
626
|
} catch (std::exception &exception) {
|
|
621
627
|
MMKVError("%s", exception.what());
|
|
622
628
|
}
|
|
623
629
|
}
|
|
630
|
+
if (hasValue != nullptr) {
|
|
631
|
+
*hasValue = false;
|
|
632
|
+
}
|
|
624
633
|
return defaultValue;
|
|
625
634
|
}
|
|
626
635
|
|
|
627
|
-
int32_t MMKV::getInt32(MMKVKey_t key, int32_t defaultValue) {
|
|
636
|
+
int32_t MMKV::getInt32(MMKVKey_t key, int32_t defaultValue, bool *hasValue) {
|
|
628
637
|
if (isKeyEmpty(key)) {
|
|
638
|
+
if (hasValue != nullptr) {
|
|
639
|
+
*hasValue = false;
|
|
640
|
+
}
|
|
629
641
|
return defaultValue;
|
|
630
642
|
}
|
|
631
643
|
SCOPED_LOCK(m_lock);
|
|
@@ -633,16 +645,25 @@ int32_t MMKV::getInt32(MMKVKey_t key, int32_t defaultValue) {
|
|
|
633
645
|
if (data.length() > 0) {
|
|
634
646
|
try {
|
|
635
647
|
CodedInputData input(data.getPtr(), data.length());
|
|
648
|
+
if (hasValue != nullptr) {
|
|
649
|
+
*hasValue = true;
|
|
650
|
+
}
|
|
636
651
|
return input.readInt32();
|
|
637
652
|
} catch (std::exception &exception) {
|
|
638
653
|
MMKVError("%s", exception.what());
|
|
639
654
|
}
|
|
640
655
|
}
|
|
656
|
+
if (hasValue != nullptr) {
|
|
657
|
+
*hasValue = false;
|
|
658
|
+
}
|
|
641
659
|
return defaultValue;
|
|
642
660
|
}
|
|
643
661
|
|
|
644
|
-
uint32_t MMKV::getUInt32(MMKVKey_t key, uint32_t defaultValue) {
|
|
662
|
+
uint32_t MMKV::getUInt32(MMKVKey_t key, uint32_t defaultValue, bool *hasValue) {
|
|
645
663
|
if (isKeyEmpty(key)) {
|
|
664
|
+
if (hasValue != nullptr) {
|
|
665
|
+
*hasValue = false;
|
|
666
|
+
}
|
|
646
667
|
return defaultValue;
|
|
647
668
|
}
|
|
648
669
|
SCOPED_LOCK(m_lock);
|
|
@@ -650,16 +671,25 @@ uint32_t MMKV::getUInt32(MMKVKey_t key, uint32_t defaultValue) {
|
|
|
650
671
|
if (data.length() > 0) {
|
|
651
672
|
try {
|
|
652
673
|
CodedInputData input(data.getPtr(), data.length());
|
|
674
|
+
if (hasValue != nullptr) {
|
|
675
|
+
*hasValue = true;
|
|
676
|
+
}
|
|
653
677
|
return input.readUInt32();
|
|
654
678
|
} catch (std::exception &exception) {
|
|
655
679
|
MMKVError("%s", exception.what());
|
|
656
680
|
}
|
|
657
681
|
}
|
|
682
|
+
if (hasValue != nullptr) {
|
|
683
|
+
*hasValue = false;
|
|
684
|
+
}
|
|
658
685
|
return defaultValue;
|
|
659
686
|
}
|
|
660
687
|
|
|
661
|
-
int64_t MMKV::getInt64(MMKVKey_t key, int64_t defaultValue) {
|
|
688
|
+
int64_t MMKV::getInt64(MMKVKey_t key, int64_t defaultValue, bool *hasValue) {
|
|
662
689
|
if (isKeyEmpty(key)) {
|
|
690
|
+
if (hasValue != nullptr) {
|
|
691
|
+
*hasValue = false;
|
|
692
|
+
}
|
|
663
693
|
return defaultValue;
|
|
664
694
|
}
|
|
665
695
|
SCOPED_LOCK(m_lock);
|
|
@@ -667,16 +697,25 @@ int64_t MMKV::getInt64(MMKVKey_t key, int64_t defaultValue) {
|
|
|
667
697
|
if (data.length() > 0) {
|
|
668
698
|
try {
|
|
669
699
|
CodedInputData input(data.getPtr(), data.length());
|
|
700
|
+
if (hasValue != nullptr) {
|
|
701
|
+
*hasValue = true;
|
|
702
|
+
}
|
|
670
703
|
return input.readInt64();
|
|
671
704
|
} catch (std::exception &exception) {
|
|
672
705
|
MMKVError("%s", exception.what());
|
|
673
706
|
}
|
|
674
707
|
}
|
|
708
|
+
if (hasValue != nullptr) {
|
|
709
|
+
*hasValue = false;
|
|
710
|
+
}
|
|
675
711
|
return defaultValue;
|
|
676
712
|
}
|
|
677
713
|
|
|
678
|
-
uint64_t MMKV::getUInt64(MMKVKey_t key, uint64_t defaultValue) {
|
|
714
|
+
uint64_t MMKV::getUInt64(MMKVKey_t key, uint64_t defaultValue, bool *hasValue) {
|
|
679
715
|
if (isKeyEmpty(key)) {
|
|
716
|
+
if (hasValue != nullptr) {
|
|
717
|
+
*hasValue = false;
|
|
718
|
+
}
|
|
680
719
|
return defaultValue;
|
|
681
720
|
}
|
|
682
721
|
SCOPED_LOCK(m_lock);
|
|
@@ -684,16 +723,25 @@ uint64_t MMKV::getUInt64(MMKVKey_t key, uint64_t defaultValue) {
|
|
|
684
723
|
if (data.length() > 0) {
|
|
685
724
|
try {
|
|
686
725
|
CodedInputData input(data.getPtr(), data.length());
|
|
726
|
+
if (hasValue != nullptr) {
|
|
727
|
+
*hasValue = true;
|
|
728
|
+
}
|
|
687
729
|
return input.readUInt64();
|
|
688
730
|
} catch (std::exception &exception) {
|
|
689
731
|
MMKVError("%s", exception.what());
|
|
690
732
|
}
|
|
691
733
|
}
|
|
734
|
+
if (hasValue != nullptr) {
|
|
735
|
+
*hasValue = false;
|
|
736
|
+
}
|
|
692
737
|
return defaultValue;
|
|
693
738
|
}
|
|
694
739
|
|
|
695
|
-
float MMKV::getFloat(MMKVKey_t key, float defaultValue) {
|
|
740
|
+
float MMKV::getFloat(MMKVKey_t key, float defaultValue, bool *hasValue) {
|
|
696
741
|
if (isKeyEmpty(key)) {
|
|
742
|
+
if (hasValue != nullptr) {
|
|
743
|
+
*hasValue = false;
|
|
744
|
+
}
|
|
697
745
|
return defaultValue;
|
|
698
746
|
}
|
|
699
747
|
SCOPED_LOCK(m_lock);
|
|
@@ -701,16 +749,25 @@ float MMKV::getFloat(MMKVKey_t key, float defaultValue) {
|
|
|
701
749
|
if (data.length() > 0) {
|
|
702
750
|
try {
|
|
703
751
|
CodedInputData input(data.getPtr(), data.length());
|
|
752
|
+
if (hasValue != nullptr) {
|
|
753
|
+
*hasValue = true;
|
|
754
|
+
}
|
|
704
755
|
return input.readFloat();
|
|
705
756
|
} catch (std::exception &exception) {
|
|
706
757
|
MMKVError("%s", exception.what());
|
|
707
758
|
}
|
|
708
759
|
}
|
|
760
|
+
if (hasValue != nullptr) {
|
|
761
|
+
*hasValue = false;
|
|
762
|
+
}
|
|
709
763
|
return defaultValue;
|
|
710
764
|
}
|
|
711
765
|
|
|
712
|
-
double MMKV::getDouble(MMKVKey_t key, double defaultValue) {
|
|
766
|
+
double MMKV::getDouble(MMKVKey_t key, double defaultValue, bool *hasValue) {
|
|
713
767
|
if (isKeyEmpty(key)) {
|
|
768
|
+
if (hasValue != nullptr) {
|
|
769
|
+
*hasValue = false;
|
|
770
|
+
}
|
|
714
771
|
return defaultValue;
|
|
715
772
|
}
|
|
716
773
|
SCOPED_LOCK(m_lock);
|
|
@@ -718,11 +775,17 @@ double MMKV::getDouble(MMKVKey_t key, double defaultValue) {
|
|
|
718
775
|
if (data.length() > 0) {
|
|
719
776
|
try {
|
|
720
777
|
CodedInputData input(data.getPtr(), data.length());
|
|
778
|
+
if (hasValue != nullptr) {
|
|
779
|
+
*hasValue = true;
|
|
780
|
+
}
|
|
721
781
|
return input.readDouble();
|
|
722
782
|
} catch (std::exception &exception) {
|
|
723
783
|
MMKVError("%s", exception.what());
|
|
724
784
|
}
|
|
725
785
|
}
|
|
786
|
+
if (hasValue != nullptr) {
|
|
787
|
+
*hasValue = false;
|
|
788
|
+
}
|
|
726
789
|
return defaultValue;
|
|
727
790
|
}
|
|
728
791
|
|
package/MMKV/Core/MMKV.h
CHANGED
|
@@ -47,6 +47,8 @@ enum MMKVMode : uint32_t {
|
|
|
47
47
|
#endif
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
+
#define OUT
|
|
51
|
+
|
|
50
52
|
class MMKV {
|
|
51
53
|
#ifndef MMKV_ANDROID
|
|
52
54
|
std::string m_mmapKey;
|
|
@@ -253,19 +255,19 @@ public:
|
|
|
253
255
|
bool getVector(MMKVKey_t key, std::vector<std::string> &result);
|
|
254
256
|
#endif // MMKV_APPLE
|
|
255
257
|
|
|
256
|
-
bool getBool(MMKVKey_t key, bool defaultValue = false);
|
|
258
|
+
bool getBool(MMKVKey_t key, bool defaultValue = false, OUT bool *hasValue = nullptr);
|
|
257
259
|
|
|
258
|
-
int32_t getInt32(MMKVKey_t key, int32_t defaultValue = 0);
|
|
260
|
+
int32_t getInt32(MMKVKey_t key, int32_t defaultValue = 0, OUT bool *hasValue = nullptr);
|
|
259
261
|
|
|
260
|
-
uint32_t getUInt32(MMKVKey_t key, uint32_t defaultValue = 0);
|
|
262
|
+
uint32_t getUInt32(MMKVKey_t key, uint32_t defaultValue = 0, OUT bool *hasValue = nullptr);
|
|
261
263
|
|
|
262
|
-
int64_t getInt64(MMKVKey_t key, int64_t defaultValue = 0);
|
|
264
|
+
int64_t getInt64(MMKVKey_t key, int64_t defaultValue = 0, OUT bool *hasValue = nullptr);
|
|
263
265
|
|
|
264
|
-
uint64_t getUInt64(MMKVKey_t key, uint64_t defaultValue = 0);
|
|
266
|
+
uint64_t getUInt64(MMKVKey_t key, uint64_t defaultValue = 0, OUT bool *hasValue = nullptr);
|
|
265
267
|
|
|
266
|
-
float getFloat(MMKVKey_t key, float defaultValue = 0);
|
|
268
|
+
float getFloat(MMKVKey_t key, float defaultValue = 0, OUT bool *hasValue = nullptr);
|
|
267
269
|
|
|
268
|
-
double getDouble(MMKVKey_t key, double defaultValue = 0);
|
|
270
|
+
double getDouble(MMKVKey_t key, double defaultValue = 0, OUT bool *hasValue = nullptr);
|
|
269
271
|
|
|
270
272
|
// return the actual size consumption of the key's value
|
|
271
273
|
// pass actualSize = true to get value's length
|
package/MMKV/Core/MMKVPredef.h
CHANGED
package/MMKV/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[](https://github.com/Tencent/MMKV/blob/master/LICENSE.TXT)
|
|
2
2
|
[](https://github.com/Tencent/MMKV/pulls)
|
|
3
|
-
[](https://github.com/Tencent/MMKV/releases)
|
|
4
4
|
[](https://github.com/Tencent/MMKV/wiki/home)
|
|
5
5
|
|
|
6
6
|
中文版本请参看[这里](./README_CN.md)
|
|
@@ -11,14 +11,14 @@ MMKV is an **efficient**, **small**, **easy-to-use** mobile key-value storage fr
|
|
|
11
11
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
|
-
* **Efficient**. MMKV uses mmap to keep memory synced with
|
|
14
|
+
* **Efficient**. MMKV uses mmap to keep memory synced with files, and protobuf to encode/decode values, making the most of Android to achieve the best performance.
|
|
15
15
|
* **Multi-Process concurrency**: MMKV supports concurrent read-read and read-write access between processes.
|
|
16
16
|
|
|
17
17
|
* **Easy-to-use**. You can use MMKV as you go. All changes are saved immediately, no `sync`, no `apply` calls needed.
|
|
18
18
|
|
|
19
19
|
* **Small**.
|
|
20
|
-
* **A handful of files**: MMKV contains process locks, encode/decode helpers and mmap logics and nothing more. It's really tidy.
|
|
21
|
-
* **About 50K in binary size**: MMKV adds about 50K per architecture on App size, and much less when zipped (
|
|
20
|
+
* **A handful of files**: MMKV contains process locks, encode/decode helpers and mmap logics, and nothing more. It's really tidy.
|
|
21
|
+
* **About 50K in binary size**: MMKV adds about 50K per architecture on App size, and much less when zipped (APK).
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
## Getting Started
|
|
@@ -28,8 +28,8 @@ Add the following lines to `build.gradle` on your app module:
|
|
|
28
28
|
|
|
29
29
|
```gradle
|
|
30
30
|
dependencies {
|
|
31
|
-
implementation 'com.tencent:mmkv:1.2.
|
|
32
|
-
// replace "1.2.
|
|
31
|
+
implementation 'com.tencent:mmkv:1.2.13'
|
|
32
|
+
// replace "1.2.13" with any available version
|
|
33
33
|
}
|
|
34
34
|
```
|
|
35
35
|
|
|
@@ -78,19 +78,19 @@ For more benchmark data, please refer to [our benchmark](https://github.com/Tenc
|
|
|
78
78
|
|
|
79
79
|
## Features
|
|
80
80
|
|
|
81
|
-
* **Efficient**. MMKV uses mmap to keep memory synced with
|
|
81
|
+
* **Efficient**. MMKV uses mmap to keep memory synced with files, and protobuf to encode/decode values, making the most of iOS/macOS to achieve the best performance.
|
|
82
82
|
|
|
83
|
-
* **Easy-to-use**. You can use MMKV as you go, no configurations needed. All changes are saved immediately, no `synchronize` calls needed.
|
|
83
|
+
* **Easy-to-use**. You can use MMKV as you go, no configurations are needed. All changes are saved immediately, no `synchronize` calls are needed.
|
|
84
84
|
|
|
85
85
|
* **Small**.
|
|
86
86
|
* **A handful of files**: MMKV contains encode/decode helpers and mmap logics and nothing more. It's really tidy.
|
|
87
|
-
* **Less than 30K in binary size**: MMKV adds less than 30K per architecture on App size, and much less when zipped (
|
|
87
|
+
* **Less than 30K in binary size**: MMKV adds less than 30K per architecture on App size, and much less when zipped (IPA).
|
|
88
88
|
|
|
89
89
|
## Getting Started
|
|
90
90
|
|
|
91
91
|
### Installation Via CocoaPods:
|
|
92
92
|
1. Install [CocoaPods](https://guides.CocoaPods.org/using/getting-started.html);
|
|
93
|
-
2. Open terminal, `cd` to your project directory, run `pod repo update` to make CocoaPods aware of the latest available MMKV versions;
|
|
93
|
+
2. Open the terminal, `cd` to your project directory, run `pod repo update` to make CocoaPods aware of the latest available MMKV versions;
|
|
94
94
|
3. Edit your Podfile, add `pod 'MMKV'` to your app target;
|
|
95
95
|
4. Run `pod install`;
|
|
96
96
|
5. Open the `.xcworkspace` file generated by CocoaPods;
|
|
@@ -99,7 +99,7 @@ For more benchmark data, please refer to [our benchmark](https://github.com/Tenc
|
|
|
99
99
|
For other installation options, see [iOS/macOS Setup](https://github.com/Tencent/MMKV/wiki/iOS_setup).
|
|
100
100
|
|
|
101
101
|
### Quick Tutorial
|
|
102
|
-
You can use MMKV as you go, no configurations needed. All changes are saved immediately, no `synchronize` calls needed.
|
|
102
|
+
You can use MMKV as you go, no configurations are needed. All changes are saved immediately, no `synchronize` calls are needed.
|
|
103
103
|
Setup MMKV on App startup, in your `-[MyApp application: didFinishLaunchingWithOptions:]`, add these lines:
|
|
104
104
|
|
|
105
105
|
```objective-c
|
|
@@ -139,13 +139,13 @@ For more benchmark data, please refer to [our benchmark](https://github.com/Tenc
|
|
|
139
139
|
|
|
140
140
|
## Features
|
|
141
141
|
|
|
142
|
-
* **Efficient**. MMKV uses mmap to keep memory synced with
|
|
142
|
+
* **Efficient**. MMKV uses mmap to keep memory synced with files, and protobuf to encode/decode values, making the most of Windows to achieve the best performance.
|
|
143
143
|
* **Multi-Process concurrency**: MMKV supports concurrent read-read and read-write access between processes.
|
|
144
144
|
|
|
145
|
-
* **Easy-to-use**. You can use MMKV as you go. All changes are saved immediately, no `save`, no `sync` calls needed.
|
|
145
|
+
* **Easy-to-use**. You can use MMKV as you go. All changes are saved immediately, no `save`, no `sync` calls are needed.
|
|
146
146
|
|
|
147
147
|
* **Small**.
|
|
148
|
-
* **A handful of files**: MMKV contains process locks, encode/decode helpers and mmap logics and nothing more. It's really tidy.
|
|
148
|
+
* **A handful of files**: MMKV contains process locks, encode/decode helpers and mmap logics, and nothing more. It's really tidy.
|
|
149
149
|
* **About 10K in binary size**: MMKV adds about 10K on application size, and much less when zipped.
|
|
150
150
|
|
|
151
151
|
|
|
@@ -168,7 +168,7 @@ For more benchmark data, please refer to [our benchmark](https://github.com/Tenc
|
|
|
168
168
|
|
|
169
169
|
note:
|
|
170
170
|
|
|
171
|
-
1. MMKV is compiled with `MT/MTd` runtime by default. If your project uses `MD/MDd`, you should change MMKV's setting to match your project's (`C/C++` -> `Code Generation` -> `Runtime Library`), or
|
|
171
|
+
1. MMKV is compiled with `MT/MTd` runtime by default. If your project uses `MD/MDd`, you should change MMKV's setting to match your project's (`C/C++` -> `Code Generation` -> `Runtime Library`), or vice versa.
|
|
172
172
|
2. MMKV is developed with Visual Studio 2017, change the `Platform Toolset` if you use a different version of Visual Studio.
|
|
173
173
|
|
|
174
174
|
For other installation options, see [Win32 Setup](https://github.com/Tencent/MMKV/wiki/windows_setup).
|
|
@@ -210,20 +210,20 @@ MMKV also supports **Multi-Process Access**. Full tutorials can be found here [W
|
|
|
210
210
|
|
|
211
211
|
## Features
|
|
212
212
|
|
|
213
|
-
* **Efficient**. MMKV uses mmap to keep memory synced with
|
|
213
|
+
* **Efficient**. MMKV uses mmap to keep memory synced with files, and protobuf to encode/decode values, making the most of POSIX to achieve the best performance.
|
|
214
214
|
* **Multi-Process concurrency**: MMKV supports concurrent read-read and read-write access between processes.
|
|
215
215
|
|
|
216
|
-
* **Easy-to-use**. You can use MMKV as you go. All changes are saved immediately, no `save`, no `sync` calls needed.
|
|
216
|
+
* **Easy-to-use**. You can use MMKV as you go. All changes are saved immediately, no `save`, no `sync` calls are needed.
|
|
217
217
|
|
|
218
218
|
* **Small**.
|
|
219
|
-
* **A handful of files**: MMKV contains process locks, encode/decode helpers and mmap logics and nothing more. It's really tidy.
|
|
219
|
+
* **A handful of files**: MMKV contains process locks, encode/decode helpers and mmap logics, and nothing more. It's really tidy.
|
|
220
220
|
* **About 7K in binary size**: MMKV adds about 7K on application size, and much less when zipped.
|
|
221
221
|
|
|
222
222
|
|
|
223
223
|
## Getting Started
|
|
224
224
|
|
|
225
225
|
### Installation Via CMake
|
|
226
|
-
1. Getting source code from git repository:
|
|
226
|
+
1. Getting source code from the git repository:
|
|
227
227
|
|
|
228
228
|
```
|
|
229
229
|
git clone https://github.com/Tencent/MMKV.git
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* **Encryption** support (secure storage)
|
|
30
30
|
* **Multiple instances** support (separate user-data with global data)
|
|
31
31
|
* **Customize storage location**
|
|
32
|
-
* **High performance** because everything is **written in C++**
|
|
32
|
+
* **High performance** because everything is **written in C++**
|
|
33
33
|
* **~30x faster than AsyncStorage**
|
|
34
34
|
* Uses [**JSI**](https://github.com/react-native-community/discussions-and-proposals/issues/91) instead of the "old" Bridge
|
|
35
35
|
* **iOS**, **Android** and **Web** support
|
|
@@ -181,6 +181,10 @@ storage.recrypt(undefined)
|
|
|
181
181
|
|
|
182
182
|
As the library uses JSI for synchronous native methods access, remote debugging (e.g. with Chrome) is no longer possible. Instead, you should use [Flipper](https://fbflipper.com).
|
|
183
183
|
|
|
184
|
+
## Debugging
|
|
185
|
+
|
|
186
|
+
Use [flipper-plugin-react-native-mmkv](https://github.com/muchobien/flipper-plugin-react-native-mmkv) to debug your MMKV storage using Flipper. You can also simply `console.log` an MMKV instance.
|
|
187
|
+
|
|
184
188
|
## Adopting at scale
|
|
185
189
|
|
|
186
190
|
react-native-mmkv is provided _as is_, I work on it in my free time.
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
#include "MmkvHostObject.h"
|
|
10
10
|
#include <MMKV.h>
|
|
11
11
|
#include <android/log.h>
|
|
12
|
+
#include <string>
|
|
12
13
|
|
|
13
14
|
MmkvHostObject::MmkvHostObject(const std::string& instanceId, std::string path, std::string cryptKey) {
|
|
14
15
|
__android_log_print(ANDROID_LOG_INFO, "RNMMKV", "Creating MMKV instance \"%s\"... (Path: %s, Encryption-Key: %s)",
|
|
@@ -59,21 +60,23 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
59
60
|
const jsi::Value& thisValue,
|
|
60
61
|
const jsi::Value* arguments,
|
|
61
62
|
size_t count) -> jsi::Value {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
63
|
+
if (!arguments[0].isString()) {
|
|
64
|
+
throw jsi::JSError(runtime, "MMKV::set: First argument ('key') has to be of type string!");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
auto keyName = arguments[0].getString(runtime).utf8(runtime);
|
|
68
|
+
if (arguments[1].isBool()) {
|
|
69
|
+
instance->set(arguments[1].getBool(), keyName);
|
|
70
|
+
} else if (arguments[1].isNumber()) {
|
|
71
|
+
instance->set(arguments[1].getNumber(), keyName);
|
|
72
|
+
} else if (arguments[1].isString()) {
|
|
73
|
+
auto stringValue = arguments[1].getString(runtime).utf8(runtime);
|
|
74
|
+
instance->set(stringValue, keyName);
|
|
75
|
+
} else {
|
|
76
|
+
throw jsi::JSError(runtime, "MMKV::set: 'value' argument is not of type bool, number or string!");
|
|
77
|
+
}
|
|
78
|
+
return jsi::Value::undefined();
|
|
79
|
+
});
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
if (propName == "getBoolean") {
|
|
@@ -85,11 +88,19 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
85
88
|
const jsi::Value& thisValue,
|
|
86
89
|
const jsi::Value* arguments,
|
|
87
90
|
size_t count) -> jsi::Value {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
if (!arguments[0].isString()) {
|
|
92
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
auto keyName = arguments[0].getString(runtime).utf8(runtime);
|
|
96
|
+
bool hasValue;
|
|
97
|
+
auto value = instance->getBool(keyName, false, &hasValue);
|
|
98
|
+
if (hasValue) {
|
|
99
|
+
return jsi::Value(value);
|
|
100
|
+
} else {
|
|
101
|
+
return jsi::Value::undefined();
|
|
102
|
+
}
|
|
103
|
+
});
|
|
93
104
|
}
|
|
94
105
|
|
|
95
106
|
if (propName == "getString") {
|
|
@@ -101,17 +112,19 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
101
112
|
const jsi::Value& thisValue,
|
|
102
113
|
const jsi::Value* arguments,
|
|
103
114
|
size_t count) -> jsi::Value {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
115
|
+
if (!arguments[0].isString()) {
|
|
116
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
117
|
+
}
|
|
107
118
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
119
|
+
auto keyName = arguments[0].getString(runtime).utf8(runtime);
|
|
120
|
+
std::string result;
|
|
121
|
+
bool hasValue = instance->getString(keyName, result);
|
|
122
|
+
if (hasValue) {
|
|
123
|
+
return jsi::Value(runtime, jsi::String::createFromUtf8(runtime, result));
|
|
124
|
+
} else {
|
|
125
|
+
return jsi::Value::undefined();
|
|
126
|
+
}
|
|
127
|
+
});
|
|
115
128
|
}
|
|
116
129
|
|
|
117
130
|
if (propName == "getNumber") {
|
|
@@ -123,12 +136,19 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
123
136
|
const jsi::Value& thisValue,
|
|
124
137
|
const jsi::Value* arguments,
|
|
125
138
|
size_t count) -> jsi::Value {
|
|
126
|
-
|
|
127
|
-
|
|
139
|
+
if (!arguments[0].isString()) {
|
|
140
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
141
|
+
}
|
|
128
142
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
143
|
+
auto keyName = arguments[0].getString(runtime).utf8(runtime);
|
|
144
|
+
bool hasValue;
|
|
145
|
+
auto value = instance->getDouble(keyName, 0.0, &hasValue);
|
|
146
|
+
if (hasValue) {
|
|
147
|
+
return jsi::Value(value);
|
|
148
|
+
} else {
|
|
149
|
+
return jsi::Value::undefined();
|
|
150
|
+
}
|
|
151
|
+
});
|
|
132
152
|
}
|
|
133
153
|
|
|
134
154
|
if (propName == "contains") {
|
|
@@ -140,12 +160,14 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
140
160
|
const jsi::Value& thisValue,
|
|
141
161
|
const jsi::Value* arguments,
|
|
142
162
|
size_t count) -> jsi::Value {
|
|
143
|
-
|
|
144
|
-
|
|
163
|
+
if (!arguments[0].isString()) {
|
|
164
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
165
|
+
}
|
|
145
166
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
167
|
+
auto keyName = arguments[0].getString(runtime).utf8(runtime);
|
|
168
|
+
bool containsKey = instance->containsKey(keyName);
|
|
169
|
+
return jsi::Value(containsKey);
|
|
170
|
+
});
|
|
149
171
|
}
|
|
150
172
|
|
|
151
173
|
if (propName == "delete") {
|
|
@@ -157,12 +179,14 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
157
179
|
const jsi::Value& thisValue,
|
|
158
180
|
const jsi::Value* arguments,
|
|
159
181
|
size_t count) -> jsi::Value {
|
|
160
|
-
|
|
161
|
-
|
|
182
|
+
if (!arguments[0].isString()) {
|
|
183
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
184
|
+
}
|
|
162
185
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
186
|
+
auto keyName = arguments[0].getString(runtime).utf8(runtime);
|
|
187
|
+
instance->removeValueForKey(keyName);
|
|
188
|
+
return jsi::Value::undefined();
|
|
189
|
+
});
|
|
166
190
|
}
|
|
167
191
|
|
|
168
192
|
if (propName == "getAllKeys") {
|
|
@@ -174,13 +198,13 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
174
198
|
const jsi::Value& thisValue,
|
|
175
199
|
const jsi::Value* arguments,
|
|
176
200
|
size_t count) -> jsi::Value {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
201
|
+
auto keys = instance->allKeys();
|
|
202
|
+
auto array = jsi::Array(runtime, keys.size());
|
|
203
|
+
for (int i = 0; i < keys.size(); i++) {
|
|
204
|
+
array.setValueAtIndex(runtime, i, keys[i]);
|
|
205
|
+
}
|
|
206
|
+
return array;
|
|
207
|
+
});
|
|
184
208
|
}
|
|
185
209
|
|
|
186
210
|
if (propName == "clearAll") {
|
|
@@ -192,10 +216,9 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
192
216
|
const jsi::Value& thisValue,
|
|
193
217
|
const jsi::Value* arguments,
|
|
194
218
|
size_t count) -> jsi::Value {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
});
|
|
219
|
+
instance->clearAll();
|
|
220
|
+
return jsi::Value::undefined();
|
|
221
|
+
});
|
|
199
222
|
}
|
|
200
223
|
|
|
201
224
|
if (propName == "recrypt") {
|
package/ios/JSIUtils.mm
CHANGED
|
@@ -29,6 +29,7 @@ jsi::String convertNSStringToJSIString(jsi::Runtime &runtime, NSString *value)
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
jsi::Value convertObjCObjectToJSIValue(jsi::Runtime &runtime, id value);
|
|
32
|
+
|
|
32
33
|
jsi::Object convertNSDictionaryToJSIObject(jsi::Runtime &runtime, NSDictionary *value)
|
|
33
34
|
{
|
|
34
35
|
jsi::Object result = jsi::Object(runtime);
|
|
@@ -75,16 +76,14 @@ jsi::Value convertObjCObjectToJSIValue(jsi::Runtime &runtime, id value)
|
|
|
75
76
|
return jsi::Value::undefined();
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
id convertJSIValueToObjCObject(
|
|
79
|
-
|
|
80
|
-
const jsi::Value &value);
|
|
79
|
+
id convertJSIValueToObjCObject(jsi::Runtime &runtime, const jsi::Value &value);
|
|
80
|
+
|
|
81
81
|
NSString *convertJSIStringToNSString(jsi::Runtime &runtime, const jsi::String &value)
|
|
82
82
|
{
|
|
83
83
|
return [NSString stringWithUTF8String:value.utf8(runtime).c_str()];
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
NSArray *convertJSIArrayToNSArray(
|
|
87
|
-
jsi::Runtime &runtime,
|
|
86
|
+
NSArray *convertJSIArrayToNSArray(jsi::Runtime &runtime,
|
|
88
87
|
const jsi::Array &value)
|
|
89
88
|
{
|
|
90
89
|
size_t size = value.size(runtime);
|
|
@@ -97,8 +96,7 @@ NSArray *convertJSIArrayToNSArray(
|
|
|
97
96
|
return [result copy];
|
|
98
97
|
}
|
|
99
98
|
|
|
100
|
-
NSDictionary *convertJSIObjectToNSDictionary(
|
|
101
|
-
jsi::Runtime &runtime,
|
|
99
|
+
NSDictionary *convertJSIObjectToNSDictionary(jsi::Runtime &runtime,
|
|
102
100
|
const jsi::Object &value)
|
|
103
101
|
{
|
|
104
102
|
jsi::Array propertyNames = value.getPropertyNames(runtime);
|
|
@@ -115,8 +113,7 @@ NSDictionary *convertJSIObjectToNSDictionary(
|
|
|
115
113
|
return [result copy];
|
|
116
114
|
}
|
|
117
115
|
|
|
118
|
-
RCTResponseSenderBlock convertJSIFunctionToCallback(
|
|
119
|
-
jsi::Runtime &runtime,
|
|
116
|
+
RCTResponseSenderBlock convertJSIFunctionToCallback(jsi::Runtime &runtime,
|
|
120
117
|
const jsi::Function &value)
|
|
121
118
|
{
|
|
122
119
|
__block auto cb = value.getFunction(runtime);
|
|
@@ -126,8 +123,7 @@ RCTResponseSenderBlock convertJSIFunctionToCallback(
|
|
|
126
123
|
};
|
|
127
124
|
}
|
|
128
125
|
|
|
129
|
-
id convertJSIValueToObjCObject(
|
|
130
|
-
jsi::Runtime &runtime,
|
|
126
|
+
id convertJSIValueToObjCObject(jsi::Runtime &runtime,
|
|
131
127
|
const jsi::Value &value)
|
|
132
128
|
{
|
|
133
129
|
if (value.isUndefined() || value.isNull()) {
|
|
@@ -148,7 +144,8 @@ id convertJSIValueToObjCObject(
|
|
|
148
144
|
return convertJSIArrayToNSArray(runtime, o.getArray(runtime));
|
|
149
145
|
}
|
|
150
146
|
if (o.isFunction(runtime)) {
|
|
151
|
-
return convertJSIFunctionToCallback(runtime,
|
|
147
|
+
return convertJSIFunctionToCallback(runtime,
|
|
148
|
+
std::move(o.getFunction(runtime)));
|
|
152
149
|
}
|
|
153
150
|
return convertJSIObjectToNSDictionary(runtime, o);
|
|
154
151
|
}
|
|
@@ -159,34 +156,36 @@ id convertJSIValueToObjCObject(
|
|
|
159
156
|
Promise::Promise(jsi::Runtime &rt, jsi::Function resolve, jsi::Function reject)
|
|
160
157
|
: runtime_(rt), resolve_(std::move(resolve)), reject_(std::move(reject)) {}
|
|
161
158
|
|
|
162
|
-
void Promise::resolve(const jsi::Value &result)
|
|
159
|
+
void Promise::resolve(const jsi::Value &result)
|
|
160
|
+
{
|
|
163
161
|
resolve_.call(runtime_, result);
|
|
164
162
|
}
|
|
165
163
|
|
|
166
|
-
void Promise::reject(const std::string &message)
|
|
164
|
+
void Promise::reject(const std::string &message)
|
|
165
|
+
{
|
|
167
166
|
jsi::Object error(runtime_);
|
|
168
|
-
error.setProperty(
|
|
169
|
-
|
|
167
|
+
error.setProperty(runtime_,
|
|
168
|
+
"message",
|
|
169
|
+
jsi::String::createFromUtf8(runtime_, message));
|
|
170
170
|
reject_.call(runtime_, error);
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
jsi::Value createPromiseAsJSIValue(
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
jsi::Value createPromiseAsJSIValue(jsi::Runtime &rt,
|
|
174
|
+
const PromiseSetupFunctionType func)
|
|
175
|
+
{
|
|
176
176
|
jsi::Function JSPromise = rt.global().getPropertyAsFunction(rt, "Promise");
|
|
177
|
-
jsi::Function fn = jsi::Function::createFromHostFunction(
|
|
178
|
-
rt,
|
|
177
|
+
jsi::Function fn = jsi::Function::createFromHostFunction(rt,
|
|
179
178
|
jsi::PropNameID::forAscii(rt, "fn"),
|
|
180
179
|
2,
|
|
181
|
-
[func](
|
|
182
|
-
jsi::Runtime &rt2,
|
|
180
|
+
[func](jsi::Runtime &rt2,
|
|
183
181
|
const jsi::Value &thisVal,
|
|
184
182
|
const jsi::Value *args,
|
|
185
183
|
size_t count) {
|
|
186
184
|
jsi::Function resolve = args[0].getObject(rt2).getFunction(rt2);
|
|
187
185
|
jsi::Function reject = args[1].getObject(rt2).getFunction(rt2);
|
|
188
|
-
auto wrapper = std::make_shared<Promise>(
|
|
189
|
-
|
|
186
|
+
auto wrapper = std::make_shared<Promise>(rt2,
|
|
187
|
+
std::move(resolve),
|
|
188
|
+
std::move(reject));
|
|
190
189
|
func(rt2, wrapper);
|
|
191
190
|
return jsi::Value::undefined();
|
|
192
191
|
});
|
package/ios/MmkvHostObject.mm
CHANGED
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
#import "MmkvHostObject.h"
|
|
11
11
|
#import "JSIUtils.h"
|
|
12
12
|
|
|
13
|
-
MmkvHostObject::MmkvHostObject(NSString* instanceId, NSString* path, NSString* cryptKey)
|
|
13
|
+
MmkvHostObject::MmkvHostObject(NSString* instanceId, NSString* path, NSString* cryptKey)
|
|
14
|
+
{
|
|
14
15
|
NSData* cryptData = cryptKey == nil ? nil : [cryptKey dataUsingEncoding:NSUTF8StringEncoding];
|
|
15
16
|
instance = [MMKV mmkvWithID:instanceId cryptKey:cryptData rootPath:path];
|
|
16
17
|
|
|
@@ -36,7 +37,8 @@ MmkvHostObject::MmkvHostObject(NSString* instanceId, NSString* path, NSString* c
|
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
std::vector<jsi::PropNameID> MmkvHostObject::getPropertyNames(jsi::Runtime& rt)
|
|
40
|
+
std::vector<jsi::PropNameID> MmkvHostObject::getPropertyNames(jsi::Runtime& rt)
|
|
41
|
+
{
|
|
40
42
|
std::vector<jsi::PropNameID> result;
|
|
41
43
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("set")));
|
|
42
44
|
result.push_back(jsi::PropNameID::forUtf8(rt, std::string("getBoolean")));
|
|
@@ -50,7 +52,8 @@ std::vector<jsi::PropNameID> MmkvHostObject::getPropertyNames(jsi::Runtime& rt)
|
|
|
50
52
|
return result;
|
|
51
53
|
}
|
|
52
54
|
|
|
53
|
-
jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& propNameId)
|
|
55
|
+
jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& propNameId)
|
|
56
|
+
{
|
|
54
57
|
auto propName = propNameId.utf8(runtime);
|
|
55
58
|
auto funcName = "MMKV." + propName;
|
|
56
59
|
|
|
@@ -63,9 +66,11 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
63
66
|
const jsi::Value& thisValue,
|
|
64
67
|
const jsi::Value* arguments,
|
|
65
68
|
size_t count) -> jsi::Value {
|
|
66
|
-
if (!arguments[0].isString())
|
|
67
|
-
|
|
69
|
+
if (!arguments[0].isString()) {
|
|
70
|
+
throw jsi::JSError(runtime, "MMKV::set: First argument ('key') has to be of type string!");
|
|
71
|
+
}
|
|
68
72
|
|
|
73
|
+
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
69
74
|
if (arguments[1].isBool()) {
|
|
70
75
|
[instance setBool:arguments[1].getBool() forKey:keyName];
|
|
71
76
|
} else if (arguments[1].isNumber()) {
|
|
@@ -74,8 +79,9 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
74
79
|
auto stringValue = convertJSIStringToNSString(runtime, arguments[1].getString(runtime));
|
|
75
80
|
[instance setString:stringValue forKey:keyName];
|
|
76
81
|
} else {
|
|
77
|
-
throw jsi::JSError(runtime, "
|
|
82
|
+
throw jsi::JSError(runtime, "Second argument ('value') has to be of type bool, number or string!");
|
|
78
83
|
}
|
|
84
|
+
|
|
79
85
|
return jsi::Value::undefined();
|
|
80
86
|
});
|
|
81
87
|
}
|
|
@@ -89,11 +95,18 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
89
95
|
const jsi::Value& thisValue,
|
|
90
96
|
const jsi::Value* arguments,
|
|
91
97
|
size_t count) -> jsi::Value {
|
|
92
|
-
if (!arguments[0].isString())
|
|
98
|
+
if (!arguments[0].isString()) {
|
|
99
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
100
|
+
}
|
|
93
101
|
|
|
94
102
|
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
95
|
-
bool
|
|
96
|
-
|
|
103
|
+
bool hasValue;
|
|
104
|
+
auto value = [instance getBoolForKey:keyName defaultValue:false hasValue:&hasValue];
|
|
105
|
+
if (hasValue) {
|
|
106
|
+
return jsi::Value(value);
|
|
107
|
+
} else {
|
|
108
|
+
return jsi::Value::undefined();
|
|
109
|
+
}
|
|
97
110
|
});
|
|
98
111
|
}
|
|
99
112
|
|
|
@@ -106,14 +119,17 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
106
119
|
const jsi::Value& thisValue,
|
|
107
120
|
const jsi::Value* arguments,
|
|
108
121
|
size_t count) -> jsi::Value {
|
|
109
|
-
if (!arguments[0].isString())
|
|
122
|
+
if (!arguments[0].isString()) {
|
|
123
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
124
|
+
}
|
|
110
125
|
|
|
111
126
|
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
112
127
|
auto value = [instance getStringForKey:keyName];
|
|
113
|
-
if (value != nil)
|
|
128
|
+
if (value != nil) {
|
|
114
129
|
return convertNSStringToJSIString(runtime, value);
|
|
115
|
-
else
|
|
130
|
+
} else {
|
|
116
131
|
return jsi::Value::undefined();
|
|
132
|
+
}
|
|
117
133
|
});
|
|
118
134
|
}
|
|
119
135
|
|
|
@@ -126,11 +142,18 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
126
142
|
const jsi::Value& thisValue,
|
|
127
143
|
const jsi::Value* arguments,
|
|
128
144
|
size_t count) -> jsi::Value {
|
|
129
|
-
if (!arguments[0].isString())
|
|
145
|
+
if (!arguments[0].isString()) {
|
|
146
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
147
|
+
}
|
|
130
148
|
|
|
131
149
|
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
132
|
-
|
|
133
|
-
|
|
150
|
+
bool hasValue;
|
|
151
|
+
auto value = [instance getDoubleForKey:keyName defaultValue:0.0 hasValue:&hasValue];
|
|
152
|
+
if (hasValue) {
|
|
153
|
+
return jsi::Value(value);
|
|
154
|
+
} else {
|
|
155
|
+
return jsi::Value::undefined();
|
|
156
|
+
}
|
|
134
157
|
});
|
|
135
158
|
}
|
|
136
159
|
|
|
@@ -143,7 +166,9 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
143
166
|
const jsi::Value& thisValue,
|
|
144
167
|
const jsi::Value* arguments,
|
|
145
168
|
size_t count) -> jsi::Value {
|
|
146
|
-
if (!arguments[0].isString())
|
|
169
|
+
if (!arguments[0].isString()) {
|
|
170
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
171
|
+
}
|
|
147
172
|
|
|
148
173
|
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
149
174
|
bool containsKey = [instance containsKey:keyName];
|
|
@@ -160,7 +185,9 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
|
|
|
160
185
|
const jsi::Value& thisValue,
|
|
161
186
|
const jsi::Value* arguments,
|
|
162
187
|
size_t count) -> jsi::Value {
|
|
163
|
-
if (!arguments[0].isString())
|
|
188
|
+
if (!arguments[0].isString()) {
|
|
189
|
+
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
|
|
190
|
+
}
|
|
164
191
|
|
|
165
192
|
auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
166
193
|
[instance removeValueForKey:keyName];
|
package/ios/MmkvModule.mm
CHANGED
|
@@ -14,7 +14,10 @@ using namespace facebook;
|
|
|
14
14
|
|
|
15
15
|
RCT_EXPORT_MODULE(MMKV)
|
|
16
16
|
|
|
17
|
-
+ (NSString*)getPropertyAsStringOrNilFromObject:(jsi::Object&)object
|
|
17
|
+
+ (NSString*)getPropertyAsStringOrNilFromObject:(jsi::Object&)object
|
|
18
|
+
propertyName:(std::string)propertyName
|
|
19
|
+
runtime:(jsi::Runtime&)runtime
|
|
20
|
+
{
|
|
18
21
|
jsi::Value value = object.getProperty(runtime, propertyName.c_str());
|
|
19
22
|
std::string string = value.isString() ? value.asString(runtime).utf8(runtime) : "";
|
|
20
23
|
return string.length() > 0 ? [NSString stringWithUTF8String:string.c_str()] : nil;
|
package/lib/commonjs/MMKV.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["MMKV.ts"],"names":["onValueChangedListeners","Map","MMKV","constructor","configuration","id","nativeInstance","functionCache","has","set","get","getFunctionFromCache","functionName","onValuesAboutToChange","keys","length","setImmediate","key","listener","value","func","getBoolean","getString","getNumber","contains","delete","getAllKeys","clearAll","recrypt","toString","join","toJSON","addOnValueChangedListener","onValueChanged","push","remove","index","indexOf","splice"],"mappings":";;;;;;;AAAA;;AACA;;;;AAwHA,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,4BAAWF,aAAX,CAAtB;AACA,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,qBAAqB,CAACC,IAAD,EAAiB;AAC5C,QAAI,KAAKd,uBAAL,CAA6Be,MAA7B,KAAwC,CAA5C,EAA+C;AAE/CC,IAAAA,YAAY,CAAC,MAAM;AACjB,gDAAwB,MAAM;AAC5B,aAAK,MAAMC,GAAX,IAAkBH,IAAlB,EAAwB;AACtB,eAAK,MAAMI,QAAX,IAAuB,KAAKlB,uBAA5B,EAAqD;AACnDkB,YAAAA,QAAQ,CAACD,GAAD,CAAR;AACD;AACF;AACF,OAND;AAOD,KARW,CAAZ;AASD;;AAEDR,EAAAA,GAAG,CAACQ,GAAD,EAAcE,KAAd,EAAsD;AACvD,SAAKN,qBAAL,CAA2B,CAACI,GAAD,CAA3B;AAEA,UAAMG,IAAI,GAAG,KAAKT,oBAAL,CAA0B,KAA1B,CAAb;AACA,WAAOS,IAAI,CAACH,GAAD,EAAME,KAAN,CAAX;AACD;;AACDE,EAAAA,UAAU,CAACJ,GAAD,
|
|
1
|
+
{"version":3,"sources":["MMKV.ts"],"names":["onValueChangedListeners","Map","MMKV","constructor","configuration","id","nativeInstance","functionCache","has","set","get","getFunctionFromCache","functionName","onValuesAboutToChange","keys","length","setImmediate","key","listener","value","func","getBoolean","getString","getNumber","contains","delete","getAllKeys","clearAll","recrypt","toString","join","toJSON","addOnValueChangedListener","onValueChanged","push","remove","index","indexOf","splice"],"mappings":"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","sourcesContent":["import { unstable_batchedUpdates } from 'react-native';\nimport { createMMKV } from './createMMKV';\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) => 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 * 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 | '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 = 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 onValuesAboutToChange(keys: string[]) {\n if (this.onValueChangedListeners.length === 0) return;\n\n setImmediate(() => {\n unstable_batchedUpdates(() => {\n for (const key of keys) {\n for (const listener of this.onValueChangedListeners) {\n listener(key);\n }\n }\n });\n });\n }\n\n set(key: string, value: boolean | string | number): void {\n this.onValuesAboutToChange([key]);\n\n const func = this.getFunctionFromCache('set');\n return func(key, value);\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 contains(key: string): boolean {\n const func = this.getFunctionFromCache('contains');\n return func(key);\n }\n delete(key: string): void {\n this.onValuesAboutToChange([key]);\n\n const func = this.getFunctionFromCache('delete');\n return func(key);\n }\n getAllKeys(): string[] {\n const func = this.getFunctionFromCache('getAllKeys');\n return func();\n }\n clearAll(): void {\n const keys = this.getAllKeys();\n this.onValuesAboutToChange(keys);\n\n const func = this.getFunctionFromCache('clearAll');\n return func();\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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["hooks.ts"],"names":["isConfigurationEqual","left","right","encryptionKey","id","path","defaultInstance","getDefaultInstance","MMKV","useMMKV","configuration","instance","lastConfiguration","current","createMMKVHook","getter","key","mmkv","value","setValue","valueRef","set","v","newValue","delete","Error","keyRef","listener","addOnValueChangedListener","changedKey","remove","useMMKVString","getString","useMMKVNumber","getNumber","useMMKVBoolean","getBoolean","useMMKVObject","string","setString","undefined","JSON","parse","stringify","useMMKVListener","valueChangedListener","ref"],"mappings":"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","sourcesContent":["import { useRef, useState, useMemo, useCallback, useEffect } from 'react';\nimport { MMKV, MMKVConfiguration } from './MMKV';\n\nfunction isConfigurationEqual(\n left?: MMKVConfiguration,\n right?: MMKVConfiguration\n): boolean {\n if (left == null || right == null) return left == null && right == null;\n\n return (\n left.encryptionKey === right.encryptionKey &&\n left.id === right.id &&\n left.path === right.path\n );\n}\n\nlet defaultInstance: MMKV | null = null;\nfunction getDefaultInstance(): MMKV {\n if (defaultInstance == null) {\n defaultInstance = new MMKV();\n }\n return defaultInstance;\n}\n\n/**\n * Use the default, shared MMKV instance.\n */\nexport function useMMKV(): MMKV;\n/**\n * Use a custom MMKV instance with the given configuration.\n * @param configuration The configuration to initialize the MMKV instance with. Does not have to be memoized.\n */\nexport function useMMKV(configuration: MMKVConfiguration): MMKV;\nexport function useMMKV(configuration?: MMKVConfiguration): MMKV {\n const instance = useRef<MMKV>();\n const lastConfiguration = useRef<MMKVConfiguration>();\n\n if (configuration == null) return getDefaultInstance();\n\n if (\n instance.current == null ||\n !isConfigurationEqual(lastConfiguration.current, configuration)\n ) {\n lastConfiguration.current = configuration;\n instance.current = new MMKV(configuration);\n }\n\n // @ts-expect-error it's not null, I promise.\n return instance;\n}\n\nfunction createMMKVHook<\n T extends boolean | number | (string | undefined),\n TSet extends T | undefined,\n TSetAction extends TSet | ((current: T) => TSet)\n>(getter: (instance: MMKV, key: string) => T) {\n return (\n key: string,\n instance?: MMKV\n ): [value: T, setValue: (value: TSetAction) => void] => {\n const mmkv = instance ?? getDefaultInstance();\n const [value, setValue] = useState(() => getter(mmkv, key));\n const valueRef = useRef<T>(value);\n valueRef.current = value;\n\n // update value by user set\n const set = useCallback(\n (v: TSetAction) => {\n const newValue = typeof v === 'function' ? v(valueRef.current) : v;\n switch (typeof newValue) {\n case 'number':\n case 'string':\n case 'boolean':\n mmkv.set(key, newValue);\n break;\n case 'undefined':\n mmkv.delete(key);\n break;\n default:\n throw new Error(`MMKV: Type ${typeof newValue} is not supported!`);\n }\n },\n [key, mmkv]\n );\n\n // update value if key changes\n const keyRef = useRef(key);\n useEffect(() => {\n if (key !== keyRef.current) {\n setValue(getter(mmkv, key));\n keyRef.current = key;\n }\n }, [key, mmkv]);\n\n // update value if it changes somewhere else (second hook, same key)\n useEffect(() => {\n const listener = mmkv.addOnValueChangedListener((changedKey) => {\n if (changedKey === key) {\n setValue(getter(mmkv, key));\n }\n });\n return () => listener.remove();\n }, [key, mmkv]);\n\n return [value, set];\n };\n}\n\n/**\n * Use the string value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [username, setUsername] = useMMKVString(\"user.name\")\n * ```\n */\nexport const useMMKVString = createMMKVHook((instance, key) =>\n instance.getString(key)\n);\n\n/**\n * Use the number value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [age, setAge] = useMMKVNumber(\"user.age\")\n * ```\n */\nexport const useMMKVNumber = createMMKVHook((instance, key) =>\n instance.getNumber(key)\n);\n/**\n * Use the boolean value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [isPremiumAccount, setIsPremiumAccount] = useMMKVBoolean(\"user.isPremium\")\n * ```\n */\nexport const useMMKVBoolean = createMMKVHook((instance, key) =>\n instance.getBoolean(key)\n);\n/**\n * Use an object value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * The object will be serialized using `JSON`.\n *\n * @example\n * ```ts\n * const [user, setUser] = useMMKVObject<User>(\"user\")\n * ```\n */\nexport function useMMKVObject<T>(\n key: string,\n instance?: MMKV\n): [value: T | undefined, setValue: (value: T | undefined) => void] {\n const [string, setString] = useMMKVString(key, instance);\n\n const value = useMemo(() => {\n if (string == null) return undefined;\n return JSON.parse(string) as T;\n }, [string]);\n const setValue = useCallback(\n (v: T | undefined) => {\n if (v == null) {\n // Clear the Value\n setString(undefined);\n } else {\n // Store the Object as a serialized Value\n setString(JSON.stringify(v));\n }\n },\n [setString]\n );\n\n return [value, setValue];\n}\n\n/**\n * Listen for changes in the given MMKV storage instance.\n * If no instance is passed, the default instance will be used.\n * @param valueChangedListener The function to call whenever a value inside the storage instance changes\n * @param instance The instance to listen to changes to (or the default instance)\n *\n * @example\n * ```ts\n * useMMKVListener((key) => {\n * console.log(`Value for \"${key}\" changed!`)\n * })\n * ```\n */\nexport function useMMKVListener(\n valueChangedListener: (key: string) => void,\n instance?: MMKV\n): void {\n const ref = useRef(valueChangedListener);\n ref.current = valueChangedListener;\n\n const mmkv = instance ?? getDefaultInstance();\n\n useEffect(() => {\n const listener = mmkv.addOnValueChangedListener((changedKey) => {\n ref.current(changedKey);\n });\n return () => listener.remove();\n }, [mmkv]);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["hooks.ts"],"names":["isConfigurationEqual","left","right","encryptionKey","id","path","defaultInstance","getDefaultInstance","MMKV","useMMKV","configuration","instance","lastConfiguration","current","createMMKVHook","getter","key","mmkv","value","setValue","valueRef","set","v","newValue","delete","Error","keyRef","listener","addOnValueChangedListener","changedKey","remove","useMMKVString","getString","useMMKVNumber","getNumber","useMMKVBoolean","getBoolean","useMMKVObject","string","setString","undefined","JSON","parse","stringify","useMMKVListener","valueChangedListener","ref"],"mappings":"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","sourcesContent":["import { useRef, useState, useMemo, useCallback, useEffect } from 'react';\nimport { MMKV, MMKVConfiguration } from './MMKV';\n\nfunction isConfigurationEqual(\n left?: MMKVConfiguration,\n right?: MMKVConfiguration\n): boolean {\n if (left == null || right == null) return left == null && right == null;\n\n return (\n left.encryptionKey === right.encryptionKey &&\n left.id === right.id &&\n left.path === right.path\n );\n}\n\nlet defaultInstance: MMKV | null = null;\nfunction getDefaultInstance(): MMKV {\n if (defaultInstance == null) {\n defaultInstance = new MMKV();\n }\n return defaultInstance;\n}\n\n/**\n * Use the default, shared MMKV instance.\n */\nexport function useMMKV(): MMKV;\n/**\n * Use a custom MMKV instance with the given configuration.\n * @param configuration The configuration to initialize the MMKV instance with. Does not have to be memoized.\n */\nexport function useMMKV(configuration: MMKVConfiguration): MMKV;\nexport function useMMKV(configuration?: MMKVConfiguration): MMKV {\n const instance = useRef<MMKV>();\n const lastConfiguration = useRef<MMKVConfiguration>();\n\n if (configuration == null) return getDefaultInstance();\n\n if (\n instance.current == null ||\n !isConfigurationEqual(lastConfiguration.current, configuration)\n ) {\n lastConfiguration.current = configuration;\n instance.current = new MMKV(configuration);\n }\n\n // @ts-expect-error it's not null, I promise.\n return instance;\n}\n\nfunction createMMKVHook<\n T extends (boolean | number | string) | undefined,\n TSet extends T | undefined,\n TSetAction extends TSet | ((current: T) => TSet)\n>(getter: (instance: MMKV, key: string) => T) {\n return (\n key: string,\n instance?: MMKV\n ): [value: T, setValue: (value: TSetAction) => void] => {\n const mmkv = instance ?? getDefaultInstance();\n const [value, setValue] = useState(() => getter(mmkv, key));\n const valueRef = useRef<T>(value);\n valueRef.current = value;\n\n // update value by user set\n const set = useCallback(\n (v: TSetAction) => {\n const newValue = typeof v === 'function' ? v(valueRef.current) : v;\n switch (typeof newValue) {\n case 'number':\n case 'string':\n case 'boolean':\n mmkv.set(key, newValue);\n break;\n case 'undefined':\n mmkv.delete(key);\n break;\n default:\n throw new Error(`MMKV: Type ${typeof newValue} is not supported!`);\n }\n },\n [key, mmkv]\n );\n\n // update value if key changes\n const keyRef = useRef(key);\n useEffect(() => {\n if (key !== keyRef.current) {\n setValue(getter(mmkv, key));\n keyRef.current = key;\n }\n }, [key, mmkv]);\n\n // update value if it changes somewhere else (second hook, same key)\n useEffect(() => {\n const listener = mmkv.addOnValueChangedListener((changedKey) => {\n if (changedKey === key) {\n setValue(getter(mmkv, key));\n }\n });\n return () => listener.remove();\n }, [key, mmkv]);\n\n return [value, set];\n };\n}\n\n/**\n * Use the string value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [username, setUsername] = useMMKVString(\"user.name\")\n * ```\n */\nexport const useMMKVString = createMMKVHook((instance, key) =>\n instance.getString(key)\n);\n\n/**\n * Use the number value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [age, setAge] = useMMKVNumber(\"user.age\")\n * ```\n */\nexport const useMMKVNumber = createMMKVHook((instance, key) =>\n instance.getNumber(key)\n);\n/**\n * Use the boolean value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [isPremiumAccount, setIsPremiumAccount] = useMMKVBoolean(\"user.isPremium\")\n * ```\n */\nexport const useMMKVBoolean = createMMKVHook((instance, key) =>\n instance.getBoolean(key)\n);\n/**\n * Use an object value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * The object will be serialized using `JSON`.\n *\n * @example\n * ```ts\n * const [user, setUser] = useMMKVObject<User>(\"user\")\n * ```\n */\nexport function useMMKVObject<T>(\n key: string,\n instance?: MMKV\n): [value: T | undefined, setValue: (value: T | undefined) => void] {\n const [string, setString] = useMMKVString(key, instance);\n\n const value = useMemo(() => {\n if (string == null) return undefined;\n return JSON.parse(string) as T;\n }, [string]);\n const setValue = useCallback(\n (v: T | undefined) => {\n if (v == null) {\n // Clear the Value\n setString(undefined);\n } else {\n // Store the Object as a serialized Value\n setString(JSON.stringify(v));\n }\n },\n [setString]\n );\n\n return [value, setValue];\n}\n\n/**\n * Listen for changes in the given MMKV storage instance.\n * If no instance is passed, the default instance will be used.\n * @param valueChangedListener The function to call whenever a value inside the storage instance changes\n * @param instance The instance to listen to changes to (or the default instance)\n *\n * @example\n * ```ts\n * useMMKVListener((key) => {\n * console.log(`Value for \"${key}\" changed!`)\n * })\n * ```\n */\nexport function useMMKVListener(\n valueChangedListener: (key: string) => void,\n instance?: MMKV\n): void {\n const ref = useRef(valueChangedListener);\n ref.current = valueChangedListener;\n\n const mmkv = instance ?? getDefaultInstance();\n\n useEffect(() => {\n const listener = mmkv.addOnValueChangedListener((changedKey) => {\n ref.current(changedKey);\n });\n return () => listener.remove();\n }, [mmkv]);\n}\n"]}
|
package/lib/module/MMKV.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["MMKV.ts"],"names":["unstable_batchedUpdates","createMMKV","onValueChangedListeners","Map","MMKV","constructor","configuration","id","nativeInstance","functionCache","has","set","get","getFunctionFromCache","functionName","onValuesAboutToChange","keys","length","setImmediate","key","listener","value","func","getBoolean","getString","getNumber","contains","delete","getAllKeys","clearAll","recrypt","toString","join","toJSON","addOnValueChangedListener","onValueChanged","push","remove","index","indexOf","splice"],"mappings":"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","sourcesContent":["import { unstable_batchedUpdates } from 'react-native';\nimport { createMMKV } from './createMMKV';\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) => void;\n /**\n * Get a boolean value for the given `key`.\n *\n * @default false\n */\n getBoolean: (key: string) => boolean;\n /**\n * Get a string value for the given `key`.\n *\n * @default undefined\n */\n getString: (key: string) => string | undefined;\n /**\n * Get a number value for the given `key`.\n *\n * @default 0\n */\n getNumber: (key: string) => number;\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 | '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 = 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 onValuesAboutToChange(keys: string[]) {\n if (this.onValueChangedListeners.length === 0) return;\n\n setImmediate(() => {\n unstable_batchedUpdates(() => {\n for (const key of keys) {\n for (const listener of this.onValueChangedListeners) {\n listener(key);\n }\n }\n });\n });\n }\n\n set(key: string, value: boolean | string | number): void {\n this.onValuesAboutToChange([key]);\n\n const func = this.getFunctionFromCache('set');\n return func(key, value);\n }\n getBoolean(key: string): boolean {\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 {\n const func = this.getFunctionFromCache('getNumber');\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 this.onValuesAboutToChange([key]);\n\n const func = this.getFunctionFromCache('delete');\n return func(key);\n }\n getAllKeys(): string[] {\n const func = this.getFunctionFromCache('getAllKeys');\n return func();\n }\n clearAll(): void {\n const keys = this.getAllKeys();\n this.onValuesAboutToChange(keys);\n\n const func = this.getFunctionFromCache('clearAll');\n return func();\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"]}
|
|
1
|
+
{"version":3,"sources":["MMKV.ts"],"names":["unstable_batchedUpdates","createMMKV","onValueChangedListeners","Map","MMKV","constructor","configuration","id","nativeInstance","functionCache","has","set","get","getFunctionFromCache","functionName","onValuesAboutToChange","keys","length","setImmediate","key","listener","value","func","getBoolean","getString","getNumber","contains","delete","getAllKeys","clearAll","recrypt","toString","join","toJSON","addOnValueChangedListener","onValueChanged","push","remove","index","indexOf","splice"],"mappings":";;AAAA,SAASA,uBAAT,QAAwC,cAAxC;AACA,SAASC,UAAT,QAA2B,cAA3B;AAwHA,MAAMC,uBAAuB,GAAG,IAAIC,GAAJ,EAAhC;AAEA;AACA;AACA;;AACA,OAAO,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,GAAsBP,UAAU,CAACK,aAAD,CAAhC;AACA,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,qBAAqB,CAACC,IAAD,EAAiB;AAC5C,QAAI,KAAKd,uBAAL,CAA6Be,MAA7B,KAAwC,CAA5C,EAA+C;AAE/CC,IAAAA,YAAY,CAAC,MAAM;AACjBlB,MAAAA,uBAAuB,CAAC,MAAM;AAC5B,aAAK,MAAMmB,GAAX,IAAkBH,IAAlB,EAAwB;AACtB,eAAK,MAAMI,QAAX,IAAuB,KAAKlB,uBAA5B,EAAqD;AACnDkB,YAAAA,QAAQ,CAACD,GAAD,CAAR;AACD;AACF;AACF,OANsB,CAAvB;AAOD,KARW,CAAZ;AASD;;AAEDR,EAAAA,GAAG,CAACQ,GAAD,EAAcE,KAAd,EAAsD;AACvD,SAAKN,qBAAL,CAA2B,CAACI,GAAD,CAA3B;AAEA,UAAMG,IAAI,GAAG,KAAKT,oBAAL,CAA0B,KAA1B,CAAb;AACA,WAAOS,IAAI,CAACH,GAAD,EAAME,KAAN,CAAX;AACD;;AACDE,EAAAA,UAAU,CAACJ,GAAD,EAAmC;AAC3C,UAAMG,IAAI,GAAG,KAAKT,oBAAL,CAA0B,YAA1B,CAAb;AACA,WAAOS,IAAI,CAACH,GAAD,CAAX;AACD;;AACDK,EAAAA,SAAS,CAACL,GAAD,EAAkC;AACzC,UAAMG,IAAI,GAAG,KAAKT,oBAAL,CAA0B,WAA1B,CAAb;AACA,WAAOS,IAAI,CAACH,GAAD,CAAX;AACD;;AACDM,EAAAA,SAAS,CAACN,GAAD,EAAkC;AACzC,UAAMG,IAAI,GAAG,KAAKT,oBAAL,CAA0B,WAA1B,CAAb;AACA,WAAOS,IAAI,CAACH,GAAD,CAAX;AACD;;AACDO,EAAAA,QAAQ,CAACP,GAAD,EAAuB;AAC7B,UAAMG,IAAI,GAAG,KAAKT,oBAAL,CAA0B,UAA1B,CAAb;AACA,WAAOS,IAAI,CAACH,GAAD,CAAX;AACD;;AACDQ,EAAAA,MAAM,CAACR,GAAD,EAAoB;AACxB,SAAKJ,qBAAL,CAA2B,CAACI,GAAD,CAA3B;AAEA,UAAMG,IAAI,GAAG,KAAKT,oBAAL,CAA0B,QAA1B,CAAb;AACA,WAAOS,IAAI,CAACH,GAAD,CAAX;AACD;;AACDS,EAAAA,UAAU,GAAa;AACrB,UAAMN,IAAI,GAAG,KAAKT,oBAAL,CAA0B,YAA1B,CAAb;AACA,WAAOS,IAAI,EAAX;AACD;;AACDO,EAAAA,QAAQ,GAAS;AACf,UAAMb,IAAI,GAAG,KAAKY,UAAL,EAAb;AACA,SAAKb,qBAAL,CAA2BC,IAA3B;AAEA,UAAMM,IAAI,GAAG,KAAKT,oBAAL,CAA0B,UAA1B,CAAb;AACA,WAAOS,IAAI,EAAX;AACD;;AACDQ,EAAAA,OAAO,CAACX,GAAD,EAAgC;AACrC,UAAMG,IAAI,GAAG,KAAKT,oBAAL,CAA0B,SAA1B,CAAb;AACA,WAAOS,IAAI,CAACH,GAAD,CAAX;AACD;;AAEDY,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;;AA7GwC","sourcesContent":["import { unstable_batchedUpdates } from 'react-native';\nimport { createMMKV } from './createMMKV';\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) => 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 * 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 | '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 = 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 onValuesAboutToChange(keys: string[]) {\n if (this.onValueChangedListeners.length === 0) return;\n\n setImmediate(() => {\n unstable_batchedUpdates(() => {\n for (const key of keys) {\n for (const listener of this.onValueChangedListeners) {\n listener(key);\n }\n }\n });\n });\n }\n\n set(key: string, value: boolean | string | number): void {\n this.onValuesAboutToChange([key]);\n\n const func = this.getFunctionFromCache('set');\n return func(key, value);\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 contains(key: string): boolean {\n const func = this.getFunctionFromCache('contains');\n return func(key);\n }\n delete(key: string): void {\n this.onValuesAboutToChange([key]);\n\n const func = this.getFunctionFromCache('delete');\n return func(key);\n }\n getAllKeys(): string[] {\n const func = this.getFunctionFromCache('getAllKeys');\n return func();\n }\n clearAll(): void {\n const keys = this.getAllKeys();\n this.onValuesAboutToChange(keys);\n\n const func = this.getFunctionFromCache('clearAll');\n return func();\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"]}
|
package/lib/module/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["hooks.ts"],"names":["useRef","useState","useMemo","useCallback","useEffect","MMKV","isConfigurationEqual","left","right","encryptionKey","id","path","defaultInstance","getDefaultInstance","useMMKV","configuration","instance","lastConfiguration","current","createMMKVHook","getter","key","mmkv","value","setValue","valueRef","set","v","newValue","delete","Error","keyRef","listener","addOnValueChangedListener","changedKey","remove","useMMKVString","getString","useMMKVNumber","getNumber","useMMKVBoolean","getBoolean","useMMKVObject","string","setString","undefined","JSON","parse","stringify","useMMKVListener","valueChangedListener","ref"],"mappings":"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","sourcesContent":["import { useRef, useState, useMemo, useCallback, useEffect } from 'react';\nimport { MMKV, MMKVConfiguration } from './MMKV';\n\nfunction isConfigurationEqual(\n left?: MMKVConfiguration,\n right?: MMKVConfiguration\n): boolean {\n if (left == null || right == null) return left == null && right == null;\n\n return (\n left.encryptionKey === right.encryptionKey &&\n left.id === right.id &&\n left.path === right.path\n );\n}\n\nlet defaultInstance: MMKV | null = null;\nfunction getDefaultInstance(): MMKV {\n if (defaultInstance == null) {\n defaultInstance = new MMKV();\n }\n return defaultInstance;\n}\n\n/**\n * Use the default, shared MMKV instance.\n */\nexport function useMMKV(): MMKV;\n/**\n * Use a custom MMKV instance with the given configuration.\n * @param configuration The configuration to initialize the MMKV instance with. Does not have to be memoized.\n */\nexport function useMMKV(configuration: MMKVConfiguration): MMKV;\nexport function useMMKV(configuration?: MMKVConfiguration): MMKV {\n const instance = useRef<MMKV>();\n const lastConfiguration = useRef<MMKVConfiguration>();\n\n if (configuration == null) return getDefaultInstance();\n\n if (\n instance.current == null ||\n !isConfigurationEqual(lastConfiguration.current, configuration)\n ) {\n lastConfiguration.current = configuration;\n instance.current = new MMKV(configuration);\n }\n\n // @ts-expect-error it's not null, I promise.\n return instance;\n}\n\nfunction createMMKVHook<\n T extends boolean | number | (string | undefined),\n TSet extends T | undefined,\n TSetAction extends TSet | ((current: T) => TSet)\n>(getter: (instance: MMKV, key: string) => T) {\n return (\n key: string,\n instance?: MMKV\n ): [value: T, setValue: (value: TSetAction) => void] => {\n const mmkv = instance ?? getDefaultInstance();\n const [value, setValue] = useState(() => getter(mmkv, key));\n const valueRef = useRef<T>(value);\n valueRef.current = value;\n\n // update value by user set\n const set = useCallback(\n (v: TSetAction) => {\n const newValue = typeof v === 'function' ? v(valueRef.current) : v;\n switch (typeof newValue) {\n case 'number':\n case 'string':\n case 'boolean':\n mmkv.set(key, newValue);\n break;\n case 'undefined':\n mmkv.delete(key);\n break;\n default:\n throw new Error(`MMKV: Type ${typeof newValue} is not supported!`);\n }\n },\n [key, mmkv]\n );\n\n // update value if key changes\n const keyRef = useRef(key);\n useEffect(() => {\n if (key !== keyRef.current) {\n setValue(getter(mmkv, key));\n keyRef.current = key;\n }\n }, [key, mmkv]);\n\n // update value if it changes somewhere else (second hook, same key)\n useEffect(() => {\n const listener = mmkv.addOnValueChangedListener((changedKey) => {\n if (changedKey === key) {\n setValue(getter(mmkv, key));\n }\n });\n return () => listener.remove();\n }, [key, mmkv]);\n\n return [value, set];\n };\n}\n\n/**\n * Use the string value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [username, setUsername] = useMMKVString(\"user.name\")\n * ```\n */\nexport const useMMKVString = createMMKVHook((instance, key) =>\n instance.getString(key)\n);\n\n/**\n * Use the number value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [age, setAge] = useMMKVNumber(\"user.age\")\n * ```\n */\nexport const useMMKVNumber = createMMKVHook((instance, key) =>\n instance.getNumber(key)\n);\n/**\n * Use the boolean value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [isPremiumAccount, setIsPremiumAccount] = useMMKVBoolean(\"user.isPremium\")\n * ```\n */\nexport const useMMKVBoolean = createMMKVHook((instance, key) =>\n instance.getBoolean(key)\n);\n/**\n * Use an object value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * The object will be serialized using `JSON`.\n *\n * @example\n * ```ts\n * const [user, setUser] = useMMKVObject<User>(\"user\")\n * ```\n */\nexport function useMMKVObject<T>(\n key: string,\n instance?: MMKV\n): [value: T | undefined, setValue: (value: T | undefined) => void] {\n const [string, setString] = useMMKVString(key, instance);\n\n const value = useMemo(() => {\n if (string == null) return undefined;\n return JSON.parse(string) as T;\n }, [string]);\n const setValue = useCallback(\n (v: T | undefined) => {\n if (v == null) {\n // Clear the Value\n setString(undefined);\n } else {\n // Store the Object as a serialized Value\n setString(JSON.stringify(v));\n }\n },\n [setString]\n );\n\n return [value, setValue];\n}\n\n/**\n * Listen for changes in the given MMKV storage instance.\n * If no instance is passed, the default instance will be used.\n * @param valueChangedListener The function to call whenever a value inside the storage instance changes\n * @param instance The instance to listen to changes to (or the default instance)\n *\n * @example\n * ```ts\n * useMMKVListener((key) => {\n * console.log(`Value for \"${key}\" changed!`)\n * })\n * ```\n */\nexport function useMMKVListener(\n valueChangedListener: (key: string) => void,\n instance?: MMKV\n): void {\n const ref = useRef(valueChangedListener);\n ref.current = valueChangedListener;\n\n const mmkv = instance ?? getDefaultInstance();\n\n useEffect(() => {\n const listener = mmkv.addOnValueChangedListener((changedKey) => {\n ref.current(changedKey);\n });\n return () => listener.remove();\n }, [mmkv]);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["hooks.ts"],"names":["useRef","useState","useMemo","useCallback","useEffect","MMKV","isConfigurationEqual","left","right","encryptionKey","id","path","defaultInstance","getDefaultInstance","useMMKV","configuration","instance","lastConfiguration","current","createMMKVHook","getter","key","mmkv","value","setValue","valueRef","set","v","newValue","delete","Error","keyRef","listener","addOnValueChangedListener","changedKey","remove","useMMKVString","getString","useMMKVNumber","getNumber","useMMKVBoolean","getBoolean","useMMKVObject","string","setString","undefined","JSON","parse","stringify","useMMKVListener","valueChangedListener","ref"],"mappings":"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","sourcesContent":["import { useRef, useState, useMemo, useCallback, useEffect } from 'react';\nimport { MMKV, MMKVConfiguration } from './MMKV';\n\nfunction isConfigurationEqual(\n left?: MMKVConfiguration,\n right?: MMKVConfiguration\n): boolean {\n if (left == null || right == null) return left == null && right == null;\n\n return (\n left.encryptionKey === right.encryptionKey &&\n left.id === right.id &&\n left.path === right.path\n );\n}\n\nlet defaultInstance: MMKV | null = null;\nfunction getDefaultInstance(): MMKV {\n if (defaultInstance == null) {\n defaultInstance = new MMKV();\n }\n return defaultInstance;\n}\n\n/**\n * Use the default, shared MMKV instance.\n */\nexport function useMMKV(): MMKV;\n/**\n * Use a custom MMKV instance with the given configuration.\n * @param configuration The configuration to initialize the MMKV instance with. Does not have to be memoized.\n */\nexport function useMMKV(configuration: MMKVConfiguration): MMKV;\nexport function useMMKV(configuration?: MMKVConfiguration): MMKV {\n const instance = useRef<MMKV>();\n const lastConfiguration = useRef<MMKVConfiguration>();\n\n if (configuration == null) return getDefaultInstance();\n\n if (\n instance.current == null ||\n !isConfigurationEqual(lastConfiguration.current, configuration)\n ) {\n lastConfiguration.current = configuration;\n instance.current = new MMKV(configuration);\n }\n\n // @ts-expect-error it's not null, I promise.\n return instance;\n}\n\nfunction createMMKVHook<\n T extends (boolean | number | string) | undefined,\n TSet extends T | undefined,\n TSetAction extends TSet | ((current: T) => TSet)\n>(getter: (instance: MMKV, key: string) => T) {\n return (\n key: string,\n instance?: MMKV\n ): [value: T, setValue: (value: TSetAction) => void] => {\n const mmkv = instance ?? getDefaultInstance();\n const [value, setValue] = useState(() => getter(mmkv, key));\n const valueRef = useRef<T>(value);\n valueRef.current = value;\n\n // update value by user set\n const set = useCallback(\n (v: TSetAction) => {\n const newValue = typeof v === 'function' ? v(valueRef.current) : v;\n switch (typeof newValue) {\n case 'number':\n case 'string':\n case 'boolean':\n mmkv.set(key, newValue);\n break;\n case 'undefined':\n mmkv.delete(key);\n break;\n default:\n throw new Error(`MMKV: Type ${typeof newValue} is not supported!`);\n }\n },\n [key, mmkv]\n );\n\n // update value if key changes\n const keyRef = useRef(key);\n useEffect(() => {\n if (key !== keyRef.current) {\n setValue(getter(mmkv, key));\n keyRef.current = key;\n }\n }, [key, mmkv]);\n\n // update value if it changes somewhere else (second hook, same key)\n useEffect(() => {\n const listener = mmkv.addOnValueChangedListener((changedKey) => {\n if (changedKey === key) {\n setValue(getter(mmkv, key));\n }\n });\n return () => listener.remove();\n }, [key, mmkv]);\n\n return [value, set];\n };\n}\n\n/**\n * Use the string value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [username, setUsername] = useMMKVString(\"user.name\")\n * ```\n */\nexport const useMMKVString = createMMKVHook((instance, key) =>\n instance.getString(key)\n);\n\n/**\n * Use the number value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [age, setAge] = useMMKVNumber(\"user.age\")\n * ```\n */\nexport const useMMKVNumber = createMMKVHook((instance, key) =>\n instance.getNumber(key)\n);\n/**\n * Use the boolean value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [isPremiumAccount, setIsPremiumAccount] = useMMKVBoolean(\"user.isPremium\")\n * ```\n */\nexport const useMMKVBoolean = createMMKVHook((instance, key) =>\n instance.getBoolean(key)\n);\n/**\n * Use an object value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * The object will be serialized using `JSON`.\n *\n * @example\n * ```ts\n * const [user, setUser] = useMMKVObject<User>(\"user\")\n * ```\n */\nexport function useMMKVObject<T>(\n key: string,\n instance?: MMKV\n): [value: T | undefined, setValue: (value: T | undefined) => void] {\n const [string, setString] = useMMKVString(key, instance);\n\n const value = useMemo(() => {\n if (string == null) return undefined;\n return JSON.parse(string) as T;\n }, [string]);\n const setValue = useCallback(\n (v: T | undefined) => {\n if (v == null) {\n // Clear the Value\n setString(undefined);\n } else {\n // Store the Object as a serialized Value\n setString(JSON.stringify(v));\n }\n },\n [setString]\n );\n\n return [value, setValue];\n}\n\n/**\n * Listen for changes in the given MMKV storage instance.\n * If no instance is passed, the default instance will be used.\n * @param valueChangedListener The function to call whenever a value inside the storage instance changes\n * @param instance The instance to listen to changes to (or the default instance)\n *\n * @example\n * ```ts\n * useMMKVListener((key) => {\n * console.log(`Value for \"${key}\" changed!`)\n * })\n * ```\n */\nexport function useMMKVListener(\n valueChangedListener: (key: string) => void,\n instance?: MMKV\n): void {\n const ref = useRef(valueChangedListener);\n ref.current = valueChangedListener;\n\n const mmkv = instance ?? getDefaultInstance();\n\n useEffect(() => {\n const listener = mmkv.addOnValueChangedListener((changedKey) => {\n ref.current(changedKey);\n });\n return () => listener.remove();\n }, [mmkv]);\n}\n"]}
|
package/lib/typescript/MMKV.d.ts
CHANGED
|
@@ -47,23 +47,23 @@ interface MMKVInterface {
|
|
|
47
47
|
*/
|
|
48
48
|
set: (key: string, value: boolean | string | number) => void;
|
|
49
49
|
/**
|
|
50
|
-
* Get
|
|
50
|
+
* Get the boolean value for the given `key`, or `undefined` if it does not exist.
|
|
51
51
|
*
|
|
52
|
-
* @default
|
|
52
|
+
* @default undefined
|
|
53
53
|
*/
|
|
54
|
-
getBoolean: (key: string) => boolean;
|
|
54
|
+
getBoolean: (key: string) => boolean | undefined;
|
|
55
55
|
/**
|
|
56
|
-
* Get
|
|
56
|
+
* Get the string value for the given `key`, or `undefined` if it does not exist.
|
|
57
57
|
*
|
|
58
58
|
* @default undefined
|
|
59
59
|
*/
|
|
60
60
|
getString: (key: string) => string | undefined;
|
|
61
61
|
/**
|
|
62
|
-
* Get
|
|
62
|
+
* Get the number value for the given `key`, or `undefined` if it does not exist.
|
|
63
63
|
*
|
|
64
|
-
* @default
|
|
64
|
+
* @default undefined
|
|
65
65
|
*/
|
|
66
|
-
getNumber: (key: string) => number;
|
|
66
|
+
getNumber: (key: string) => number | undefined;
|
|
67
67
|
/**
|
|
68
68
|
* Checks whether the given `key` is being stored in this MMKV instance.
|
|
69
69
|
*/
|
|
@@ -115,9 +115,9 @@ export declare class MMKV implements MMKVInterface {
|
|
|
115
115
|
private getFunctionFromCache;
|
|
116
116
|
private onValuesAboutToChange;
|
|
117
117
|
set(key: string, value: boolean | string | number): void;
|
|
118
|
-
getBoolean(key: string): boolean;
|
|
118
|
+
getBoolean(key: string): boolean | undefined;
|
|
119
119
|
getString(key: string): string | undefined;
|
|
120
|
-
getNumber(key: string): number;
|
|
120
|
+
getNumber(key: string): number | undefined;
|
|
121
121
|
contains(key: string): boolean;
|
|
122
122
|
delete(key: string): void;
|
|
123
123
|
getAllKeys(): string[];
|
|
@@ -29,7 +29,7 @@ export declare const useMMKVString: (key: string, instance?: MMKV | undefined) =
|
|
|
29
29
|
* const [age, setAge] = useMMKVNumber("user.age")
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
|
-
export declare const useMMKVNumber: (key: string, instance?: MMKV | undefined) => [value: number, setValue: (value: number | ((current: number) => number | undefined) | undefined) => void];
|
|
32
|
+
export declare const useMMKVNumber: (key: string, instance?: MMKV | undefined) => [value: number | undefined, setValue: (value: number | ((current: number | undefined) => number | undefined) | undefined) => void];
|
|
33
33
|
/**
|
|
34
34
|
* Use the boolean value of the given `key` from the given MMKV storage instance.
|
|
35
35
|
*
|
|
@@ -40,7 +40,7 @@ export declare const useMMKVNumber: (key: string, instance?: MMKV | undefined) =
|
|
|
40
40
|
* const [isPremiumAccount, setIsPremiumAccount] = useMMKVBoolean("user.isPremium")
|
|
41
41
|
* ```
|
|
42
42
|
*/
|
|
43
|
-
export declare const useMMKVBoolean: (key: string, instance?: MMKV | undefined) => [value: boolean, setValue: (value: boolean | ((current: boolean) => boolean | undefined) | undefined) => void];
|
|
43
|
+
export declare const useMMKVBoolean: (key: string, instance?: MMKV | undefined) => [value: boolean | undefined, setValue: (value: boolean | ((current: boolean | undefined) => boolean | undefined) | undefined) => void];
|
|
44
44
|
/**
|
|
45
45
|
* Use an object value of the given `key` from the given MMKV storage instance.
|
|
46
46
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-mmkv",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "The fastest key/value storage for React Native. ~30x faster than AsyncStorage! Works on Android, iOS and Web.",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|