react-native-mmkv 2.12.1 → 3.0.0-beta.1

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 (116) hide show
  1. package/LICENSE +1 -200
  2. package/MMKV/Core/Core.xcodeproj/project.pbxproj +4 -2
  3. package/MMKV/Core/MMKVPredef.h +1 -1
  4. package/MMKV/Core/MMKV_IO.cpp +5 -1
  5. package/MMKV/Core/MemoryFile.cpp +1 -0
  6. package/MMKV/Core/MemoryFile_OSX.cpp +2 -1
  7. package/MMKV/README.md +8 -8
  8. package/README.md +7 -1
  9. package/android/CMakeLists.txt +20 -28
  10. package/android/build.gradle +59 -89
  11. package/android/gradle.properties +4 -5
  12. package/android/src/main/AndroidManifest.xml +2 -2
  13. package/android/src/{hasNamespace/AndroidManifest.xml → main/AndroidManifestNew.xml} +0 -1
  14. package/android/src/main/cpp/AndroidLogger.cpp +16 -0
  15. package/android/src/main/cpp/cpp-adapter.cpp +4 -80
  16. package/android/src/main/java/com/mrousavy/mmkv/MmkvPackage.java +44 -0
  17. package/android/src/main/java/com/mrousavy/mmkv/MmkvPlatformContextModule.java +17 -0
  18. package/cpp/Logger.h +35 -0
  19. package/cpp/MMKVManagedBuffer.h +37 -0
  20. package/{android/src/main/cpp → cpp}/MmkvHostObject.cpp +126 -63
  21. package/{android/src/main/cpp → cpp}/MmkvHostObject.h +14 -3
  22. package/cpp/NativeMmkvModule.cpp +40 -0
  23. package/cpp/NativeMmkvModule.h +37 -0
  24. package/ios/AppleLogger.mm +16 -0
  25. package/ios/MmkvOnLoad.mm +25 -0
  26. package/ios/MmkvPlatformContext.h +19 -0
  27. package/ios/MmkvPlatformContextModule.mm +37 -0
  28. package/lib/commonjs/MMKV.js +34 -4
  29. package/lib/commonjs/MMKV.js.map +1 -1
  30. package/lib/commonjs/NativeMmkv.js +66 -0
  31. package/lib/commonjs/NativeMmkv.js.map +1 -0
  32. package/lib/commonjs/NativeMmkvPlatformContext.js +9 -0
  33. package/lib/commonjs/NativeMmkvPlatformContext.js.map +1 -0
  34. package/lib/commonjs/PlatformChecker.js.map +1 -1
  35. package/lib/commonjs/createMMKV.js +7 -43
  36. package/lib/commonjs/createMMKV.js.map +1 -1
  37. package/lib/commonjs/createMMKV.mock.js +5 -1
  38. package/lib/commonjs/createMMKV.mock.js.map +1 -1
  39. package/lib/commonjs/createMMKV.web.js +8 -4
  40. package/lib/commonjs/createMMKV.web.js.map +1 -1
  41. package/lib/commonjs/createTextEncoder.js.map +1 -1
  42. package/lib/commonjs/hooks.js +11 -10
  43. package/lib/commonjs/hooks.js.map +1 -1
  44. package/lib/commonjs/index.js.map +1 -1
  45. package/lib/module/MMKV.js +23 -4
  46. package/lib/module/MMKV.js.map +1 -1
  47. package/lib/module/NativeMmkv.js +63 -0
  48. package/lib/module/NativeMmkv.js.map +1 -0
  49. package/lib/module/NativeMmkvPlatformContext.js +3 -0
  50. package/lib/module/NativeMmkvPlatformContext.js.map +1 -0
  51. package/lib/module/PlatformChecker.js.map +1 -1
  52. package/lib/module/createMMKV.js +7 -43
  53. package/lib/module/createMMKV.js.map +1 -1
  54. package/lib/module/createMMKV.mock.js +5 -1
  55. package/lib/module/createMMKV.mock.js.map +1 -1
  56. package/lib/module/createMMKV.web.js +6 -4
  57. package/lib/module/createMMKV.web.js.map +1 -1
  58. package/lib/module/createTextEncoder.js.map +1 -1
  59. package/lib/module/hooks.js +7 -2
  60. package/lib/module/hooks.js.map +1 -1
  61. package/lib/module/index.js.map +1 -1
  62. package/lib/typescript/{MMKV.d.ts → src/MMKV.d.ts} +26 -49
  63. package/lib/typescript/src/MMKV.d.ts.map +1 -0
  64. package/lib/typescript/src/NativeMmkv.d.ts +79 -0
  65. package/lib/typescript/src/NativeMmkv.d.ts.map +1 -0
  66. package/lib/typescript/src/NativeMmkvPlatformContext.d.ts +9 -0
  67. package/lib/typescript/src/NativeMmkvPlatformContext.d.ts.map +1 -0
  68. package/lib/typescript/src/PlatformChecker.d.ts.map +1 -0
  69. package/lib/typescript/src/__tests__/hooks.test.d.ts +2 -0
  70. package/lib/typescript/src/__tests__/hooks.test.d.ts.map +1 -0
  71. package/lib/typescript/src/createMMKV.d.ts +3 -0
  72. package/lib/typescript/src/createMMKV.d.ts.map +1 -0
  73. package/lib/typescript/src/createMMKV.mock.d.ts +3 -0
  74. package/lib/typescript/src/createMMKV.mock.d.ts.map +1 -0
  75. package/lib/typescript/src/createMMKV.web.d.ts +3 -0
  76. package/lib/typescript/src/createMMKV.web.d.ts.map +1 -0
  77. package/lib/typescript/src/createTextEncoder.d.ts.map +1 -0
  78. package/lib/typescript/{hooks.d.ts → src/hooks.d.ts} +7 -4
  79. package/lib/typescript/src/hooks.d.ts.map +1 -0
  80. package/lib/typescript/src/index.d.ts.map +1 -0
  81. package/package.json +49 -40
  82. package/react-native-mmkv.podspec +17 -14
  83. package/src/MMKV.ts +40 -62
  84. package/src/NativeMmkv.ts +132 -0
  85. package/src/NativeMmkvPlatformContext.ts +12 -0
  86. package/src/__tests__/hooks.test.tsx +88 -0
  87. package/src/createMMKV.mock.ts +7 -3
  88. package/src/createMMKV.ts +9 -63
  89. package/src/createMMKV.web.ts +6 -2
  90. package/src/hooks.ts +17 -11
  91. package/android/src/main/java/com/reactnativemmkv/MmkvModule.java +0 -49
  92. package/android/src/main/java/com/reactnativemmkv/MmkvPackage.java +0 -26
  93. package/cpp/TypedArray.cpp +0 -322
  94. package/cpp/TypedArray.h +0 -153
  95. package/ios/JSIUtils.h +0 -38
  96. package/ios/JSIUtils.mm +0 -167
  97. package/ios/Mmkv.xcodeproj/project.pbxproj +0 -291
  98. package/ios/MmkvHostObject.h +0 -27
  99. package/ios/MmkvHostObject.mm +0 -295
  100. package/ios/MmkvModule.h +0 -5
  101. package/ios/MmkvModule.mm +0 -101
  102. package/lib/typescript/MMKV.d.ts.map +0 -1
  103. package/lib/typescript/PlatformChecker.d.ts.map +0 -1
  104. package/lib/typescript/createMMKV.d.ts +0 -7
  105. package/lib/typescript/createMMKV.d.ts.map +0 -1
  106. package/lib/typescript/createMMKV.mock.d.ts +0 -3
  107. package/lib/typescript/createMMKV.mock.d.ts.map +0 -1
  108. package/lib/typescript/createMMKV.web.d.ts +0 -3
  109. package/lib/typescript/createMMKV.web.d.ts.map +0 -1
  110. package/lib/typescript/createTextEncoder.d.ts.map +0 -1
  111. package/lib/typescript/hooks.d.ts.map +0 -1
  112. package/lib/typescript/index.d.ts.map +0 -1
  113. /package/lib/typescript/{PlatformChecker.d.ts → src/PlatformChecker.d.ts} +0 -0
  114. /package/lib/typescript/{createTextEncoder.d.ts → src/createTextEncoder.d.ts} +0 -0
  115. /package/lib/typescript/{index.d.ts → src/index.d.ts} +0 -0
  116. /package/src/{index.ts → index.tsx} +0 -0
