react-native-mmkv 2.12.2 → 3.0.0-beta.2
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/LICENSE +1 -200
- package/MMKV/Core/Core.xcodeproj/project.pbxproj +4 -2
- package/MMKV/Core/MMKVPredef.h +1 -1
- package/MMKV/Core/MMKV_IO.cpp +5 -1
- package/MMKV/Core/MemoryFile.cpp +1 -0
- package/MMKV/Core/MemoryFile_OSX.cpp +2 -1
- package/MMKV/README.md +8 -8
- package/README.md +35 -4
- package/android/CMakeLists.txt +20 -28
- package/android/build.gradle +59 -89
- package/android/gradle.properties +4 -5
- package/android/src/main/AndroidManifest.xml +2 -2
- package/android/src/{hasNamespace/AndroidManifest.xml → main/AndroidManifestNew.xml} +0 -1
- package/android/src/main/cpp/AndroidLogger.cpp +16 -0
- package/android/src/main/cpp/cpp-adapter.cpp +4 -80
- package/android/src/main/java/com/mrousavy/mmkv/MmkvPackage.java +44 -0
- package/android/src/main/java/com/mrousavy/mmkv/MmkvPlatformContextModule.java +17 -0
- package/cpp/Logger.h +35 -0
- package/cpp/MMKVManagedBuffer.h +32 -0
- package/{android/src/main/cpp → cpp}/MmkvHostObject.cpp +126 -63
- package/{android/src/main/cpp → cpp}/MmkvHostObject.h +9 -3
- package/cpp/NativeMmkvModule.cpp +46 -0
- package/cpp/NativeMmkvModule.h +37 -0
- package/ios/AppleLogger.mm +16 -0
- package/ios/MmkvOnLoad.mm +25 -0
- package/ios/MmkvPlatformContext.h +19 -0
- package/ios/MmkvPlatformContextModule.mm +37 -0
- package/lib/commonjs/LazyTurboModule.js +49 -0
- package/lib/commonjs/LazyTurboModule.js.map +1 -0
- package/lib/commonjs/MMKV.js +28 -4
- package/lib/commonjs/MMKV.js.map +1 -1
- package/lib/commonjs/NativeMmkv.js +35 -0
- package/lib/commonjs/NativeMmkv.js.map +1 -0
- package/lib/commonjs/NativeMmkvPlatformContext.js +13 -0
- package/lib/commonjs/NativeMmkvPlatformContext.js.map +1 -0
- package/lib/commonjs/PlatformChecker.js.map +1 -1
- package/lib/commonjs/Types.js +2 -0
- package/lib/commonjs/Types.js.map +1 -0
- package/lib/commonjs/createMMKV.js +6 -43
- package/lib/commonjs/createMMKV.js.map +1 -1
- package/lib/commonjs/createMMKV.mock.js +5 -1
- package/lib/commonjs/createMMKV.mock.js.map +1 -1
- package/lib/commonjs/createMMKV.web.js +8 -4
- package/lib/commonjs/createMMKV.web.js.map +1 -1
- package/lib/commonjs/createTextEncoder.js.map +1 -1
- package/lib/commonjs/hooks.js +11 -10
- package/lib/commonjs/hooks.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/LazyTurboModule.js +43 -0
- package/lib/module/LazyTurboModule.js.map +1 -0
- package/lib/module/MMKV.js +16 -4
- package/lib/module/MMKV.js.map +1 -1
- package/lib/module/NativeMmkv.js +32 -0
- package/lib/module/NativeMmkv.js.map +1 -0
- package/lib/module/NativeMmkvPlatformContext.js +7 -0
- package/lib/module/NativeMmkvPlatformContext.js.map +1 -0
- package/lib/module/PlatformChecker.js.map +1 -1
- package/lib/module/Types.js +2 -0
- package/lib/module/Types.js.map +1 -0
- package/lib/module/createMMKV.js +6 -43
- package/lib/module/createMMKV.js.map +1 -1
- package/lib/module/createMMKV.mock.js +5 -1
- package/lib/module/createMMKV.mock.js.map +1 -1
- package/lib/module/createMMKV.web.js +6 -4
- package/lib/module/createMMKV.web.js.map +1 -1
- package/lib/module/createTextEncoder.js.map +1 -1
- package/lib/module/hooks.js +7 -2
- package/lib/module/hooks.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/LazyTurboModule.d.ts +6 -0
- package/lib/typescript/src/LazyTurboModule.d.ts.map +1 -0
- package/lib/typescript/src/MMKV.d.ts +35 -0
- package/lib/typescript/src/MMKV.d.ts.map +1 -0
- package/lib/typescript/src/NativeMmkv.d.ts +83 -0
- package/lib/typescript/src/NativeMmkv.d.ts.map +1 -0
- package/lib/typescript/src/NativeMmkvPlatformContext.d.ts +9 -0
- package/lib/typescript/src/NativeMmkvPlatformContext.d.ts.map +1 -0
- package/lib/typescript/src/PlatformChecker.d.ts.map +1 -0
- package/lib/typescript/src/Types.d.ts +86 -0
- package/lib/typescript/src/Types.d.ts.map +1 -0
- package/lib/typescript/src/__tests__/hooks.test.d.ts +2 -0
- package/lib/typescript/src/__tests__/hooks.test.d.ts.map +1 -0
- package/lib/typescript/src/createMMKV.d.ts +4 -0
- package/lib/typescript/src/createMMKV.d.ts.map +1 -0
- package/lib/typescript/src/createMMKV.mock.d.ts +3 -0
- package/lib/typescript/src/createMMKV.mock.d.ts.map +1 -0
- package/lib/typescript/src/createMMKV.web.d.ts +4 -0
- package/lib/typescript/src/createMMKV.web.d.ts.map +1 -0
- package/lib/typescript/src/createTextEncoder.d.ts.map +1 -0
- package/lib/typescript/{hooks.d.ts → src/hooks.d.ts} +7 -4
- package/lib/typescript/src/hooks.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/package.json +52 -40
- package/react-native-mmkv.podspec +17 -18
- package/react-native.config.js +20 -0
- package/src/LazyTurboModule.ts +62 -0
- package/src/MMKV.ts +19 -132
- package/src/NativeMmkv.ts +105 -0
- package/src/NativeMmkvPlatformContext.ts +14 -0
- package/src/Types.ts +89 -0
- package/src/__tests__/hooks.test.tsx +89 -0
- package/src/createMMKV.mock.ts +7 -3
- package/src/createMMKV.ts +10 -65
- package/src/createMMKV.web.ts +7 -2
- package/src/hooks.ts +17 -11
- package/android/src/main/java/com/reactnativemmkv/MmkvModule.java +0 -49
- package/android/src/main/java/com/reactnativemmkv/MmkvPackage.java +0 -26
- package/cpp/TypedArray.cpp +0 -322
- package/cpp/TypedArray.h +0 -153
- package/ios/JSIUtils.h +0 -38
- package/ios/JSIUtils.mm +0 -167
- package/ios/Mmkv.xcodeproj/project.pbxproj +0 -291
- package/ios/MmkvHostObject.h +0 -27
- package/ios/MmkvHostObject.mm +0 -295
- package/ios/MmkvModule.h +0 -5
- package/ios/MmkvModule.mm +0 -101
- package/lib/typescript/MMKV.d.ts +0 -142
- package/lib/typescript/MMKV.d.ts.map +0 -1
- package/lib/typescript/PlatformChecker.d.ts.map +0 -1
- package/lib/typescript/createMMKV.d.ts +0 -7
- package/lib/typescript/createMMKV.d.ts.map +0 -1
- package/lib/typescript/createMMKV.mock.d.ts +0 -3
- package/lib/typescript/createMMKV.mock.d.ts.map +0 -1
- package/lib/typescript/createMMKV.web.d.ts +0 -3
- package/lib/typescript/createMMKV.web.d.ts.map +0 -1
- package/lib/typescript/createTextEncoder.d.ts.map +0 -1
- package/lib/typescript/hooks.d.ts.map +0 -1
- package/lib/typescript/index.d.ts.map +0 -1
- /package/lib/typescript/{PlatformChecker.d.ts → src/PlatformChecker.d.ts} +0 -0
- /package/lib/typescript/{createTextEncoder.d.ts → src/createTextEncoder.d.ts} +0 -0
- /package/lib/typescript/{index.d.ts → src/index.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-mmkv",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-beta.2",
|
|
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",
|
|
7
|
-
"types": "lib/typescript/index.d.ts",
|
|
8
|
-
"react-native": "
|
|
7
|
+
"types": "lib/typescript/src/index.d.ts",
|
|
8
|
+
"react-native": "src/index",
|
|
9
9
|
"source": "src/index",
|
|
10
10
|
"files": [
|
|
11
|
+
"cpp/**/*.h",
|
|
12
|
+
"cpp/**/*.cpp",
|
|
13
|
+
"MMKV/Core",
|
|
11
14
|
"android/src",
|
|
12
15
|
"android/build.gradle",
|
|
13
|
-
"android/gradle.properties",
|
|
14
16
|
"android/CMakeLists.txt",
|
|
15
|
-
"cpp",
|
|
16
|
-
"
|
|
17
|
+
"android/cpp-adapter.cpp",
|
|
18
|
+
"android/gradle.properties",
|
|
17
19
|
"lib/commonjs",
|
|
18
20
|
"lib/module",
|
|
19
21
|
"lib/typescript",
|
|
@@ -21,9 +23,9 @@
|
|
|
21
23
|
"ios/**/*.m",
|
|
22
24
|
"ios/**/*.mm",
|
|
23
25
|
"ios/**/*.cpp",
|
|
24
|
-
"ios/Mmkv.xcodeproj/project.pbxproj",
|
|
25
26
|
"src",
|
|
26
27
|
"react-native-mmkv.podspec",
|
|
28
|
+
"react-native.config.js",
|
|
27
29
|
"README.md",
|
|
28
30
|
"img/banner-light.png",
|
|
29
31
|
"img/banner-dark.png"
|
|
@@ -34,21 +36,32 @@
|
|
|
34
36
|
"lint-ci": "yarn lint -f ./node_modules/@firmnav/eslint-github-actions-formatter/dist/formatter.js",
|
|
35
37
|
"lint-cpp": "scripts/clang-format.sh",
|
|
36
38
|
"test": "jest",
|
|
39
|
+
"typecheck": "tsc --noEmit",
|
|
40
|
+
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
|
|
37
41
|
"prepare": "git submodule update --init --recursive && bob build",
|
|
38
42
|
"prepack": "bob build",
|
|
39
43
|
"update-submodule": "git submodule update --remote --merge",
|
|
40
|
-
"release": "release-it",
|
|
41
|
-
"example": "yarn --cwd example",
|
|
42
44
|
"pods": "cd example && yarn pods",
|
|
43
|
-
"
|
|
45
|
+
"release": "release-it",
|
|
46
|
+
"codegen": "npx react-native codegen"
|
|
44
47
|
},
|
|
45
48
|
"keywords": [
|
|
46
49
|
"react-native",
|
|
47
50
|
"ios",
|
|
48
|
-
"android"
|
|
51
|
+
"android",
|
|
52
|
+
"mmkv",
|
|
53
|
+
"storage",
|
|
54
|
+
"key",
|
|
55
|
+
"value",
|
|
56
|
+
"fast",
|
|
57
|
+
"turbo",
|
|
58
|
+
"async"
|
|
49
59
|
],
|
|
50
|
-
"repository":
|
|
51
|
-
|
|
60
|
+
"repository": {
|
|
61
|
+
"type": "git",
|
|
62
|
+
"url": "git+https://github.com/mrousavy/react-native-mmkv.git"
|
|
63
|
+
},
|
|
64
|
+
"author": "Marc Rousavy <me@mrousavy.com> (https://github.com/mrousavy)",
|
|
52
65
|
"license": "(MIT AND BSD-3-Clause)",
|
|
53
66
|
"bugs": {
|
|
54
67
|
"url": "https://github.com/mrousavy/react-native-mmkv/issues"
|
|
@@ -58,33 +71,34 @@
|
|
|
58
71
|
"registry": "https://registry.npmjs.org/"
|
|
59
72
|
},
|
|
60
73
|
"devDependencies": {
|
|
74
|
+
"@firmnav/eslint-github-actions-formatter": "^1.0.1",
|
|
61
75
|
"@jamesacarr/eslint-formatter-github-actions": "^0.2.0",
|
|
62
|
-
"@react-native-community/
|
|
63
|
-
"@react-native
|
|
76
|
+
"@react-native-community/cli-types": "^13.6.6",
|
|
77
|
+
"@react-native/eslint-config": "^0.74.81",
|
|
64
78
|
"@release-it/conventional-changelog": "^8.0.1",
|
|
65
79
|
"@testing-library/react-native": "^12.4.3",
|
|
66
|
-
"@
|
|
67
|
-
"@types/
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"eslint": "^8.56.0",
|
|
73
|
-
"eslint-plugin-ft-flow": "^3.0.4",
|
|
74
|
-
"eslint-plugin-jest": "^27.8.0",
|
|
80
|
+
"@types/jest": "^29.5.5",
|
|
81
|
+
"@types/react": "^18.3.1",
|
|
82
|
+
"del-cli": "^5.1.0",
|
|
83
|
+
"eslint": "^8.51.0",
|
|
84
|
+
"eslint-config-prettier": "^9.0.0",
|
|
85
|
+
"eslint-plugin-prettier": "^5.0.1",
|
|
75
86
|
"jest": "^29.7.0",
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"react": "
|
|
79
|
-
"react-native": "^0.
|
|
80
|
-
"react-
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
|
|
87
|
+
"prettier": "^3.0.3",
|
|
88
|
+
"react": "18.3.1",
|
|
89
|
+
"react-native": "0.74.0",
|
|
90
|
+
"react-native-builder-bob": "^0.23.2",
|
|
91
|
+
"react-test-renderer": "18.3.1",
|
|
92
|
+
"release-it": "^17.2.1",
|
|
93
|
+
"typescript": "^5.4.5"
|
|
94
|
+
},
|
|
95
|
+
"resolutions": {
|
|
96
|
+
"@types/react": "^18.2.44",
|
|
97
|
+
"@react-native-community/cli": "^14.0.0-alpha.2"
|
|
84
98
|
},
|
|
85
99
|
"peerDependencies": {
|
|
86
100
|
"react": "*",
|
|
87
|
-
"react-native": "
|
|
101
|
+
"react-native": "*"
|
|
88
102
|
},
|
|
89
103
|
"jest": {
|
|
90
104
|
"preset": "react-native",
|
|
@@ -137,12 +151,9 @@
|
|
|
137
151
|
"eslintConfig": {
|
|
138
152
|
"root": true,
|
|
139
153
|
"extends": [
|
|
140
|
-
"@react-native
|
|
154
|
+
"@react-native",
|
|
141
155
|
"prettier"
|
|
142
156
|
],
|
|
143
|
-
"plugins": [
|
|
144
|
-
"jest"
|
|
145
|
-
],
|
|
146
157
|
"rules": {
|
|
147
158
|
"prettier/prettier": [
|
|
148
159
|
"error",
|
|
@@ -182,8 +193,9 @@
|
|
|
182
193
|
]
|
|
183
194
|
},
|
|
184
195
|
"codegenConfig": {
|
|
185
|
-
"name": "
|
|
196
|
+
"name": "RNMmkvSpec",
|
|
186
197
|
"type": "modules",
|
|
187
|
-
"jsSrcsDir": "
|
|
188
|
-
}
|
|
198
|
+
"jsSrcsDir": "src"
|
|
199
|
+
},
|
|
200
|
+
"packageManager": "yarn@1.22.19+sha1.4ba7fc5c6e704fce2066ecbfb0b0d8976fe62447"
|
|
189
201
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require "json"
|
|
2
2
|
|
|
3
3
|
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
|
|
4
5
|
|
|
5
6
|
Pod::Spec.new do |s|
|
|
6
7
|
s.name = "react-native-mmkv"
|
|
@@ -10,27 +11,25 @@ Pod::Spec.new do |s|
|
|
|
10
11
|
s.license = package["license"]
|
|
11
12
|
s.authors = package["author"]
|
|
12
13
|
|
|
13
|
-
s.platforms = { :ios =>
|
|
14
|
+
s.platforms = { :ios => min_ios_version_supported }
|
|
14
15
|
s.source = { :git => "https://github.com/mrousavy/react-native-mmkv.git", :tag => "#{s.version}" }
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
s.pod_target_xcconfig = {
|
|
18
|
+
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
|
19
|
+
"CLANG_CXX_LIBRARY" => "libc++",
|
|
20
|
+
"CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF" => "NO",
|
|
21
|
+
# FORCE_POSIX ensures we are using C++ types instead of Objective-C types for MMKV.
|
|
22
|
+
"GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) FORCE_POSIX",
|
|
23
|
+
}
|
|
24
|
+
s.compiler_flags = '-x objective-c++'
|
|
25
|
+
|
|
18
26
|
s.source_files = [
|
|
19
|
-
|
|
20
|
-
"ios
|
|
21
|
-
"cpp/**/*.{
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
# Otherwise there will be a nameclash, since CocoaPods flattens out any header directories
|
|
25
|
-
# See https://github.com/firebase/firebase-ios-sdk/issues/4035 for more details.
|
|
26
|
-
s.preserve_paths = [
|
|
27
|
-
'ios/**/*.h'
|
|
27
|
+
# react-native-mmkv
|
|
28
|
+
"ios/**/*.{h,m,mm}",
|
|
29
|
+
"cpp/**/*.{hpp,cpp,c,h}",
|
|
30
|
+
# MMKV/Core
|
|
31
|
+
"MMKV/Core/**/*.{h,cpp,hpp,S}",
|
|
28
32
|
]
|
|
29
33
|
|
|
30
|
-
s
|
|
31
|
-
if respond_to?(:install_modules_dependencies, true)
|
|
32
|
-
install_modules_dependencies(s)
|
|
33
|
-
else
|
|
34
|
-
s.dependency "React-Core"
|
|
35
|
-
end
|
|
34
|
+
install_modules_dependencies(s)
|
|
36
35
|
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// https://github.com/react-native-community/cli/blob/main/docs/dependencies.md
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
dependency: {
|
|
5
|
+
platforms: {
|
|
6
|
+
/**
|
|
7
|
+
* @type {import('@react-native-community/cli-types').IOSDependencyParams}
|
|
8
|
+
*/
|
|
9
|
+
ios: {},
|
|
10
|
+
/**
|
|
11
|
+
* @type {import('@react-native-community/cli-types').AndroidDependencyParams}
|
|
12
|
+
*/
|
|
13
|
+
android: {
|
|
14
|
+
cxxModuleCMakeListsModuleName: 'react-native-mmkv',
|
|
15
|
+
cxxModuleCMakeListsPath: `${__dirname}/android/CMakeLists.txt`,
|
|
16
|
+
cxxModuleHeaderName: 'NativeMmkvModule',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { NativeModules, Platform, TurboModule } from 'react-native';
|
|
2
|
+
|
|
3
|
+
interface ModuleHolder<T> {
|
|
4
|
+
module: T | null;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Lazily get a TurboModule by wrapping it in a Proxy.
|
|
9
|
+
*/
|
|
10
|
+
export function getLazyTurboModule<T extends TurboModule>(
|
|
11
|
+
initializeTurboModule: () => T | null
|
|
12
|
+
): T {
|
|
13
|
+
const proxy = new Proxy<ModuleHolder<T>>(
|
|
14
|
+
{
|
|
15
|
+
module: null,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
get: (target, property) => {
|
|
19
|
+
if (target.module == null) {
|
|
20
|
+
// Target is null, let's initialize it!
|
|
21
|
+
target.module = initializeTurboModule();
|
|
22
|
+
|
|
23
|
+
if (target.module == null) {
|
|
24
|
+
// TurboModule not found, something went wrong!
|
|
25
|
+
let message =
|
|
26
|
+
'Failed to create a new MMKV instance: The native MMKV Module could not be found.';
|
|
27
|
+
message +=
|
|
28
|
+
'\n* Make sure react-native-mmkv is correctly autolinked (run `npx react-native config` to verify)';
|
|
29
|
+
if (Platform.OS === 'ios' || Platform.OS === 'macos') {
|
|
30
|
+
message +=
|
|
31
|
+
'\n* Make sure you ran `pod install` in the ios/ directory.';
|
|
32
|
+
}
|
|
33
|
+
if (Platform.OS === 'android') {
|
|
34
|
+
message += '\n* Make sure gradle is synced.';
|
|
35
|
+
}
|
|
36
|
+
// check if Expo
|
|
37
|
+
const ExpoConstants =
|
|
38
|
+
NativeModules.NativeUnimoduleProxy?.modulesConstants
|
|
39
|
+
?.ExponentConstants;
|
|
40
|
+
if (ExpoConstants != null) {
|
|
41
|
+
if (ExpoConstants.appOwnership === 'expo') {
|
|
42
|
+
// We're running Expo Go
|
|
43
|
+
throw new Error(
|
|
44
|
+
'react-native-mmkv is not supported in Expo Go! Use EAS (`expo prebuild`) or eject to a bare workflow instead.'
|
|
45
|
+
);
|
|
46
|
+
} else {
|
|
47
|
+
// We're running Expo bare / standalone
|
|
48
|
+
message += '\n* Make sure you ran `expo prebuild`.';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
message += '\n* Make sure you rebuilt the app.';
|
|
53
|
+
throw new Error(message);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return target.module[property as keyof T];
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
return proxy as unknown as T;
|
|
62
|
+
}
|
package/src/MMKV.ts
CHANGED
|
@@ -1,135 +1,10 @@
|
|
|
1
|
+
import { AppState } from 'react-native';
|
|
1
2
|
import { createMMKV } from './createMMKV';
|
|
2
3
|
import { createMockMMKV } from './createMMKV.mock';
|
|
3
4
|
import { isJest } from './PlatformChecker';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Used for configuration of a single MMKV instance.
|
|
11
|
-
*/
|
|
12
|
-
export interface MMKVConfiguration {
|
|
13
|
-
/**
|
|
14
|
-
* The MMKV instance's ID. If you want to use multiple instances, make sure to use different IDs!
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```ts
|
|
18
|
-
* const userStorage = new MMKV({ id: `user-${userId}-storage` })
|
|
19
|
-
* const globalStorage = new MMKV({ id: 'global-app-storage' })
|
|
20
|
-
* ```
|
|
21
|
-
*
|
|
22
|
-
* @default 'mmkv.default'
|
|
23
|
-
*/
|
|
24
|
-
id: string;
|
|
25
|
-
/**
|
|
26
|
-
* The MMKV instance's root path. By default, MMKV stores file inside `$(Documents)/mmkv/`. You can customize MMKV's root directory on MMKV initialization:
|
|
27
|
-
|
|
28
|
-
* @example
|
|
29
|
-
* ```ts
|
|
30
|
-
* const temporaryStorage = new MMKV({ path: '/tmp/' })
|
|
31
|
-
* ```
|
|
32
|
-
*
|
|
33
|
-
* _Notice_: On iOS you can set the AppGroup bundle property to share the same storage between your app and its extensions.
|
|
34
|
-
* In this case `path` property will be ignored.
|
|
35
|
-
* See more on MMKV configuration [here](https://github.com/Tencent/MMKV/wiki/iOS_tutorial#configuration).
|
|
36
|
-
*/
|
|
37
|
-
path?: string;
|
|
38
|
-
/**
|
|
39
|
-
* 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.
|
|
40
|
-
*
|
|
41
|
-
* Encryption keys can have a maximum length of 16 bytes.
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* ```ts
|
|
45
|
-
* const secureStorage = new MMKV({ encryptionKey: 'my-encryption-key!' })
|
|
46
|
-
* ```
|
|
47
|
-
*/
|
|
48
|
-
encryptionKey?: string;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Represents a single MMKV instance.
|
|
53
|
-
*/
|
|
54
|
-
interface MMKVInterface {
|
|
55
|
-
/**
|
|
56
|
-
* Set a value for the given `key`.
|
|
57
|
-
*/
|
|
58
|
-
set: (key: string, value: boolean | string | number | Uint8Array) => void;
|
|
59
|
-
/**
|
|
60
|
-
* Get the boolean value for the given `key`, or `undefined` if it does not exist.
|
|
61
|
-
*
|
|
62
|
-
* @default undefined
|
|
63
|
-
*/
|
|
64
|
-
getBoolean: (key: string) => boolean | undefined;
|
|
65
|
-
/**
|
|
66
|
-
* Get the string value for the given `key`, or `undefined` if it does not exist.
|
|
67
|
-
*
|
|
68
|
-
* @default undefined
|
|
69
|
-
*/
|
|
70
|
-
getString: (key: string) => string | undefined;
|
|
71
|
-
/**
|
|
72
|
-
* Get the number value for the given `key`, or `undefined` if it does not exist.
|
|
73
|
-
*
|
|
74
|
-
* @default undefined
|
|
75
|
-
*/
|
|
76
|
-
getNumber: (key: string) => number | undefined;
|
|
77
|
-
/**
|
|
78
|
-
* Get a raw buffer of unsigned 8-bit (0-255) data.
|
|
79
|
-
*
|
|
80
|
-
* @default undefined
|
|
81
|
-
*/
|
|
82
|
-
getBuffer: (key: string) => Uint8Array | undefined;
|
|
83
|
-
/**
|
|
84
|
-
* Checks whether the given `key` is being stored in this MMKV instance.
|
|
85
|
-
*/
|
|
86
|
-
contains: (key: string) => boolean;
|
|
87
|
-
/**
|
|
88
|
-
* Delete the given `key`.
|
|
89
|
-
*/
|
|
90
|
-
delete: (key: string) => void;
|
|
91
|
-
/**
|
|
92
|
-
* Get all keys.
|
|
93
|
-
*
|
|
94
|
-
* @default []
|
|
95
|
-
*/
|
|
96
|
-
getAllKeys: () => string[];
|
|
97
|
-
/**
|
|
98
|
-
* Delete all keys.
|
|
99
|
-
*/
|
|
100
|
-
clearAll: () => void;
|
|
101
|
-
/**
|
|
102
|
-
* Sets (or updates) the encryption-key to encrypt all data in this MMKV instance with.
|
|
103
|
-
*
|
|
104
|
-
* To remove encryption, pass `undefined` as a key.
|
|
105
|
-
*
|
|
106
|
-
* Encryption keys can have a maximum length of 16 bytes.
|
|
107
|
-
*/
|
|
108
|
-
recrypt: (key: string | undefined) => void;
|
|
109
|
-
/**
|
|
110
|
-
* Adds a value changed listener. The Listener will be called whenever any value
|
|
111
|
-
* in this storage instance changes (set or delete).
|
|
112
|
-
*
|
|
113
|
-
* To unsubscribe from value changes, call `remove()` on the Listener.
|
|
114
|
-
*/
|
|
115
|
-
addOnValueChangedListener: (
|
|
116
|
-
onValueChanged: (key: string) => void
|
|
117
|
-
) => Listener;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export type NativeMMKV = Pick<
|
|
121
|
-
MMKVInterface,
|
|
122
|
-
| 'clearAll'
|
|
123
|
-
| 'contains'
|
|
124
|
-
| 'delete'
|
|
125
|
-
| 'getAllKeys'
|
|
126
|
-
| 'getBoolean'
|
|
127
|
-
| 'getNumber'
|
|
128
|
-
| 'getString'
|
|
129
|
-
| 'getBuffer'
|
|
130
|
-
| 'set'
|
|
131
|
-
| 'recrypt'
|
|
132
|
-
>;
|
|
5
|
+
import { Configuration } from './NativeMmkv';
|
|
6
|
+
import { Listener, MMKVInterface, NativeMMKV } from './Types';
|
|
7
|
+
export { Configuration, Mode } from './NativeMmkv';
|
|
133
8
|
|
|
134
9
|
const onValueChangedListeners = new Map<string, ((key: string) => void)[]>();
|
|
135
10
|
|
|
@@ -145,12 +20,17 @@ export class MMKV implements MMKVInterface {
|
|
|
145
20
|
* Creates a new MMKV instance with the given Configuration.
|
|
146
21
|
* If no custom `id` is supplied, `'mmkv.default'` will be used.
|
|
147
22
|
*/
|
|
148
|
-
constructor(configuration:
|
|
23
|
+
constructor(configuration: Configuration = { id: 'mmkv.default' }) {
|
|
149
24
|
this.id = configuration.id;
|
|
150
25
|
this.nativeInstance = isJest()
|
|
151
26
|
? createMockMMKV()
|
|
152
27
|
: createMMKV(configuration);
|
|
153
28
|
this.functionCache = {};
|
|
29
|
+
|
|
30
|
+
AppState.addEventListener('memoryWarning', () => {
|
|
31
|
+
// when we have a memory warning, delete unused keys by trimming MMKV
|
|
32
|
+
this.trim();
|
|
33
|
+
});
|
|
154
34
|
}
|
|
155
35
|
|
|
156
36
|
private get onValueChangedListeners() {
|
|
@@ -179,7 +59,10 @@ export class MMKV implements MMKVInterface {
|
|
|
179
59
|
}
|
|
180
60
|
}
|
|
181
61
|
|
|
182
|
-
|
|
62
|
+
get size(): number {
|
|
63
|
+
return this.nativeInstance.size;
|
|
64
|
+
}
|
|
65
|
+
set(key: string, value: boolean | string | number | ArrayBuffer): void {
|
|
183
66
|
const func = this.getFunctionFromCache('set');
|
|
184
67
|
func(key, value);
|
|
185
68
|
|
|
@@ -197,7 +80,7 @@ export class MMKV implements MMKVInterface {
|
|
|
197
80
|
const func = this.getFunctionFromCache('getNumber');
|
|
198
81
|
return func(key);
|
|
199
82
|
}
|
|
200
|
-
getBuffer(key: string):
|
|
83
|
+
getBuffer(key: string): ArrayBuffer | undefined {
|
|
201
84
|
const func = this.getFunctionFromCache('getBuffer');
|
|
202
85
|
return func(key);
|
|
203
86
|
}
|
|
@@ -227,6 +110,10 @@ export class MMKV implements MMKVInterface {
|
|
|
227
110
|
const func = this.getFunctionFromCache('recrypt');
|
|
228
111
|
return func(key);
|
|
229
112
|
}
|
|
113
|
+
trim(): void {
|
|
114
|
+
const func = this.getFunctionFromCache('trim');
|
|
115
|
+
func();
|
|
116
|
+
}
|
|
230
117
|
|
|
231
118
|
toString(): string {
|
|
232
119
|
return `MMKV (${this.id}): [${this.getAllKeys().join(', ')}]`;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { TurboModule } from 'react-native';
|
|
2
|
+
import { TurboModuleRegistry } from 'react-native';
|
|
3
|
+
import { UnsafeObject } from 'react-native/Libraries/Types/CodegenTypes';
|
|
4
|
+
import { getLazyTurboModule } from './LazyTurboModule';
|
|
5
|
+
import { PlatformContext } from './NativeMmkvPlatformContext';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Configures the mode of the MMKV instance.
|
|
9
|
+
*/
|
|
10
|
+
export enum Mode {
|
|
11
|
+
/**
|
|
12
|
+
* The MMKV instance is only used from a single process (this app).
|
|
13
|
+
*/
|
|
14
|
+
SINGLE_PROCESS,
|
|
15
|
+
/**
|
|
16
|
+
* The MMKV instance may be used from multiple processes, such as app clips, share extensions or background services.
|
|
17
|
+
*/
|
|
18
|
+
MULTI_PROCESS,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Used for configuration of a single MMKV instance.
|
|
23
|
+
*/
|
|
24
|
+
export interface Configuration {
|
|
25
|
+
/**
|
|
26
|
+
* The MMKV instance's ID. If you want to use multiple instances, make sure to use different IDs!
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const userStorage = new MMKV({ id: `user-${userId}-storage` })
|
|
31
|
+
* const globalStorage = new MMKV({ id: 'global-app-storage' })
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @default 'mmkv.default'
|
|
35
|
+
*/
|
|
36
|
+
id: string;
|
|
37
|
+
/**
|
|
38
|
+
* The MMKV instance's root path. By default, MMKV stores file inside `$(Documents)/mmkv/`. You can customize MMKV's root directory on MMKV initialization:
|
|
39
|
+
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* const temporaryStorage = new MMKV({ path: '/tmp/' })
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* _Notice_: On iOS you can set the AppGroup bundle property to share the same storage between your app and its extensions.
|
|
46
|
+
* In this case `path` property will be ignored.
|
|
47
|
+
* See more on MMKV configuration [here](https://github.com/Tencent/MMKV/wiki/iOS_tutorial#configuration).
|
|
48
|
+
*
|
|
49
|
+
* @default undefined
|
|
50
|
+
*/
|
|
51
|
+
path?: string;
|
|
52
|
+
/**
|
|
53
|
+
* 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.
|
|
54
|
+
*
|
|
55
|
+
* Encryption keys can have a maximum length of 16 bytes.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* const secureStorage = new MMKV({ encryptionKey: 'my-encryption-key!' })
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @default undefined
|
|
63
|
+
*/
|
|
64
|
+
encryptionKey?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Configure the processing mode for MMKV.
|
|
67
|
+
* - `SINGLE_PROCESS`: The MMKV instance is only used from a single process (this app).
|
|
68
|
+
* - `MULTI_PROCESS`: The MMKV instance may be used from multiple processes, such as app clips, share extensions or background services.
|
|
69
|
+
*
|
|
70
|
+
* @default SINGLE_PROCESS
|
|
71
|
+
*/
|
|
72
|
+
mode?: Mode;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface Spec extends TurboModule {
|
|
76
|
+
/**
|
|
77
|
+
* Initialize MMKV with the given base storage directory.
|
|
78
|
+
* This should be the documents directory by default.
|
|
79
|
+
*/
|
|
80
|
+
initialize(basePath: string): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Create a new instance of MMKV.
|
|
83
|
+
* The returned {@linkcode UnsafeObject} is a `jsi::HostObject`.
|
|
84
|
+
*/
|
|
85
|
+
createMMKV(configuration: Configuration): UnsafeObject;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let basePath: string | null = null;
|
|
89
|
+
|
|
90
|
+
function getNativeModule(): Spec | null {
|
|
91
|
+
if (basePath == null) {
|
|
92
|
+
// use default base path from the Platform (iOS/Android)
|
|
93
|
+
basePath = PlatformContext.getBaseDirectory();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const module = TurboModuleRegistry.get<Spec>('MmkvCxx');
|
|
97
|
+
|
|
98
|
+
if (module != null) {
|
|
99
|
+
// initialize MMKV
|
|
100
|
+
module.initialize(basePath);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return module;
|
|
104
|
+
}
|
|
105
|
+
export const MMKVTurboModule = getLazyTurboModule(getNativeModule);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { TurboModule, TurboModuleRegistry } from 'react-native';
|
|
2
|
+
import { getLazyTurboModule } from './LazyTurboModule';
|
|
3
|
+
|
|
4
|
+
export interface Spec extends TurboModule {
|
|
5
|
+
/**
|
|
6
|
+
* Gets the base directory of the documents storage
|
|
7
|
+
*/
|
|
8
|
+
getBaseDirectory(): string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function getModule(): Spec | null {
|
|
12
|
+
return TurboModuleRegistry.get<Spec>('MmkvPlatformContext');
|
|
13
|
+
}
|
|
14
|
+
export const PlatformContext = getLazyTurboModule(getModule);
|