react-native-mmkv 2.1.1 → 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.
Files changed (40) hide show
  1. package/MMKV/CHANGELOG.md +14 -0
  2. package/MMKV/Core/Core.xcodeproj/project.pbxproj +1 -1
  3. package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/Core.xcscheme +1 -1
  4. package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/MMKVWatchCore.xcscheme +1 -1
  5. package/MMKV/Core/MMKV.cpp +70 -7
  6. package/MMKV/Core/MMKV.h +9 -7
  7. package/MMKV/Core/MMKVPredef.h +1 -1
  8. package/MMKV/README.md +19 -19
  9. package/README.md +6 -2
  10. package/android/src/main/cpp/MmkvHostObject.cpp +79 -56
  11. package/ios/JSIUtils.mm +24 -25
  12. package/ios/MmkvHostObject.mm +44 -17
  13. package/ios/MmkvModule.mm +4 -1
  14. package/lib/commonjs/MMKV.js +142 -0
  15. package/lib/commonjs/MMKV.js.map +1 -0
  16. package/lib/commonjs/createMMKV.js +66 -0
  17. package/lib/commonjs/createMMKV.js.map +1 -0
  18. package/lib/commonjs/createMMKV.web.js +70 -0
  19. package/lib/commonjs/createMMKV.web.js.map +1 -0
  20. package/lib/commonjs/hooks.js +192 -0
  21. package/lib/commonjs/hooks.js.map +1 -0
  22. package/lib/commonjs/index.js +32 -0
  23. package/lib/commonjs/index.js.map +1 -0
  24. package/lib/module/MMKV.js +131 -0
  25. package/lib/module/MMKV.js.map +1 -0
  26. package/lib/module/createMMKV.js +55 -0
  27. package/lib/module/createMMKV.js.map +1 -0
  28. package/lib/module/createMMKV.web.js +60 -0
  29. package/lib/module/createMMKV.web.js.map +1 -0
  30. package/lib/module/hooks.js +174 -0
  31. package/lib/module/hooks.js.map +1 -0
  32. package/lib/module/index.js +3 -0
  33. package/lib/module/index.js.map +1 -0
  34. package/lib/typescript/MMKV.d.ts +130 -0
  35. package/lib/typescript/createMMKV.d.ts +6 -0
  36. package/lib/typescript/createMMKV.web.d.ts +2 -0
  37. package/lib/typescript/hooks.d.ts +70 -0
  38. package/lib/typescript/index.d.ts +2 -0
  39. package/package.json +1 -1
  40. 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.