@@ -0,0 +1,132 @@
1
+ import { NativeModules, Platform, TurboModule } from 'react-native';
2
+ import { TurboModuleRegistry } from 'react-native';
3
+ import { UnsafeObject } from 'react-native/Libraries/Types/CodegenTypes';
4
+ import { PlatformContext } from './NativeMmkvPlatformContext';
5
+
6
+ /**
7
+ * Configures the mode of the MMKV instance.
8
+ */
9
+ export enum Mode {
10
+ /**
11
+ * The MMKV instance is only used from a single process (this app).
12
+ */
13
+ SINGLE_PROCESS,
14
+ /**
15
+ * The MMKV instance may be used from multiple processes, such as app clips, share extensions or background services.
16
+ */
17
+ MULTI_PROCESS,
18
+ }
19
+
20
+ /**
21
+ * Used for configuration of a single MMKV instance.
22
+ */
23
+ export interface Configuration {
24
+ /**
25
+ * The MMKV instance's ID. If you want to use multiple instances, make sure to use different IDs!
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * const userStorage = new MMKV({ id: `user-${userId}-storage` })
30
+ * const globalStorage = new MMKV({ id: 'global-app-storage' })
31
+ * ```
32
+ *
33
+ * @default 'mmkv.default'
34
+ */
35
+ id: string;
36
+ /**
37
+ * The MMKV instance's root path. By default, MMKV stores file inside `$(Documents)/mmkv/`. You can customize MMKV's root directory on MMKV initialization:
38
+
39
+ * @example
40
+ * ```ts
41
+ * const temporaryStorage = new MMKV({ path: '/tmp/' })
42
+ * ```
43
+ *
44
+ * _Notice_: On iOS you can set the AppGroup bundle property to share the same storage between your app and its extensions.
45
+ * In this case `path` property will be ignored.
46
+ * See more on MMKV configuration [here](https://github.com/Tencent/MMKV/wiki/iOS_tutorial#configuration).
47
+ *
48
+ * @default undefined
49
+ */
50
+ path?: string;
51
+ /**
52
+ * 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.
53
+ *
54
+ * Encryption keys can have a maximum length of 16 bytes.
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * const secureStorage = new MMKV({ encryptionKey: 'my-encryption-key!' })
59
+ * ```
60
+ *
61
+ * @default undefined
62
+ */
63
+ encryptionKey?: string;
64
+ /**
65
+ * Configure the processing mode for MMKV.
66
+ * - `SINGLE_PROCESS`: The MMKV instance is only used from a single process (this app).
67
+ * - `MULTI_PROCESS`: The MMKV instance may be used from multiple processes, such as app clips, share extensions or background services.
68
+ *
69
+ * @default SINGLE_PROCESS
70
+ */
71
+ mode?: Mode;
72
+ }
73
+
74
+ export interface Spec extends TurboModule {
75
+ initialize(basePath: string): boolean;
76
+ createMMKV(configuration: Configuration): UnsafeObject;
77
+ }
78
+
79
+ let module: Spec | null = null;
80
+ let basePath: string | null = null;
81
+
82
+ /**
83
+ * Get the MMKV TurboModule, and initialize it if this is the first time calling.
84
+ * This will throw an error if the module cannot be found.
85
+ */
86
+ export function getMMKVTurboModule(): Spec {
87
+ if (module == null) {
88
+ // try to find the turbomodule
89
+ module = TurboModuleRegistry.get<Spec>('MmkvCxx');
90
+
91
+ if (module == null) {
92
+ // if it still is null, something went wrong!
93
+ let message =
94
+ 'Failed to create a new MMKV instance: The native MMKV Module could not be found.';
95
+ message +=
96
+ '\n* Make sure react-native-mmkv is correctly autolinked (run `npx react-native config` to verify)';
97
+ if (Platform.OS === 'ios' || Platform.OS === 'macos') {
98
+ message += '\n* Make sure you ran `pod install` in the ios/ directory.';
99
+ }
100
+ if (Platform.OS === 'android') {
101
+ message += '\n* Make sure gradle is synced.';
102
+ }
103
+ // check if Expo
104
+ const ExpoConstants =
105
+ NativeModules.NativeUnimoduleProxy?.modulesConstants?.ExponentConstants;
106
+ if (ExpoConstants != null) {
107
+ if (ExpoConstants.appOwnership === 'expo') {
108
+ // We're running Expo Go
109
+ throw new Error(
110
+ 'react-native-mmkv is not supported in Expo Go! Use EAS (`expo prebuild`) or eject to a bare workflow instead.'
111
+ );
112
+ } else {
113
+ // We're running Expo bare / standalone
114
+ message += '\n* Make sure you ran `expo prebuild`.';
115
+ }
116
+ }
117
+
118
+ message += '\n* Make sure you rebuilt the app.';
119
+ throw new Error(message);
120
+ }
121
+
122
+ if (basePath == null) {
123
+ // Get base path from platform specific context
124
+ basePath = PlatformContext.getBaseDirectory();
125
+ }
126
+
127
+ // Initialize MMKV
128
+ module.initialize(basePath);
129
+ }
130
+
131
+ return module;
132
+ }
@@ -0,0 +1,12 @@
1
+ import { TurboModule, TurboModuleRegistry } from 'react-native';
2
+
3
+ export interface Spec extends TurboModule {
4
+ /**
5
+ * Gets the base directory of the documents storage
6
+ */
7
+ getBaseDirectory(): string;
8
+ }
9
+
10
+ export const PlatformContext = TurboModuleRegistry.getEnforcing<Spec>(
11
+ 'MmkvPlatformContext'
12
+ );
@@ -0,0 +1,88 @@
1
+ import React from 'react';
2
+ import { Button, Text } from 'react-native';
3
+ import {
4
+ act,
5
+ fireEvent,
6
+ render,
7
+ renderHook,
8
+ screen,
9
+ } from '@testing-library/react-native';
10
+ import { MMKV, useMMKVNumber, useMMKVString } from '..';
11
+
12
+ const mmkv = new MMKV();
13
+
14
+ beforeEach(() => {
15
+ mmkv.clearAll();
16
+ });
17
+
18
+ test('hooks update when the value is changed directly through the instance', () => {
19
+ const { result } = renderHook(() => useMMKVString('string-key', mmkv));
20
+
21
+ expect(result.current[0]).toBeUndefined();
22
+
23
+ // First, make a "normal" change
24
+ act(() => {
25
+ result.current[1]('value 1');
26
+ });
27
+
28
+ expect(result.current[0]).toStrictEqual('value 1');
29
+
30
+ // Now, make the change directly through the instance.
31
+ act(() => {
32
+ mmkv.set('string-key', 'value 2');
33
+ });
34
+ expect(result.current[0]).toStrictEqual('value 2');
35
+ });
36
+
37
+ test('functional updates to hooks', () => {
38
+ const Component: React.FC = () => {
39
+ const [state, setState] = React.useState(0);
40
+ const [value, setValue] = useMMKVNumber('number-key', mmkv);
41
+
42
+ return (
43
+ <>
44
+ <Button
45
+ testID="button"
46
+ title="Double Increment Me"
47
+ onPress={() => {
48
+ // Increment the state value twice, using the function form of useState.
49
+ setState((current) => current + 1);
50
+ setState((current) => current + 1);
51
+
52
+ // Increment the MMKV value twice, using the same function form.
53
+ setValue((current) => (current ?? 0) + 1);
54
+ setValue((current) => (current ?? 0) + 1);
55
+ }}
56
+ />
57
+ <Text testID="state-value">State: {state.toString()}</Text>
58
+ <Text testID="mmkv-value">MMKV: {(value ?? 0).toString()}</Text>
59
+ </>
60
+ );
61
+ };
62
+
63
+ render(<Component />);
64
+
65
+ const button = screen.getByTestId('button');
66
+
67
+ // Why these assertions:
68
+ // https://github.com/mrousavy/react-native-mmkv/issues/599
69
+ fireEvent.press(button);
70
+ expect(screen.getByTestId('state-value').children).toStrictEqual([
71
+ 'State: ',
72
+ '2',
73
+ ]);
74
+ expect(screen.getByTestId('mmkv-value').children).toStrictEqual([
75
+ 'MMKV: ',
76
+ '2',
77
+ ]);
78
+
79
+ fireEvent.press(button);
80
+ expect(screen.getByTestId('state-value').children).toStrictEqual([
81
+ 'State: ',
82
+ '4',
83
+ ]);
84
+ expect(screen.getByTestId('mmkv-value').children).toStrictEqual([
85
+ 'MMKV: ',
86
+ '4',
87
+ ]);
88
+ });
@@ -1,8 +1,8 @@
1
- import type { NativeMMKV } from 'react-native-mmkv';
1
+ import type { NativeMMKV } from './MMKV';
2
2
 
