react-native-mmkv 4.0.0 → 4.1.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 (50) hide show
  1. package/NitroMmkv.podspec +0 -1
  2. package/android/build.gradle +1 -1
  3. package/cpp/HybridMMKV.cpp +13 -0
  4. package/cpp/HybridMMKV.hpp +2 -0
  5. package/cpp/HybridMMKVFactory.cpp +12 -4
  6. package/cpp/HybridMMKVFactory.hpp +4 -1
  7. package/lib/createMMKV/createMMKV.js +4 -14
  8. package/lib/createMMKV/createMMKV.web.js +43 -51
  9. package/lib/createMMKV/createMockMMKV.d.ts +2 -1
  10. package/lib/createMMKV/createMockMMKV.js +18 -5
  11. package/lib/deleteMMKV/deleteMMKV.d.ts +1 -0
  12. package/lib/deleteMMKV/deleteMMKV.js +9 -0
  13. package/lib/deleteMMKV/deleteMMKV.web.d.ts +1 -0
  14. package/lib/deleteMMKV/deleteMMKV.web.js +14 -0
  15. package/lib/existsMMKV/existsMMKV.d.ts +1 -0
  16. package/lib/existsMMKV/existsMMKV.js +9 -0
  17. package/lib/existsMMKV/existsMMKV.web.d.ts +1 -0
  18. package/lib/existsMMKV/existsMMKV.web.js +7 -0
  19. package/lib/getMMKVFactory.d.ts +4 -0
  20. package/lib/getMMKVFactory.js +20 -0
  21. package/lib/index.d.ts +2 -0
  22. package/lib/index.js +3 -0
  23. package/lib/specs/MMKV.nitro.d.ts +19 -9
  24. package/lib/specs/MMKVFactory.nitro.d.ts +13 -3
  25. package/lib/web/getLocalStorage.d.ts +2 -0
  26. package/lib/web/getLocalStorage.js +33 -0
  27. package/nitrogen/generated/android/c++/JHybridMMKVPlatformContextSpec.cpp +6 -0
  28. package/nitrogen/generated/android/c++/JHybridMMKVPlatformContextSpec.hpp +1 -0
  29. package/nitrogen/generated/android/kotlin/com/margelo/nitro/mmkv/HybridMMKVPlatformContextSpec.kt +5 -0
  30. package/nitrogen/generated/ios/NitroMmkv-Swift-Cxx-Bridge.cpp +1 -0
  31. package/nitrogen/generated/ios/c++/HybridMMKVPlatformContextSpecSwift.hpp +3 -0
  32. package/nitrogen/generated/ios/swift/HybridMMKVPlatformContextSpec.swift +7 -0
  33. package/nitrogen/generated/ios/swift/HybridMMKVPlatformContextSpec_cxx.swift +9 -1
  34. package/nitrogen/generated/shared/c++/HybridMMKVFactorySpec.cpp +3 -1
  35. package/nitrogen/generated/shared/c++/HybridMMKVFactorySpec.hpp +3 -1
  36. package/nitrogen/generated/shared/c++/HybridMMKVSpec.cpp +2 -0
  37. package/nitrogen/generated/shared/c++/HybridMMKVSpec.hpp +6 -0
  38. package/package.json +3 -4
  39. package/src/createMMKV/createMMKV.ts +5 -19
  40. package/src/createMMKV/createMMKV.web.ts +46 -65
  41. package/src/createMMKV/createMockMMKV.ts +21 -5
  42. package/src/deleteMMKV/deleteMMKV.ts +11 -0
  43. package/src/deleteMMKV/deleteMMKV.web.ts +20 -0
  44. package/src/existsMMKV/existsMMKV.ts +11 -0
  45. package/src/existsMMKV/existsMMKV.web.ts +11 -0
  46. package/src/getMMKVFactory.ts +28 -0
  47. package/src/index.ts +4 -0
  48. package/src/specs/MMKV.nitro.ts +20 -9
  49. package/src/specs/MMKVFactory.nitro.ts +15 -3
  50. package/src/web/getLocalStorage.ts +42 -0