@@ -349,7 +349,7 @@
349
349
  CB9563D023AB2D9500ACCD39 /* Project object */ = {
350
350
  isa = PBXProject;
351
351
  attributes = {
352
- LastUpgradeCheck = 1240;
352
+ LastUpgradeCheck = 1330;
353
353
  ORGANIZATIONNAME = lingol;
354
354
  TargetAttributes = {
355
355
  CB9563D723AB2D9500ACCD39 = {
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <Scheme
3
- LastUpgradeVersion = "1240"
3
+ LastUpgradeVersion = "1330"
4
4
  version = "1.3">
5
5
  <BuildAction
6
6
  parallelizeBuildables = "YES"
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <Scheme
3
- LastUpgradeVersion = "1240"
3
+ LastUpgradeVersion = "1330"
4
4
  version = "1.3">
5
5
  <BuildAction
6
6
  parallelizeBuildables = "YES"
@@ -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
@@ -34,7 +34,7 @@
34
34
  #include <vector>
35
35
  #include <unordered_map>
36
36
 
37
- constexpr auto MMKV_VERSION = "v1.2.12";
37
+ constexpr auto MMKV_VERSION = "v1.2.13";
38
38
 
39
39
  #ifdef DEBUG
40
40
  # define MMKV_DEBUG
package/MMKV/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  [![license](https://img.shields.io/badge/license-BSD_3-brightgreen.svg?style=flat)](https://github.com/Tencent/MMKV/blob/master/LICENSE.TXT)
2
2
  [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/MMKV/pulls)
3
- [![Release Version](https://img.shields.io/badge/release-1.2.12-brightgreen.svg)](https://github.com/Tencent/MMKV/releases)
3
+ [![Release Version](https://img.shields.io/badge/release-1.2.13-brightgreen.svg)](https://github.com/Tencent/MMKV/releases)
4
4
  [![Platform](https://img.shields.io/badge/Platform-%20Android%20%7C%20iOS%2FmacOS%20%7C%20Win32%20%7C%20POSIX-brightgreen.svg)](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 file, and protobuf to encode/decode values, making the most of Android to achieve best performance.
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 (apk).
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.12'
32
- // replace "1.2.12" with any available version
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 file, and protobuf to encode/decode values, making the most of iOS/macOS to achieve best performance.
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 (ipa).
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 file, and protobuf to encode/decode values, making the most of Windows to achieve best performance.
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 vise versa.
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 file, and protobuf to encode/decode values, making the most of POSIX to achieve best performance.
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++** (even the JS functions have C++ bodies!)
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
@@ -104,7 +104,7 @@ This creates a new storage instance using a custom MMKV storage ID. By using a c
104
104
 
105
105
  The following values can be configured:
106
106
 
107
- * `id`: The MMKV instance's ID. If you want to use multiple instances, use different IDs. For example, you can separte the global app's storage and a logged-in user's storage. (default: `'mmkv.default'`)
107
+ * `id`: The MMKV instance's ID. If you want to use multiple instances, use different IDs. For example, you can separte the global app's storage and a logged-in user's storage. (required if `path` or `encryptionKey` fields are specified, otherwise defaults to: `'mmkv.default'`)
108
108
  * `path`: The MMKV instance's root path. By default, MMKV stores file inside `$(Documents)/mmkv/`. You can customize MMKV's root directory on MMKV initialization (documentation: [iOS](https://github.com/Tencent/MMKV/wiki/iOS_advance#customize-location) / [Android](https://github.com/Tencent/MMKV/wiki/android_advance#customize-location))
109
109
  * `encryptionKey`: The MMKV instance's encryption/decryption key. By default, MMKV stores all key-values in plain text on file, relying on iOS's/Android's sandbox to make sure the file is encrypted. Should you worry about information leaking, you can choose to encrypt MMKV. (documentation: [iOS](https://github.com/Tencent/MMKV/wiki/iOS_advance#encryption) / [Android](https://github.com/Tencent/MMKV/wiki/android_advance#encryption))
110
110
 
@@ -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
- if (!arguments[0].isString()) throw jsi::JSError(runtime, "MMKV::set: First argument ('key') has to be of type string!");
63
- auto keyName = arguments[0].getString(runtime).utf8(runtime);
64
-
65
- if (arguments[1].isBool()) {
66
- instance->set(arguments[1].getBool(), keyName);
67
- } else if (arguments[1].isNumber()) {
68
- instance->set(arguments[1].getNumber(), keyName);
69
- } else if (arguments[1].isString()) {
70
- auto stringValue = arguments[1].getString(runtime).utf8(runtime);
71
- instance->set(stringValue, keyName);
72
- } else {
73
- throw jsi::JSError(runtime, "MMKV::set: 'value' argument is not of type bool, number or string!");
74
- }
75
- return jsi::Value::undefined();
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
- if (!arguments[0].isString()) throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
89
- auto keyName = arguments[0].getString(runtime).utf8(runtime);
90
- auto value = instance->getBool(keyName);
91
- return jsi::Value(value);
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
- if (!arguments[0].isString()) throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
105
-
106
- auto keyName = arguments[0].getString(runtime).utf8(runtime);
115
+ if (!arguments[0].isString()) {
116
+ throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
117
+ }
107
118
 
108
- std::string result;
109
- bool hasValue = instance->getString(keyName, result);
110
- if (hasValue)
111
- return jsi::Value(runtime, jsi::String::createFromUtf8(runtime, result));
112
- else
113
- return jsi::Value::undefined();
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
- if (!arguments[0].isString()) throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
127
- auto keyName = arguments[0].getString(runtime).utf8(runtime);
139
+ if (!arguments[0].isString()) {
140
+ throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
141
+ }
128
142
 
129
- auto value = instance->getDouble(keyName);
130
- return jsi::Value(value);
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
- if (!arguments[0].isString()) throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
144
- auto keyName = arguments[0].getString(runtime).utf8(runtime);
163
+ if (!arguments[0].isString()) {
164
+ throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
165
+ }
145
166
 
146
- bool containsKey = instance->containsKey(keyName);
147
- return jsi::Value(containsKey);
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
- if (!arguments[0].isString()) throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
161
- auto keyName = arguments[0].getString(runtime).utf8(runtime);
182
+ if (!arguments[0].isString()) {
183
+ throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
184
+ }
162
185
 
163
- instance->removeValueForKey(keyName);
164
- return jsi::Value::undefined();
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
- auto keys = instance->allKeys();
178
- auto array = jsi::Array(runtime, keys.size());
179
- for (int i = 0; i < keys.size(); i++) {
180
- array.setValueAtIndex(runtime, i, keys[i]);
181
- }
182
- return array;
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
- instance->clearAll();
196
-
197
- return jsi::Value::undefined();
198
- });
219
+ instance->clearAll();
220
+ return jsi::Value::undefined();
221
+ });
199
222
  }
200
223
 
201
224
  if (propName == "recrypt") {