3
3
  /* Mock MMKV instance for use in tests */
4
4
  export const createMockMMKV = (): NativeMMKV => {
5
- const storage = new Map<string, string | boolean | number | Uint8Array>();
5
+ const storage = new Map<string, string | boolean | number | ArrayBuffer>();
6
6
 
7
7
  return {
8
8
  clearAll: () => storage.clear(),
@@ -22,12 +22,16 @@ export const createMockMMKV = (): NativeMMKV => {
22
22
  },
23
23
  getBuffer: (key) => {
24
24
  const result = storage.get(key);
25
- return result instanceof Uint8Array ? result : undefined;
25
+ return result instanceof ArrayBuffer ? result : undefined;
26
26
  },
27
27
  getAllKeys: () => Array.from(storage.keys()),
28
28
  contains: (key) => storage.has(key),
29
29
  recrypt: () => {
30
30
  console.warn('Encryption is not supported in mocked MMKV instances!');
31
31
  },
32
+ size: 0,
33
+ trim: () => {
34
+ // no-op
35
+ },
32
36
  };
33
37
  };
package/src/createMMKV.ts CHANGED
@@ -1,70 +1,16 @@
1
- import { NativeModules, Platform } from 'react-native';
2
- import type { MMKVConfiguration, NativeMMKV } from 'react-native-mmkv';
1
+ import type { Configuration, NativeMMKV } from './MMKV';
2
+ import { getMMKVTurboModule } from './NativeMmkv';
3
3
 