package/NitroMmkv.podspec CHANGED
@@ -24,7 +24,6 @@ Pod::Spec.new do |s|
24
24
 
25
25
  # Add MMKV Core dependency
26
26
  s.compiler_flags = '-x objective-c++'
27
- s.libraries = 'z', 'c++'
28
27
  s.dependency 'MMKVCore', '2.2.4'
29
28
 
30
29
  # TODO: Remove when no one uses RN 0.79 anymore
@@ -5,7 +5,7 @@ buildscript {
5
5
  }
6
6
 
7
7
  dependencies {
8
- classpath "com.android.tools.build:gradle:8.13.0"
8
+ classpath "com.android.tools.build:gradle:8.13.1"
9
9
  }
10
10
  }
11
11
 
@@ -55,6 +55,9 @@ HybridMMKV::HybridMMKV(const Configuration& config) : HybridObject(TAG) {
55
55
  }
56
56
  }
57
57
 
58
+ std::string HybridMMKV::getId() {
59
+ return instance->mmapID();
60
+ }
58
61
  double HybridMMKV::getSize() {
59
62
  return instance->actualSize();
60
63
  }
@@ -209,4 +212,14 @@ MMKVMode HybridMMKV::getMMKVMode(const Configuration& config) {
209
212
  }
210
213
  }
211
214
 
215
+ double HybridMMKV::importAllFrom(const std::shared_ptr<HybridMMKVSpec>& other) {
216
+ auto hybridMMKV = std::dynamic_pointer_cast<HybridMMKV>(other);
217
+ if (hybridMMKV == nullptr) {
218
+ throw std::runtime_error("The given `MMKV` instance is not of type `HybridMMKV`!");
219
+ }
220
+
221
+ size_t importedCount = instance->importFrom(hybridMMKV->instance);
222
+ return static_cast<double>(importedCount);
223
+ }
224
+
212
225
  } // namespace margelo::nitro::mmkv
@@ -19,6 +19,7 @@ public:
19
19
 
20
20
  public:
21
21
  // Properties
22
+ std::string getId() override;
22
23
  double getSize() override;
23
24
  bool getIsReadOnly() override;
24
25
 
@@ -36,6 +37,7 @@ public:
36
37
  void recrypt(const std::optional<std::string>& key) override;
37
38
  void trim() override;
38
39
  Listener addOnValueChangedListener(const std::function<void(const std::string& /* key */)>& onValueChanged) override;
40
+ double importAllFrom(const std::shared_ptr<HybridMMKVSpec>& other) override;
39
41
 
40
42
  private:
41
43
  static MMKVMode getMMKVMode(const Configuration& config);
@@ -15,10 +15,6 @@ std::string HybridMMKVFactory::getDefaultMMKVInstanceId() {
15
15
  return DEFAULT_MMAP_ID;
16
16
  }
17
17
 
18
- std::shared_ptr<HybridMMKVSpec> HybridMMKVFactory::createMMKV(const Configuration& configuration) {
19
- return std::make_shared<HybridMMKV>(configuration);
20
- }
21
-
22
18
  void HybridMMKVFactory::initializeMMKV(const std::string& rootPath) {
23
19
  Logger::log(LogLevel::Info, TAG, "Initializing MMKV with rootPath=%s", rootPath.c_str());
24
20
 
@@ -30,4 +26,16 @@ void HybridMMKVFactory::initializeMMKV(const std::string& rootPath) {
30
26
  MMKV::initializeMMKV(rootPath, logLevel);
31
27
  }
32
28
 
29
+ std::shared_ptr<HybridMMKVSpec> HybridMMKVFactory::createMMKV(const Configuration& configuration) {
30
+ return std::make_shared<HybridMMKV>(configuration);
31
+ }
32
+
33
+ bool HybridMMKVFactory::deleteMMKV(const std::string& id) {
34
+ return MMKV::removeStorage(id);
35
+ }
36
+
37
+ bool HybridMMKVFactory::existsMMKV(const std::string& id) {
38
+ return MMKV::checkExist(id);
39
+ }
40
+
33
41
  } // namespace margelo::nitro::mmkv