4
- // global func declaration for JSI functions
5
- declare global {
6
- function mmkvCreateNewInstance(configuration: MMKVConfiguration): NativeMMKV;
7
- function nativeCallSyncHook(): unknown;
8
- }
4
+ const module = getMMKVTurboModule();
9
5
 
10
- // Root directory of all MMKV stores
11
- const ROOT_DIRECTORY: string | null = null;
12
-
13
- export const createMMKV = (config: MMKVConfiguration): NativeMMKV => {
14
- // Check if the constructor exists. If not, try installing the JSI bindings.
15
- if (global.mmkvCreateNewInstance == null) {
16
- // Get the native MMKV ReactModule
17
- const MMKVModule = NativeModules.MMKV;
18
- if (MMKVModule == null) {
19
- let message =
20
- 'Failed to create a new MMKV instance: The native MMKV Module could not be found.';
21
- message +=
22
- '\n* Make sure react-native-mmkv is correctly autolinked (run `npx react-native config` to verify)';
23
- if (Platform.OS === 'ios' || Platform.OS === 'macos') {
24
- message += '\n* Make sure you ran `pod install` in the ios/ directory.';
25
- }
26
- if (Platform.OS === 'android') {
27
- message += '\n* Make sure gradle is synced.';
28
- }
29
- // check if Expo
30
- const ExpoConstants =
31
- NativeModules.NativeUnimoduleProxy?.modulesConstants?.ExponentConstants;
32
- if (ExpoConstants != null) {
33
- if (ExpoConstants.appOwnership === 'expo') {
34
- // We're running Expo Go
35
- throw new Error(
36
- 'react-native-mmkv is not supported in Expo Go! Use EAS (`expo prebuild`) or eject to a bare workflow instead.'
37
- );
38
- } else {
39
- // We're running Expo bare / standalone
40
- message += '\n* Make sure you ran `expo prebuild`.';
41
- }
42
- }
43
-
44
- message += '\n* Make sure you rebuilt the app.';
45
- throw new Error(message);
46
- }
47
-
48
- // Check if we are running on-device (JSI)
49
- if (global.nativeCallSyncHook == null || MMKVModule.install == null) {
6
+ export const createMMKV = (config: Configuration): NativeMMKV => {
7
+ const instance = module.createMMKV(config);
8
+ if (__DEV__) {
9
+ if (typeof instance !== 'object' || instance == null) {
50
10
  throw new Error(
51
- 'Failed to create a new MMKV instance: React Native is not running on-device. MMKV can only be used when synchronous method invocations (JSI) are possible. If you are using a remote debugger (e.g. Chrome), switch to an on-device debugger (e.g. Flipper) instead.'
11
+ 'Failed to create MMKV instance - an unknown object was returned by createMMKV(..)!'
52
12
  );
53
13
  }
54
-
55
- // Call the synchronous blocking install() function
56
- const result = MMKVModule.install(ROOT_DIRECTORY);
57
- if (result !== true)
58
- throw new Error(
59
- `Failed to create a new MMKV instance: The native MMKV Module could not be installed! Looks like something went wrong when installing JSI bindings: ${result}`
60
- );
61
-
62
- // Check again if the constructor now exists. If not, throw an error.
63
- if (global.mmkvCreateNewInstance == null)
64
- throw new Error(
65
- 'Failed to create a new MMKV instance, the native initializer function does not exist. Are you trying to use MMKV from different JS Runtimes?'
66
- );
67
14
  }
68
-
69
- return global.mmkvCreateNewInstance(config);
15
+ return instance as NativeMMKV;
70
16
  };
@@ -1,5 +1,5 @@
1
1
  /* global localStorage */
2
- import type { MMKVConfiguration, NativeMMKV } from 'react-native-mmkv';
2
+ import type { Configuration, NativeMMKV } from './MMKV';
3
3
  import { createTextEncoder } from './createTextEncoder';
4
4
 
5
5
  const canUseDOM =
@@ -19,7 +19,7 @@ const hasAccessToLocalStorage = () => {
19
19
  const KEY_WILDCARD = '\\';
20
20
  const inMemoryStorage = new Map<string, string>();
21
21
 
22
- export const createMMKV = (config: MMKVConfiguration): NativeMMKV => {
22
+ export const createMMKV = (config: Configuration): NativeMMKV => {
23
23
  if (config.encryptionKey != null) {
24
24
  throw new Error("MMKV: 'encryptionKey' is not supported on Web!");
25
25
  }
@@ -118,5 +118,9 @@ export const createMMKV = (config: MMKVConfiguration): NativeMMKV => {
118
118
  recrypt: () => {
119
119
  throw new Error('`recrypt(..)` is not supported on Web!');
120
120
  },
121
+ size: 0,
122
+ trim: () => {
123
+ // no-op
124
+ },
121
125
  };
122
126
  };
package/src/hooks.ts CHANGED
@@ -1,16 +1,17 @@
1
1
  import { useRef, useState, useMemo, useCallback, useEffect } from 'react';
2
- import { MMKV, MMKVConfiguration } from './MMKV';
2
+ import { MMKV, Configuration } from './MMKV';
3
3
 
4
4
  function isConfigurationEqual(
5
- left?: MMKVConfiguration,
6
- right?: MMKVConfiguration
5
+ left?: Configuration,
6
+ right?: Configuration
7
7
  ): boolean {
8
8
  if (left == null || right == null) return left == null && right == null;
9
9
 
10
10
  return (
11
11
  left.encryptionKey === right.encryptionKey &&
12
12
  left.id === right.id &&
13
- left.path === right.path
13
+ left.path === right.path &&
14
+ left.mode === right.mode
14
15
  );
15
16
  }
16
17
 
@@ -30,10 +31,10 @@ export function useMMKV(): MMKV;
30
31
  * Use a custom MMKV instance with the given configuration.
31
32
  * @param configuration The configuration to initialize the MMKV instance with. Does not have to be memoized.
32
33
  */
33
- export function useMMKV(configuration: MMKVConfiguration): MMKV;
34
- export function useMMKV(configuration?: MMKVConfiguration): MMKV {
34
+ export function useMMKV(configuration: Configuration): MMKV;
35
+ export function useMMKV(configuration?: Configuration): MMKV {
35
36
  const instance = useRef<MMKV>();
36
- const lastConfiguration = useRef<MMKVConfiguration>();
37
+ const lastConfiguration = useRef<Configuration>();
37
38
 
38
39
  if (configuration == null) return getDefaultInstance();
39
40
 
@@ -49,9 +50,9 @@ export function useMMKV(configuration?: MMKVConfiguration): MMKV {
49
50
  }
50
51
 
51
52
  function createMMKVHook<
52
- T extends (boolean | number | string | Uint8Array) | undefined,
53
+ T extends (boolean | number | string | ArrayBuffer) | undefined,
53
54
  TSet extends T | undefined,
54
- TSetAction extends TSet | ((current: T) => TSet)
55
+ TSetAction extends TSet | ((current: T) => TSet),
55
56
  >(getter: (instance: MMKV, key: string) => T) {
56
57
  return (
57
58
  key: string,
@@ -82,7 +83,7 @@ function createMMKVHook<
82
83
  mmkv.delete(key);
83
84
  break;
84
85
  case 'object':
85
- if (newValue instanceof Uint8Array) {
86
+ if (newValue instanceof ArrayBuffer) {
86
87
  mmkv.set(key, newValue);
87
88
  break;
88
89
  } else {
@@ -179,7 +180,12 @@ export const useMMKVBuffer = createMMKVHook((instance, key) =>
179
180
  export function useMMKVObject<T>(
180
181
  key: string,
181
182
  instance?: MMKV
182
- ): [value: T | undefined, setValue: (value: T | undefined) => void] {
183
+ ): [
184
+ value: T | undefined,
185
+ setValue: (
186
+ value: T | undefined | ((prevValue: T | undefined) => T | undefined)
187
+ ) => void,
188
+ ] {
183
189
  const [json, setJson] = useMMKVString(key, instance);
184
190
 
185
191
  const value = useMemo(() => {
@@ -1,49 +0,0 @@
1
- package com.reactnativemmkv;
2
-
3
- import android.util.Log;
4
-
5
- import androidx.annotation.NonNull;
6
- import androidx.annotation.Nullable;
7
-
8
- import com.facebook.react.bridge.JavaScriptContextHolder;
9
- import com.facebook.react.bridge.ReactContextBaseJavaModule;
10
- import com.facebook.react.bridge.ReactApplicationContext;
11
- import com.facebook.react.bridge.ReactMethod;
12
- import com.facebook.react.module.annotations.ReactModule;
13
-
14
- @ReactModule(name = MmkvModule.NAME)
15
- public class MmkvModule extends ReactContextBaseJavaModule {
16
- public static final String NAME = "MMKV";
17
-
18
- public MmkvModule(ReactApplicationContext reactContext) {
19
- super(reactContext);
20
- }
21
-
22
- @NonNull
23
- @Override
24
- public String getName() {
25
- return NAME;
26
- }
27
-
28
- @ReactMethod(isBlockingSynchronousMethod = true)
29
- public boolean install(@Nullable String rootDirectory) {
30
- try {
31
- Log.i(NAME, "Loading C++ library...");
32
- System.loadLibrary("reactnativemmkv");
33
-
34
- JavaScriptContextHolder jsContext = getReactApplicationContext().getJavaScriptContextHolder();
35
- if (rootDirectory == null) {
36
- rootDirectory = getReactApplicationContext().getFilesDir().getAbsolutePath() + "/mmkv";
37
- }
38
- Log.i(NAME, "Installing MMKV JSI Bindings for MMKV root directory: " + rootDirectory);
39
- nativeInstall(jsContext.get(), rootDirectory);
40
- Log.i(NAME, "Successfully installed MMKV JSI Bindings!");
41
- return true;
42
- } catch (Exception exception) {
43
- Log.e(NAME, "Failed to install MMKV JSI Bindings!", exception);
44
- return false;
45
- }
46
- }
47
-
48
- private static native void nativeInstall(long jsiPtr, String path);
49
- }
@@ -1,26 +0,0 @@
1
- package com.reactnativemmkv;
2
-
3
- import androidx.annotation.NonNull;
4
-
5
- import com.facebook.react.ReactPackage;
6
- import com.facebook.react.bridge.NativeModule;
7
- import com.facebook.react.bridge.ReactApplicationContext;
8
- import com.facebook.react.uimanager.ViewManager;
9
-
10
- import java.util.Collections;
11
- import java.util.List;
12
-
13
-
14
- public class MmkvPackage implements ReactPackage {
15
- @NonNull
16
- @Override
17
- public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
18
- return Collections.singletonList(new MmkvModule(reactContext));
19
- }
20
-
21
- @NonNull
22
- @Override
23
- public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
24
- return Collections.emptyList();
25
- }
26
- }