@@ -17,8 +17,11 @@ public:
17
17
 
18
18
  public:
19
19
  std::string getDefaultMMKVInstanceId() override;
20
- std::shared_ptr<HybridMMKVSpec> createMMKV(const Configuration& configuration) override;
21
20
  void initializeMMKV(const std::string& rootPath) override;
21
+
22
+ std::shared_ptr<HybridMMKVSpec> createMMKV(const Configuration& configuration) override;
23
+ bool deleteMMKV(const std::string& id) override;
24
+ bool existsMMKV(const std::string& id) override;
22
25
  };
23
26
 
24
27
  } // namespace margelo::nitro::mmkv
@@ -1,31 +1,21 @@
1
- import { NitroModules } from 'react-native-nitro-modules';
2
1
  import { Platform } from 'react-native';
3
2
  import { addMemoryWarningListener } from '../addMemoryWarningListener/addMemoryWarningListener';
4
3
  import { isTest } from '../isTest';
5
4
  import { createMockMMKV } from './createMockMMKV';
6
- let factory;
7
- let platformContext;
5
+ import { getMMKVFactory, getPlatformContext } from '../getMMKVFactory';
8
6
  export function createMMKV(configuration) {
9
7
  if (isTest()) {
10
8
  // In a test environment, we mock the MMKV instance.
11
- return createMockMMKV();
12
- }
13
- if (platformContext == null) {
14
- // Lazy-init the platform-context HybridObject
15
- platformContext = NitroModules.createHybridObject('MMKVPlatformContext');
16
- }
17
- if (factory == null) {
18
- // Lazy-init the factory HybridObject
19
- factory = NitroModules.createHybridObject('MMKVFactory');
20
- const baseDirectory = platformContext.getBaseDirectory();
21
- factory.initializeMMKV(baseDirectory);
9
+ return createMockMMKV(configuration);
22
10
  }
11
+ const factory = getMMKVFactory();
23
12
  // Pre-parse the config
24
13
  let config = configuration ?? { id: factory.defaultMMKVInstanceId };
25
14
  if (Platform.OS === 'ios') {
26
15
  if (config.path == null) {
27
16
  // If the user set an App Group directory in Info.plist, let's use
28
17
  // the App Group as a MMKV path:
18
+ const platformContext = getPlatformContext();
29
19
  const appGroupDirectory = platformContext.getAppGroupDirectory();
30
20
  if (appGroupDirectory != null) {
31
21
  config.path = appGroupDirectory;
@@ -1,17 +1,5 @@
1
1
  import { createTextEncoder } from '../web/createTextEncoder';
2
- const canUseDOM = typeof window !== 'undefined' && window.document?.createElement != null;
3
- const hasAccessToLocalStorage = () => {
4
- try {
5
- // throws ACCESS_DENIED error
6
- window.localStorage;
7
- return true;
8
- }
9
- catch {
10
- return false;
11
- }
12
- };
13
- const KEY_WILDCARD = '\\';
14
- const inMemoryStorage = new Map();
2
+ import { getLocalStorage, LOCAL_STORAGE_KEY_WILDCARD, } from '../web/getLocalStorage';
15
3
  export function createMMKV(config = { id: 'mmkv.default' }) {
16
4
  if (config.encryptionKey != null) {
17
5
  throw new Error("MMKV: 'encryptionKey' is not supported on Web!");
@@ -19,36 +7,12 @@ export function createMMKV(config = { id: 'mmkv.default' }) {
19
7
  if (config.path != null) {
20
8
  throw new Error("MMKV: 'path' is not supported on Web!");
21
9
  }
22
- // canUseDOM check prevents spam in Node server environments, such as Next.js server side props.
23
- if (!hasAccessToLocalStorage() && canUseDOM) {
24
- console.warn('MMKV: LocalStorage has been disabled. Your experience will be limited to in-memory storage!');
25
- }
26
- const storage = () => {
27
- if (!canUseDOM) {
28
- throw new Error('Tried to access storage on the server. Did you forget to call this in useEffect?');
29
- }
30
- if (!hasAccessToLocalStorage()) {
31
- return {
32
- getItem: (key) => inMemoryStorage.get(key) ?? null,
33
- setItem: (key, value) => inMemoryStorage.set(key, value),
34
- removeItem: (key) => inMemoryStorage.delete(key),
35
- clear: () => inMemoryStorage.clear(),
36
- length: inMemoryStorage.size,
37
- key: (index) => Object.keys(inMemoryStorage).at(index) ?? null,
38
- };
39
- }
40
- const domStorage = global?.localStorage ?? window?.localStorage ?? localStorage;
41
- if (domStorage == null) {
42
- throw new Error(`Could not find 'localStorage' instance!`);
43
- }
44
- return domStorage;
45
- };
46
10
  const textEncoder = createTextEncoder();
47
11
  const listeners = new Set();
48
- if (config.id.includes(KEY_WILDCARD)) {
12
+ if (config.id.includes(LOCAL_STORAGE_KEY_WILDCARD)) {
49
13
  throw new Error('MMKV: `id` cannot contain the backslash character (`\\`)!');
50
14
  }
51
- const keyPrefix = `${config.id}${KEY_WILDCARD}`; // mmkv.default\\
15
+ const keyPrefix = `${config.id}${LOCAL_STORAGE_KEY_WILDCARD}`; // mmkv.default\\
52
16
  const prefixedKey = (key) => {
53
17
  if (key.includes('\\')) {
54
18
  throw new Error('MMKV: `key` cannot contain the backslash character (`\\`)!');
@@ -59,58 +23,73 @@ export function createMMKV(config = { id: 'mmkv.default' }) {
59
23
  listeners.forEach((l) => l(key));
60
24
  };
61
25
  return {
26
+ id: config.id,
27
+ size: 0,
28
+ isReadOnly: false,
62
29
  clearAll: () => {
63
- const keys = Object.keys(storage());
30
+ const storage = getLocalStorage();
31
+ const keys = Object.keys(storage);
64
32
  for (const key of keys) {
65
33
  if (key.startsWith(keyPrefix)) {
66
- storage().removeItem(key);
34
+ storage.removeItem(key);
67
35
  callListeners(key);
68
36
  }
69
37
  }
70
38
  },
71
39
  remove: (key) => {
72
- const wasRemoved = storage().removeItem(prefixedKey(key)) ?? false;
40
+ const storage = getLocalStorage();
41
+ storage.removeItem(prefixedKey(key));
42
+ const wasRemoved = storage.getItem(prefixedKey(key)) === null;
73
43
  if (wasRemoved)
74
44
  callListeners(key);
75
45
  return wasRemoved;
76
46
  },
77
47
  set: (key, value) => {
48
+ const storage = getLocalStorage();
78
49
  if (key === '')
79
50
  throw new Error('Cannot set a value for an empty key!');
80
- storage().setItem(prefixedKey(key), value.toString());
51
+ storage.setItem(prefixedKey(key), value.toString());
81
52
  callListeners(key);
82
53
  },
83
- getString: (key) => storage().getItem(prefixedKey(key)) ?? undefined,
54
+ getString: (key) => {
55
+ const storage = getLocalStorage();
56
+ return storage.getItem(prefixedKey(key)) ?? undefined;
57
+ },
84
58
  getNumber: (key) => {
85
- const value = storage().getItem(prefixedKey(key));
59
+ const storage = getLocalStorage();
60
+ const value = storage.getItem(prefixedKey(key));
86
61
  if (value == null)
87
62
  return undefined;
88
63
  return Number(value);
89
64
  },
90
65
  getBoolean: (key) => {
91
- const value = storage().getItem(prefixedKey(key));
66
+ const storage = getLocalStorage();
67
+ const value = storage.getItem(prefixedKey(key));
92
68
  if (value == null)
93
69
  return undefined;
94
70
  return value === 'true';
95
71
  },
96
72
  getBuffer: (key) => {
97
- const value = storage().getItem(prefixedKey(key));
73
+ const storage = getLocalStorage();
74
+ const value = storage.getItem(prefixedKey(key));
98
75
  if (value == null)
99
76
  return undefined;
100
77
  return textEncoder.encode(value).buffer;
101
78
  },
102
79
  getAllKeys: () => {
103
- const keys = Object.keys(storage());
80
+ const storage = getLocalStorage();
81
+ const keys = Object.keys(storage);
104
82
  return keys
105
83
  .filter((key) => key.startsWith(keyPrefix))
106
84
  .map((key) => key.slice(keyPrefix.length));
107
85
  },
108
- contains: (key) => storage().getItem(prefixedKey(key)) != null,
86
+ contains: (key) => {
87
+ const storage = getLocalStorage();
88
+ return storage.getItem(prefixedKey(key)) != null;
89
+ },
109
90
  recrypt: () => {
110
91
  throw new Error('`recrypt(..)` is not supported on Web!');
111
92
  },
112
- size: 0,
113
- isReadOnly: false,
114
93
  trim: () => {
115
94
  // no-op
116
95
  },
@@ -125,5 +104,18 @@ export function createMMKV(config = { id: 'mmkv.default' }) {
125
104
  },
126
105
  };
127
106
  },
107
+ importAllFrom: (other) => {
108
+ const storage = getLocalStorage();
109
+ const keys = other.getAllKeys();
110
+ let imported = 0;
111
+ for (const key of keys) {
112
+ const string = other.getString(key);
113
+ if (string != null) {
114
+ storage.set(key, string);
115
+ imported++;
116
+ }
117
+ }
118
+ return imported;
119
+ },
128
120
  };
129
121
  }
@@ -1,5 +1,6 @@
1
1
  import type { MMKV } from '../specs/MMKV.nitro';
2
+ import type { Configuration } from '../specs/MMKVFactory.nitro';
2
3
  /**
3
4
  * Mock MMKV instance when used in a Jest/Test environment.
4
5
  */
5
- export declare function createMockMMKV(): MMKV;
6
+ export declare function createMockMMKV(config?: Configuration): MMKV;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Mock MMKV instance when used in a Jest/Test environment.
3
3
  */
4
- export function createMockMMKV() {
4
+ export function createMockMMKV(config = { id: 'mmkv.default' }) {
5
5
  const storage = new Map();
6
6
  const listeners = new Set();
7
7
  const notifyListeners = (key) => {
@@ -10,6 +10,11 @@ export function createMockMMKV() {
10
10
  });
11
11
  };
12
12
  return {
13
+ id: config.id,
14
+ get size() {
15
+ return storage.size;
16
+ },
17
+ isReadOnly: false,
13
18
  clearAll: () => {
14
19
  const keysBefore = storage.keys();
15
20
  storage.clear();
@@ -52,10 +57,6 @@ export function createMockMMKV() {
52
57
  recrypt: () => {
53
58
  console.warn('Encryption is not supported in mocked MMKV instances!');
54
59
  },
55
- get size() {
56
- return storage.size;
57
- },
58
- isReadOnly: false,
59
60
  trim: () => {
60
61
  // no-op
61
62
  },
@@ -72,5 +73,17 @@ export function createMockMMKV() {
72
73
  },
73
74
  };
74
75
  },
76
+ importAllFrom: (other) => {
77
+ const keys = other.getAllKeys();
78
+ let imported = 0;
79
+ for (const key of keys) {
80
+ const data = other.getBuffer(key);
81
+ if (data != null) {
82
+ storage.set(key, data);
83
+ imported++;
84
+ }
85
+ }
86
+ return imported;
87
+ },
75
88
  };
76
89
  }
@@ -0,0 +1 @@
1
+ export declare function deleteMMKV(id: string): boolean;
@@ -0,0 +1,9 @@
1
+ import { getMMKVFactory } from '../getMMKVFactory';
2
+ import { isTest } from '../isTest';
3
+ export function deleteMMKV(id) {
4
+ if (isTest()) {
5
+ return true;
6
+ }
7
+ const factory = getMMKVFactory();
8
+ return factory.deleteMMKV(id);
9
+ }
@@ -0,0 +1 @@
1
+ export declare function deleteMMKV(id: string): boolean;
@@ -0,0 +1,14 @@
1
+ import { getLocalStorage, LOCAL_STORAGE_KEY_WILDCARD, } from '../web/getLocalStorage';
2
+ export function deleteMMKV(id) {
3
+ const storage = getLocalStorage();
4
+ const prefix = id + LOCAL_STORAGE_KEY_WILDCARD;
5
+ let wasRemoved = false;
6
+ const keys = Object.keys(storage);
7
+ for (const key of keys) {
8
+ if (key.startsWith(prefix)) {
9
+ storage.removeItem(key);
10
+ wasRemoved = true;
11
+ }
12
+ }
13
+ return wasRemoved;
14
+ }
@@ -0,0 +1 @@
1
+ export declare function existsMMKV(id: string): boolean;
@@ -0,0 +1,9 @@
1
+ import { getMMKVFactory } from '../getMMKVFactory';
2
+ import { isTest } from '../isTest';
3
+ export function existsMMKV(id) {
4
+ if (isTest()) {
5
+ return true;
6
+ }
7
+ const factory = getMMKVFactory();
8
+ return factory.existsMMKV(id);
9
+ }
@@ -0,0 +1 @@
1
+ export declare function existsMMKV(id: string): boolean;
@@ -0,0 +1,7 @@
1
+ import { getLocalStorage, LOCAL_STORAGE_KEY_WILDCARD, } from '../web/getLocalStorage';
2
+ export function existsMMKV(id) {
3
+ const storage = getLocalStorage();
4
+ const prefix = id + LOCAL_STORAGE_KEY_WILDCARD;
5
+ const keys = Object.keys(storage);
6
+ return keys.some((k) => k.startsWith(prefix));
7
+ }
@@ -0,0 +1,4 @@
1
+ import type { MMKVFactory } from './specs/MMKVFactory.nitro';
2
+ import type { MMKVPlatformContext } from './specs/MMKVPlatformContext.nitro';
3
+ export declare function getPlatformContext(): MMKVPlatformContext;
4
+ export declare function getMMKVFactory(): MMKVFactory;
@@ -0,0 +1,20 @@
1
+ import { NitroModules } from 'react-native-nitro-modules';
2
+ let factory;
3
+ let platformContext;
4
+ export function getPlatformContext() {
5
+ if (platformContext == null) {
6
+ // Lazy-init the platform-context HybridObject
7
+ platformContext = NitroModules.createHybridObject('MMKVPlatformContext');
8
+ }
9
+ return platformContext;
10
+ }
11
+ export function getMMKVFactory() {
12
+ if (factory == null) {
13
+ // Lazy-init the factory HybridObject
14
+ factory = NitroModules.createHybridObject('MMKVFactory');
15
+ const context = getPlatformContext();
16
+ const baseDirectory = context.getBaseDirectory();
17
+ factory.initializeMMKV(baseDirectory);
18
+ }
19
+ return factory;
20
+ }
package/lib/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  export type { MMKV } from './specs/MMKV.nitro';
2
2
  export type { Configuration, Mode } from './specs/MMKVFactory.nitro';
3
3
  export { createMMKV } from './createMMKV/createMMKV';
4
+ export { existsMMKV } from './existsMMKV/existsMMKV';
5
+ export { deleteMMKV } from './deleteMMKV/deleteMMKV';
4
6
  export { useMMKV } from './hooks/useMMKV';
5
7
  export { useMMKVBoolean } from './hooks/useMMKVBoolean';
6
8
  export { useMMKVBuffer } from './hooks/useMMKVBuffer';
package/lib/index.js CHANGED
@@ -1,5 +1,8 @@
1
1
  // The create function
2
2
  export { createMMKV } from './createMMKV/createMMKV';
3
+ // Exists + Delete
4
+ export { existsMMKV } from './existsMMKV/existsMMKV';
5
+ export { deleteMMKV } from './deleteMMKV/deleteMMKV';
3
6
  // All the hooks
4
7
  export { useMMKV } from './hooks/useMMKV';
5
8
  export { useMMKVBoolean } from './hooks/useMMKVBoolean';
@@ -6,6 +6,19 @@ export interface MMKV extends HybridObject<{
6
6
  ios: 'c++';
7
7
  android: 'c++';
8
8
  }> {
9
+ /**
10
+ * Get the ID of this {@linkcode MMKV} instance.
11
+ */
12
+ readonly id: string;
13
+ /**
14
+ * Get the current total size of the storage, in bytes.
15
+ */
16
+ readonly size: number;
17
+ /**
18
+ * Returns whether this instance is in read-only mode or not.
19
+ * If this is `true`, you can only use "get"-functions.
20
+ */
21
+ readonly isReadOnly: boolean;
9
22
  /**
10
23
  * Set a {@linkcode value} for the given {@linkcode key}.
11
24
  *
@@ -76,15 +89,6 @@ export interface MMKV extends HybridObject<{
76
89
  * In most applications, this is not needed at all.
77
90
  */
78
91
  trim(): void;
79
- /**
80
- * Get the current total size of the storage, in bytes.
81
- */
82
- readonly size: number;
83
- /**
84
- * Returns whether this instance is in read-only mode or not.
85
- * If this is `true`, you can only use "get"-functions.
86
- */
87
- readonly isReadOnly: boolean;
88
92
  /**
89
93
  * Adds a value changed listener. The Listener will be called whenever any value
90
94
  * in this storage instance changes (set or delete).
@@ -92,4 +96,10 @@ export interface MMKV extends HybridObject<{
92
96
  * To unsubscribe from value changes, call `remove()` on the Listener.
93
97
  */
94
98
  addOnValueChangedListener(onValueChanged: (key: string) => void): Listener;
99
+ /**
100
+ * Imports all keys and values from the
101
+ * given other {@linkcode MMKV} instance.
102
+ * @returns the number of imported keys/values.
103
+ */
104
+ importAllFrom(other: MMKV): number;
95
105
  }
@@ -67,15 +67,25 @@ export interface MMKVFactory extends HybridObject<{
67
67
  ios: 'c++';
68
68
  android: 'c++';
69
69
  }> {
70
+ /**
71
+ * Initialize the MMKV library with the given root path.
72
+ * This has to be called once, before using {@linkcode createMMKV}.
73
+ */
74
+ initializeMMKV(rootPath: string): void;
70
75
  /**
71
76
  * Create a new {@linkcode MMKV} instance with the given {@linkcode Configuration}
72
77
  */
73
78
  createMMKV(configuration: Configuration): MMKV;
74
79
  /**
75
- * Initialize the MMKV library with the given root path.
76
- * This has to be called once, before using {@linkcode createMMKV}.
80
+ * Deletes the MMKV instance with the
81
+ * given {@linkcode id}.
77
82
  */
78
- initializeMMKV(rootPath: string): void;
83
+ deleteMMKV(id: string): boolean;
84
+ /**
85
+ * Returns `true` if an MMKV instance with the
86
+ * given {@linkcode id} exists, `false` otherwise.
87
+ */
88
+ existsMMKV(id: string): boolean;
79
89
  /**
80
90
  * Get the default MMKV instance's ID.
81
91
  * @default 'mmkv.default'
@@ -0,0 +1,2 @@
1
+ export declare const LOCAL_STORAGE_KEY_WILDCARD = "\\";
2
+ export declare function getLocalStorage(): Storage;
@@ -0,0 +1,33 @@
1
+ export const LOCAL_STORAGE_KEY_WILDCARD = '\\';
2
+ const canUseDOM = typeof window !== 'undefined' && window.document?.createElement != null;
3
+ const hasAccessToLocalStorage = () => {
4
+ try {
5
+ // throws ACCESS_DENIED error
6
+ window.localStorage;
7
+ return true;
8
+ }
9
+ catch {
10
+ return false;
11
+ }
12
+ };
13
+ const inMemoryStorage = new Map();
14
+ export function getLocalStorage() {
15
+ if (!canUseDOM) {
16
+ throw new Error('Tried to access storage on the server. Did you forget to call this in useEffect?');
17
+ }
18
+ if (!hasAccessToLocalStorage()) {
19
+ return {
20
+ getItem: (key) => inMemoryStorage.get(key) ?? null,
21
+ setItem: (key, value) => inMemoryStorage.set(key, value),
22
+ removeItem: (key) => inMemoryStorage.delete(key),
23
+ clear: () => inMemoryStorage.clear(),
24
+ length: inMemoryStorage.size,
25
+ key: (index) => Object.keys(inMemoryStorage).at(index) ?? null,
26
+ };
27
+ }
28
+ const domStorage = global?.localStorage ?? window?.localStorage ?? localStorage;
29
+ if (domStorage == null) {
30
+ throw new Error(`Could not find 'localStorage' instance!`);
31
+ }
32
+ return domStorage;
33
+ }
@@ -34,6 +34,12 @@ namespace margelo::nitro::mmkv {
34
34
  method(_javaPart);
35
35
  }
36
36
 
37
+ std::string JHybridMMKVPlatformContextSpec::toString() {
38
+ static const auto method = javaClassStatic()->getMethod<jni::JString()>("toString");
39
+ auto javaString = method(_javaPart);
40
+ return javaString->toStdString();
41
+ }
42
+
37
43
  // Properties
38
44
 
39
45
 
@@ -41,6 +41,7 @@ namespace margelo::nitro::mmkv {
41
41
  public:
42
42
  size_t getExternalMemorySize() noexcept override;
43
43
  void dispose() noexcept override;
44
+ std::string toString() override;
44
45
 
45
46
  public:
46
47
  inline const jni::global_ref<JHybridMMKVPlatformContextSpec::javaobject>& getJavaPart() const noexcept {
@@ -36,6 +36,11 @@ abstract class HybridMMKVPlatformContextSpec: HybridObject() {
36
36
  super.updateNative(hybridData)
37
37
  }
38
38
 
39
+ // Default implementation of `HybridObject.toString()`
40
+ override fun toString(): String {
41
+ return "[HybridObject MMKVPlatformContext]"
42
+ }
43
+
39
44
  // Properties
40
45
 
41
46
 
@@ -10,6 +10,7 @@
10
10
  // Include C++ implementation defined types
11
11
  #include "HybridMMKVPlatformContextSpecSwift.hpp"
12
12
  #include "NitroMmkv-Swift-Cxx-Umbrella.hpp"
13
+ #include <NitroModules/NitroDefines.hpp>
13
14
 
14
15
  namespace margelo::nitro::mmkv::bridge::swift {
15
16
 
@@ -51,6 +51,9 @@ namespace margelo::nitro::mmkv {
51
51
  void dispose() noexcept override {
52
52
  _swiftPart.dispose();
53
53
  }
54
+ std::string toString() override {
55
+ return _swiftPart.toString();
56
+ }
54
57
 
55
58
  public:
56
59
  // Properties
@@ -18,6 +18,13 @@ public protocol HybridMMKVPlatformContextSpec_protocol: HybridObject {
18
18
  func getAppGroupDirectory() throws -> String?
19
19
  }
20
20
 
21
+ public extension HybridMMKVPlatformContextSpec_protocol {
22
+ /// Default implementation of ``HybridObject.toString``
23
+ func toString() -> String {
24
+ return "[HybridObject MMKVPlatformContext]"
25
+ }
26
+ }
27
+
21
28
  /// See ``HybridMMKVPlatformContextSpec``
22
29
  open class HybridMMKVPlatformContextSpec_base {
23
30
  private weak var cxxWrapper: HybridMMKVPlatformContextSpec_cxx? = nil