react-native-mmkv 1.5.4 → 1.6.3
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/README.md +6 -1
- package/android/CMakeLists.txt +21 -7
- package/android/build.gradle +70 -73
- package/lib/commonjs/MMKV.js +3 -5
- package/lib/commonjs/MMKV.js.map +1 -1
- package/lib/commonjs/createMMKV.js +18 -0
- package/lib/commonjs/createMMKV.js.map +1 -0
- package/lib/commonjs/createMMKV.web.js +67 -0
- package/lib/commonjs/createMMKV.web.js.map +1 -0
- package/lib/module/MMKV.js +2 -5
- package/lib/module/MMKV.js.map +1 -1
- package/lib/module/createMMKV.js +9 -0
- package/lib/module/createMMKV.js.map +1 -0
- package/lib/module/createMMKV.web.js +57 -0
- package/lib/module/createMMKV.web.js.map +1 -0
- package/lib/typescript/MMKV.d.ts +1 -3
- package/lib/typescript/createMMKV.d.ts +5 -0
- package/lib/typescript/createMMKV.web.d.ts +2 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -32,11 +32,12 @@
|
|
|
32
32
|
* **High performance** because everything is **written in C++** (even the JS functions have C++ bodies!)
|
|
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
|
+
* **iOS**, **Android** and **Web** support
|
|
35
36
|
|
|
36
37
|
## Sponsors
|
|
37
38
|
|
|
38
39
|
<div align="right">
|
|
39
|
-
<a href="https://getstream.io/chat/react-native-chat/tutorial/?utm_source=
|
|
40
|
+
<a href="https://getstream.io/chat/react-native-chat/tutorial/?utm_source=Github&utm_medium=Github_Repo_Content_Ad&utm_content=Developer&utm_campaign=Github_Jan2022_ReactNative&utm_term=react-native-mmkv">
|
|
40
41
|
<img align="right" src="https://theme.zdassets.com/theme_assets/9442057/efc3820e436f9150bc8cf34267fff4df052a1f9c.png" height="40" />
|
|
41
42
|
</a>
|
|
42
43
|
</div>
|
|
@@ -72,6 +73,10 @@ cd ios && pod install
|
|
|
72
73
|
|
|
73
74
|
To correctly initialize MMKV on Android, please follow the [Installation guide](./INSTALL.md).
|
|
74
75
|
|
|
76
|
+
### Expo
|
|
77
|
+
|
|
78
|
+
See this comment for more information: [mrousavy/react-native-mmkv#157 (comment)](https://github.com/mrousavy/react-native-mmkv/issues/157#issuecomment-960647481).
|
|
79
|
+
|
|
75
80
|
## Usage
|
|
76
81
|
|
|
77
82
|
### Create a new instance
|
package/android/CMakeLists.txt
CHANGED
|
@@ -12,10 +12,18 @@ include_directories(
|
|
|
12
12
|
"${NODE_MODULES_DIR}/react-native/ReactCommon/jsi"
|
|
13
13
|
)
|
|
14
14
|
|
|
15
|
+
if(${REACT_NATIVE_VERSION} LESS 66)
|
|
16
|
+
set (
|
|
17
|
+
INCLUDE_JSI_CPP
|
|
18
|
+
"${NODE_MODULES_DIR}/react-native/ReactCommon/jsi/jsi/jsi.cpp"
|
|
19
|
+
)
|
|
20
|
+
endif()
|
|
21
|
+
|
|
15
22
|
add_library(reactnativemmkv # <-- Library name
|
|
16
23
|
SHARED
|
|
17
24
|
src/main/cpp/cpp-adapter.cpp
|
|
18
25
|
src/main/cpp/MmkvHostObject.cpp
|
|
26
|
+
${INCLUDE_JSI_CPP} # only on older RN versions
|
|
19
27
|
)
|
|
20
28
|
|
|
21
29
|
set_target_properties(
|
|
@@ -25,24 +33,30 @@ set_target_properties(
|
|
|
25
33
|
POSITION_INDEPENDENT_CODE ON
|
|
26
34
|
)
|
|
27
35
|
|
|
28
|
-
file (GLOB LIBRN_DIR "${
|
|
36
|
+
file (GLOB LIBRN_DIR "${PREBUILT_DIR}/${ANDROID_ABI}")
|
|
29
37
|
|
|
30
38
|
find_library(
|
|
31
39
|
log-lib
|
|
32
40
|
log
|
|
33
41
|
)
|
|
34
|
-
find_library(
|
|
35
|
-
JSI_LIB
|
|
36
|
-
jsi
|
|
37
|
-
PATHS ${LIBRN_DIR}
|
|
38
|
-
NO_CMAKE_FIND_ROOT_PATH
|
|
39
|
-
)
|
|
40
42
|
find_library(
|
|
41
43
|
REACT_NATIVE_JNI_LIB
|
|
42
44
|
reactnativejni
|
|
43
45
|
PATHS ${LIBRN_DIR}
|
|
44
46
|
NO_CMAKE_FIND_ROOT_PATH
|
|
45
47
|
)
|
|
48
|
+
if(${REACT_NATIVE_VERSION} LESS 66)
|
|
49
|
+
# JSI lib didn't exist on RN 0.65 and before. Simply omit it.
|
|
50
|
+
set (JSI_LIB "")
|
|
51
|
+
else()
|
|
52
|
+
# RN 0.66 distributes libjsi.so, can be used instead of compiling jsi.cpp manually.
|
|
53
|
+
find_library(
|
|
54
|
+
JSI_LIB
|
|
55
|
+
jsi
|
|
56
|
+
PATHS ${LIBRN_DIR}
|
|
57
|
+
NO_CMAKE_FIND_ROOT_PATH
|
|
58
|
+
)
|
|
59
|
+
endif()
|
|
46
60
|
|
|
47
61
|
target_link_libraries(
|
|
48
62
|
reactnativemmkv
|
package/android/build.gradle
CHANGED
|
@@ -2,6 +2,24 @@ import groovy.json.JsonSlurper
|
|
|
2
2
|
import org.apache.tools.ant.filters.ReplaceTokens
|
|
3
3
|
import java.nio.file.Paths
|
|
4
4
|
|
|
5
|
+
static def findNodeModules(baseDir) {
|
|
6
|
+
def basePath = baseDir.toPath().normalize()
|
|
7
|
+
// Node's module resolution algorithm searches up to the root directory,
|
|
8
|
+
// after which the base path will be null
|
|
9
|
+
while (basePath) {
|
|
10
|
+
def nodeModulesPath = Paths.get(basePath.toString(), "node_modules")
|
|
11
|
+
def reactNativePath = Paths.get(nodeModulesPath.toString(), "react-native")
|
|
12
|
+
if (nodeModulesPath.toFile().exists() && reactNativePath.toFile().exists()) {
|
|
13
|
+
return nodeModulesPath.toString()
|
|
14
|
+
}
|
|
15
|
+
basePath = basePath.getParent()
|
|
16
|
+
}
|
|
17
|
+
throw new GradleException("MMKV: Failed to find node_modules/ path!")
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
def nodeModules = findNodeModules(projectDir)
|
|
21
|
+
logger.warn("MMKV: node_modules/ found at: ${nodeModules}")
|
|
22
|
+
|
|
5
23
|
buildscript {
|
|
6
24
|
repositories {
|
|
7
25
|
google()
|
|
@@ -28,7 +46,12 @@ def getExtOrIntegerDefault(name) {
|
|
|
28
46
|
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['Mmkv_' + name]).toInteger()
|
|
29
47
|
}
|
|
30
48
|
|
|
31
|
-
def
|
|
49
|
+
def reactNativeArchitectures() {
|
|
50
|
+
def value = project.getProperties().get("reactNativeArchitectures")
|
|
51
|
+
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
def sourceBuild = false
|
|
32
55
|
def defaultDir = null
|
|
33
56
|
def androidSourcesDir = null
|
|
34
57
|
def androidSourcesName = 'React Native sources'
|
|
@@ -36,41 +59,29 @@ def androidSourcesName = 'React Native sources'
|
|
|
36
59
|
if (rootProject.ext.has('reactNativeAndroidRoot')) {
|
|
37
60
|
defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
|
|
38
61
|
androidSourcesDir = defaultDir.parentFile.toString()
|
|
62
|
+
} else if (findProject(':ReactAndroid') != null) {
|
|
63
|
+
sourceBuild = true
|
|
64
|
+
defaultDir = project(':ReactAndroid').projectDir
|
|
65
|
+
androidSourcesDir = defaultDir.parentFile.toString()
|
|
39
66
|
} else {
|
|
40
|
-
defaultDir =
|
|
41
|
-
projectDir,
|
|
42
|
-
'/../../../node_modules/react-native/android'
|
|
43
|
-
)
|
|
67
|
+
defaultDir = file("$nodeModules/react-native/android")
|
|
44
68
|
androidSourcesDir = defaultDir.parentFile.toString()
|
|
45
69
|
}
|
|
46
70
|
|
|
47
|
-
if (defaultDir.exists()) {
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
def parentDir = rootProject.projectDir
|
|
51
|
-
defaultDir = new File(parentDir, '../node_modules/react-native/android')
|
|
52
|
-
|
|
53
|
-
1.upto(5, {
|
|
54
|
-
if (found) return true
|
|
55
|
-
parentDir = parentDir.parentFile
|
|
56
|
-
|
|
57
|
-
androidSourcesDir = new File(
|
|
58
|
-
parentDir,
|
|
59
|
-
'node_modules/react-native'
|
|
71
|
+
if (!defaultDir.exists()) {
|
|
72
|
+
throw new GradleException(
|
|
73
|
+
"${project.name}: React Native android directory (node_modules/react-native/android) does not exist! Resolved node_modules to: ${nodeModules}"
|
|
60
74
|
)
|
|
75
|
+
}
|
|
61
76
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
)
|
|
77
|
+
def prebuiltDir = sourceBuild
|
|
78
|
+
? "$nodeModules/react-native/ReactAndroid/src/main/jni/prebuilt/lib"
|
|
79
|
+
: "$buildDir/react-native-0*/jni"
|
|
66
80
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
}
|
|
81
|
+
|
|
82
|
+
def reactProperties = new Properties()
|
|
83
|
+
file("$nodeModules/react-native/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
|
|
84
|
+
def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME").split("\\.")[1].toInteger()
|
|
74
85
|
|
|
75
86
|
android {
|
|
76
87
|
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
|
|
@@ -85,11 +96,15 @@ android {
|
|
|
85
96
|
externalNativeBuild {
|
|
86
97
|
cmake {
|
|
87
98
|
cppFlags "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID"
|
|
88
|
-
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
|
|
89
99
|
arguments '-DANDROID_STL=c++_shared',
|
|
90
|
-
|
|
100
|
+
"-DREACT_NATIVE_VERSION=${REACT_NATIVE_VERSION}",
|
|
101
|
+
"-DNODE_MODULES_DIR=${nodeModules}",
|
|
102
|
+
"-DPREBUILT_DIR=${prebuiltDir}"
|
|
91
103
|
}
|
|
92
104
|
}
|
|
105
|
+
ndk {
|
|
106
|
+
abiFilters (*reactNativeArchitectures())
|
|
107
|
+
}
|
|
93
108
|
}
|
|
94
109
|
|
|
95
110
|
dexOptions {
|
|
@@ -129,41 +144,9 @@ repositories {
|
|
|
129
144
|
mavenCentral()
|
|
130
145
|
google()
|
|
131
146
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
name androidSourcesName
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
logger.info(":${project.name}:reactNativeAndroidRoot ${defaultDir.canonicalPath}")
|
|
139
|
-
} else {
|
|
140
|
-
def parentDir = rootProject.projectDir
|
|
141
|
-
defaultDir = new File(parentDir, '../node_modules/react-native/android')
|
|
142
|
-
|
|
143
|
-
1.upto(5, {
|
|
144
|
-
if (androidPrebuiltBinaryDir.exists()) {
|
|
145
|
-
maven {
|
|
146
|
-
url androidPrebuiltBinaryDir.toString()
|
|
147
|
-
name androidSourcesName
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
logger.info(":${project.name}:reactNativeAndroidRoot ${androidPrebuiltBinaryDir.canonicalPath}")
|
|
151
|
-
} else if (androidSourcesDir.exists()) {
|
|
152
|
-
maven {
|
|
153
|
-
url androidSourcesDir.toString()
|
|
154
|
-
name androidSourcesName
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
logger.info(":${project.name}:reactNativeAndroidRoot ${androidSourcesDir.canonicalPath}")
|
|
158
|
-
}
|
|
159
|
-
})
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (!found) {
|
|
163
|
-
throw new GradleException(
|
|
164
|
-
"${project.name}: unable to locate React Native android sources. " +
|
|
165
|
-
"Ensure you have you installed React Native as a dependency in your project and try again."
|
|
166
|
-
)
|
|
147
|
+
maven {
|
|
148
|
+
url defaultDir.toString()
|
|
149
|
+
name androidSourcesName
|
|
167
150
|
}
|
|
168
151
|
}
|
|
169
152
|
|
|
@@ -176,8 +159,10 @@ dependencies {
|
|
|
176
159
|
//noinspection GradleDynamicVersion
|
|
177
160
|
extractJNI("com.facebook.fbjni:fbjni:+")
|
|
178
161
|
|
|
179
|
-
|
|
180
|
-
|
|
162
|
+
if (!sourceBuild) {
|
|
163
|
+
def rnAAR = fileTree("${defaultDir.toString()}").matching({ it.include "**/**/*.aar" }).singleFile
|
|
164
|
+
extractJNI(files(rnAAR))
|
|
165
|
+
}
|
|
181
166
|
}
|
|
182
167
|
|
|
183
168
|
// third-party-ndk deps headers
|
|
@@ -346,10 +331,22 @@ task extractJNIFiles {
|
|
|
346
331
|
}
|
|
347
332
|
extractJNIFiles.mustRunAfter extractAARHeaders
|
|
348
333
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
task.
|
|
334
|
+
def nativeBuildDependsOn(dependsOnTask, variant) {
|
|
335
|
+
def buildTasks = tasks.findAll({ task ->
|
|
336
|
+
!task.name.contains("Clean") && (task.name.contains("externalNative") || task.name.contains("CMake")) })
|
|
337
|
+
if (variant != null) {
|
|
338
|
+
buildTasks = buildTasks.findAll({ task -> task.name.contains(variant) })
|
|
339
|
+
}
|
|
340
|
+
buildTasks.forEach { task -> task.dependsOn(dependsOnTask) }
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
afterEvaluate {
|
|
344
|
+
if (sourceBuild) {
|
|
345
|
+
nativeBuildDependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck", "Debug")
|
|
346
|
+
nativeBuildDependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck", "Rel")
|
|
347
|
+
} else {
|
|
348
|
+
nativeBuildDependsOn(extractAARHeaders, null)
|
|
349
|
+
nativeBuildDependsOn(extractJNIFiles, null)
|
|
350
|
+
nativeBuildDependsOn(prepareThirdPartyNdkHeaders, null)
|
|
354
351
|
}
|
|
355
352
|
}
|
package/lib/commonjs/MMKV.js
CHANGED
|
@@ -7,6 +7,8 @@ exports.MMKV = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
9
|
|
|
10
|
+
var _createMMKV = require("./createMMKV");
|
|
11
|
+
|
|
10
12
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
11
13
|
|
|
12
14
|
const onValueChangedListeners = new Map();
|
|
@@ -28,12 +30,8 @@ class MMKV {
|
|
|
28
30
|
|
|
29
31
|
_defineProperty(this, "id", void 0);
|
|
30
32
|
|
|
31
|
-
if (global.mmkvCreateNewInstance == null) {
|
|
32
|
-
throw new Error('Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
33
|
this.id = configuration.id;
|
|
36
|
-
this.nativeInstance =
|
|
34
|
+
this.nativeInstance = (0, _createMMKV.createMMKV)(configuration);
|
|
37
35
|
this.functionCache = {};
|
|
38
36
|
}
|
|
39
37
|
|
package/lib/commonjs/MMKV.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["MMKV.ts"],"names":["onValueChangedListeners","Map","MMKV","constructor","configuration","id","
|
|
1
|
+
{"version":3,"sources":["MMKV.ts"],"names":["onValueChangedListeners","Map","MMKV","constructor","configuration","id","nativeInstance","functionCache","has","set","get","getFunctionFromCache","functionName","onValuesAboutToChange","keys","length","setImmediate","key","listener","value","func","getBoolean","getString","getNumber","contains","delete","getAllKeys","clearAll","addOnValueChangedListener","onValueChanged","push","remove","index","indexOf","splice"],"mappings":"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","sourcesContent":["import { unstable_batchedUpdates } from 'react-native';\nimport { createMMKV } from './createMMKV';\n\ninterface Listener {\n remove: () => void;\n}\n\n/**\n * Used for configuration of a single MMKV instance.\n */\nexport interface MMKVConfiguration {\n /**\n * The MMKV instance's ID. If you want to use multiple instances, make sure to use different IDs!\n *\n * @example\n * ```ts\n * const userStorage = new MMKV({ id: `user-${userId}-storage` })\n * const globalStorage = new MMKV({ id: 'global-app-storage' })\n * ```\n *\n * @default 'mmkv.default'\n */\n id: string;\n /**\n * The MMKV instance's root path. By default, MMKV stores file inside `$(Documents)/mmkv/`. You can customize MMKV's root directory on MMKV initialization:\n *\n * @example\n * ```ts\n * const temporaryStorage = new MMKV({ path: '/tmp/' })\n * ```\n */\n path?: string;\n /**\n * The MMKV instance's encryption/decryption key. By default, MMKV stores all key-values in plain text on file, relying on iOS's sandbox to make sure the file is encrypted. Should you worry about information leaking, you can choose to encrypt MMKV.\n *\n * @example\n * ```ts\n * const secureStorage = new MMKV({ encryptionKey: 'my-encryption-key!' })\n * ```\n */\n encryptionKey?: string;\n}\n\n/**\n * Represents a single MMKV instance.\n */\ninterface MMKVInterface {\n /**\n * Set a value for the given `key`.\n */\n set: (key: string, value: boolean | string | number) => void;\n /**\n * Get a boolean value for the given `key`.\n *\n * @default false\n */\n getBoolean: (key: string) => boolean;\n /**\n * Get a string value for the given `key`.\n *\n * @default undefined\n */\n getString: (key: string) => string | undefined;\n /**\n * Get a number value for the given `key`.\n *\n * @default 0\n */\n getNumber: (key: string) => number;\n /**\n * Checks whether the given `key` is being stored in this MMKV instance.\n */\n contains: (key: string) => boolean;\n /**\n * Delete the given `key`.\n */\n delete: (key: string) => void;\n /**\n * Get all keys.\n *\n * @default []\n */\n getAllKeys: () => string[];\n /**\n * Delete all keys.\n */\n clearAll: () => void;\n /**\n * Adds a value changed listener.\n */\n addOnValueChangedListener: (\n onValueChanged: (key: string) => void\n ) => Listener;\n}\n\nexport type NativeMMKV = Pick<\n MMKVInterface,\n | 'clearAll'\n | 'contains'\n | 'delete'\n | 'getAllKeys'\n | 'getBoolean'\n | 'getNumber'\n | 'getString'\n | 'set'\n>;\n\nconst onValueChangedListeners = new Map<string, ((key: string) => void)[]>();\n\n/**\n * A single MMKV instance.\n */\nexport class MMKV implements MMKVInterface {\n private nativeInstance: NativeMMKV;\n private functionCache: Partial<NativeMMKV>;\n private id: string;\n\n /**\n * Creates a new MMKV instance with the given Configuration.\n * If no custom `id` is supplied, `'default'` will be used.\n */\n constructor(configuration: MMKVConfiguration = { id: 'mmkv.default' }) {\n this.id = configuration.id;\n this.nativeInstance = createMMKV(configuration);\n this.functionCache = {};\n }\n\n private get onValueChangedListeners() {\n if (!onValueChangedListeners.has(this.id)) {\n onValueChangedListeners.set(this.id, []);\n }\n return onValueChangedListeners.get(this.id)!;\n }\n\n private getFunctionFromCache<T extends keyof NativeMMKV>(\n functionName: T\n ): NativeMMKV[T] {\n if (this.functionCache[functionName] == null) {\n this.functionCache[functionName] = this.nativeInstance[functionName];\n }\n return this.functionCache[functionName] as NativeMMKV[T];\n }\n\n private onValuesAboutToChange(keys: string[]) {\n if (this.onValueChangedListeners.length === 0) return;\n\n setImmediate(() => {\n unstable_batchedUpdates(() => {\n for (const key of keys) {\n for (const listener of this.onValueChangedListeners) {\n listener(key);\n }\n }\n });\n });\n }\n\n set(key: string, value: boolean | string | number): void {\n this.onValuesAboutToChange([key]);\n\n const func = this.getFunctionFromCache('set');\n return func(key, value);\n }\n getBoolean(key: string): boolean {\n const func = this.getFunctionFromCache('getBoolean');\n return func(key);\n }\n getString(key: string): string | undefined {\n const func = this.getFunctionFromCache('getString');\n return func(key);\n }\n getNumber(key: string): number {\n const func = this.getFunctionFromCache('getNumber');\n return func(key);\n }\n contains(key: string): boolean {\n const func = this.getFunctionFromCache('contains');\n return func(key);\n }\n delete(key: string): void {\n this.onValuesAboutToChange([key]);\n\n const func = this.getFunctionFromCache('delete');\n return func(key);\n }\n getAllKeys(): string[] {\n const func = this.getFunctionFromCache('getAllKeys');\n return func();\n }\n clearAll(): void {\n const keys = this.getAllKeys();\n this.onValuesAboutToChange(keys);\n\n const func = this.getFunctionFromCache('clearAll');\n return func();\n }\n\n addOnValueChangedListener(onValueChanged: (key: string) => void): Listener {\n this.onValueChangedListeners.push(onValueChanged);\n\n return {\n remove: () => {\n const index = this.onValueChangedListeners.indexOf(onValueChanged);\n if (index !== -1) {\n this.onValueChangedListeners.splice(index, 1);\n }\n },\n };\n }\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createMMKV = void 0;
|
|
7
|
+
|
|
8
|
+
// global func declaration for JSI functions
|
|
9
|
+
const createMMKV = config => {
|
|
10
|
+
if (global.mmkvCreateNewInstance == null) {
|
|
11
|
+
throw new Error('Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return global.mmkvCreateNewInstance(config);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
exports.createMMKV = createMMKV;
|
|
18
|
+
//# sourceMappingURL=createMMKV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["createMMKV.ts"],"names":["createMMKV","config","global","mmkvCreateNewInstance","Error"],"mappings":";;;;;;;AAEA;AAKO,MAAMA,UAAU,GAAIC,MAAD,IAA2C;AACnE,MAAIC,MAAM,CAACC,qBAAP,IAAgC,IAApC,EAA0C;AACxC,UAAM,IAAIC,KAAJ,CACJ,0MADI,CAAN;AAGD;;AAED,SAAOF,MAAM,CAACC,qBAAP,CAA6BF,MAA7B,CAAP;AACD,CARM","sourcesContent":["import type { MMKVConfiguration, NativeMMKV } from 'react-native-mmkv';\n\n// global func declaration for JSI functions\ndeclare global {\n function mmkvCreateNewInstance(configuration: MMKVConfiguration): NativeMMKV;\n}\n\nexport const createMMKV = (config: MMKVConfiguration): NativeMMKV => {\n if (global.mmkvCreateNewInstance == null) {\n throw new Error(\n 'Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!'\n );\n }\n\n return global.mmkvCreateNewInstance(config);\n};\n"]}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createMMKV = void 0;
|
|
7
|
+
|
|
8
|
+
var _window$document;
|
|
9
|
+
|
|
10
|
+
/* global localStorage */
|
|
11
|
+
const canUseDOM = typeof window !== 'undefined' && ((_window$document = window.document) === null || _window$document === void 0 ? void 0 : _window$document.createElement) != null;
|
|
12
|
+
|
|
13
|
+
const createMMKV = config => {
|
|
14
|
+
if (config.id !== 'mmkv.default') {
|
|
15
|
+
throw new Error("MMKV: 'id' is not supported on Web!");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (config.encryptionKey != null) {
|
|
19
|
+
throw new Error("MMKV: 'encryptionKey' is not supported on Web!");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (config.path != null) {
|
|
23
|
+
throw new Error("MMKV: 'path' is not supported on Web!");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const storage = () => {
|
|
27
|
+
var _ref, _global$localStorage, _global, _window;
|
|
28
|
+
|
|
29
|
+
if (!canUseDOM) {
|
|
30
|
+
throw new Error('Tried to access storage on the server. Did you forget to call this in useEffect?');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const domStorage = (_ref = (_global$localStorage = (_global = global) === null || _global === void 0 ? void 0 : _global.localStorage) !== null && _global$localStorage !== void 0 ? _global$localStorage : (_window = window) === null || _window === void 0 ? void 0 : _window.localStorage) !== null && _ref !== void 0 ? _ref : localStorage;
|
|
34
|
+
|
|
35
|
+
if (domStorage == null) {
|
|
36
|
+
throw new Error(`Could not find 'localStorage' instance!`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return domStorage;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
clearAll: () => storage().clear(),
|
|
44
|
+
delete: key => storage().removeItem(key),
|
|
45
|
+
set: (key, value) => storage().setItem(key, value.toString()),
|
|
46
|
+
getString: key => {
|
|
47
|
+
var _storage$getItem;
|
|
48
|
+
|
|
49
|
+
return (_storage$getItem = storage().getItem(key)) !== null && _storage$getItem !== void 0 ? _storage$getItem : undefined;
|
|
50
|
+
},
|
|
51
|
+
getNumber: key => {
|
|
52
|
+
var _storage$getItem2;
|
|
53
|
+
|
|
54
|
+
return Number((_storage$getItem2 = storage().getItem(key)) !== null && _storage$getItem2 !== void 0 ? _storage$getItem2 : 0);
|
|
55
|
+
},
|
|
56
|
+
getBoolean: key => {
|
|
57
|
+
var _storage$getItem3;
|
|
58
|
+
|
|
59
|
+
return Boolean((_storage$getItem3 = storage().getItem(key)) !== null && _storage$getItem3 !== void 0 ? _storage$getItem3 : false);
|
|
60
|
+
},
|
|
61
|
+
getAllKeys: () => Object.keys(storage()),
|
|
62
|
+
contains: key => storage().getItem(key) != null
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
exports.createMMKV = createMMKV;
|
|
67
|
+
//# sourceMappingURL=createMMKV.web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["createMMKV.web.ts"],"names":["canUseDOM","window","document","createElement","createMMKV","config","id","Error","encryptionKey","path","storage","domStorage","global","localStorage","clearAll","clear","delete","key","removeItem","set","value","setItem","toString","getString","getItem","undefined","getNumber","Number","getBoolean","Boolean","getAllKeys","Object","keys","contains"],"mappings":";;;;;;;;;AAAA;AAGA,MAAMA,SAAS,GACb,OAAOC,MAAP,KAAkB,WAAlB,IAAiC,qBAAAA,MAAM,CAACC,QAAP,sEAAiBC,aAAjB,KAAkC,IADrE;;AAGO,MAAMC,UAAU,GAAIC,MAAD,IAA2C;AACnE,MAAIA,MAAM,CAACC,EAAP,KAAc,cAAlB,EAAkC;AAChC,UAAM,IAAIC,KAAJ,CAAU,qCAAV,CAAN;AACD;;AACD,MAAIF,MAAM,CAACG,aAAP,IAAwB,IAA5B,EAAkC;AAChC,UAAM,IAAID,KAAJ,CAAU,gDAAV,CAAN;AACD;;AACD,MAAIF,MAAM,CAACI,IAAP,IAAe,IAAnB,EAAyB;AACvB,UAAM,IAAIF,KAAJ,CAAU,uCAAV,CAAN;AACD;;AAED,QAAMG,OAAO,GAAG,MAAM;AAAA;;AACpB,QAAI,CAACV,SAAL,EAAgB;AACd,YAAM,IAAIO,KAAJ,CACJ,kFADI,CAAN;AAGD;;AACD,UAAMI,UAAU,8CACdC,MADc,4CACd,QAAQC,YADM,kFACUZ,MADV,4CACU,QAAQY,YADlB,uCACkCA,YADlD;;AAEA,QAAIF,UAAU,IAAI,IAAlB,EAAwB;AACtB,YAAM,IAAIJ,KAAJ,CAAW,yCAAX,CAAN;AACD;;AACD,WAAOI,UAAP;AACD,GAZD;;AAcA,SAAO;AACLG,IAAAA,QAAQ,EAAE,MAAMJ,OAAO,GAAGK,KAAV,EADX;AAELC,IAAAA,MAAM,EAAGC,GAAD,IAASP,OAAO,GAAGQ,UAAV,CAAqBD,GAArB,CAFZ;AAGLE,IAAAA,GAAG,EAAE,CAACF,GAAD,EAAMG,KAAN,KAAgBV,OAAO,GAAGW,OAAV,CAAkBJ,GAAlB,EAAuBG,KAAK,CAACE,QAAN,EAAvB,CAHhB;AAILC,IAAAA,SAAS,EAAGN,GAAD;AAAA;;AAAA,iCAASP,OAAO,GAAGc,OAAV,CAAkBP,GAAlB,CAAT,+DAAmCQ,SAAnC;AAAA,KAJN;AAKLC,IAAAA,SAAS,EAAGT,GAAD;AAAA;;AAAA,aAASU,MAAM,sBAACjB,OAAO,GAAGc,OAAV,CAAkBP,GAAlB,CAAD,iEAA2B,CAA3B,CAAf;AAAA,KALN;AAMLW,IAAAA,UAAU,EAAGX,GAAD;AAAA;;AAAA,aAASY,OAAO,sBAACnB,OAAO,GAAGc,OAAV,CAAkBP,GAAlB,CAAD,iEAA2B,KAA3B,CAAhB;AAAA,KANP;AAOLa,IAAAA,UAAU,EAAE,MAAMC,MAAM,CAACC,IAAP,CAAYtB,OAAO,EAAnB,CAPb;AAQLuB,IAAAA,QAAQ,EAAGhB,GAAD,IAASP,OAAO,GAAGc,OAAV,CAAkBP,GAAlB,KAA0B;AARxC,GAAP;AAUD,CAnCM","sourcesContent":["/* global localStorage */\nimport type { MMKVConfiguration, NativeMMKV } from 'react-native-mmkv';\n\nconst canUseDOM =\n typeof window !== 'undefined' && window.document?.createElement != null;\n\nexport const createMMKV = (config: MMKVConfiguration): NativeMMKV => {\n if (config.id !== 'mmkv.default') {\n throw new Error(\"MMKV: 'id' is not supported on Web!\");\n }\n if (config.encryptionKey != null) {\n throw new Error(\"MMKV: 'encryptionKey' is not supported on Web!\");\n }\n if (config.path != null) {\n throw new Error(\"MMKV: 'path' is not supported on Web!\");\n }\n\n const storage = () => {\n if (!canUseDOM) {\n throw new Error(\n 'Tried to access storage on the server. Did you forget to call this in useEffect?'\n );\n }\n const domStorage =\n global?.localStorage ?? window?.localStorage ?? localStorage;\n if (domStorage == null) {\n throw new Error(`Could not find 'localStorage' instance!`);\n }\n return domStorage;\n };\n\n return {\n clearAll: () => storage().clear(),\n delete: (key) => storage().removeItem(key),\n set: (key, value) => storage().setItem(key, value.toString()),\n getString: (key) => storage().getItem(key) ?? undefined,\n getNumber: (key) => Number(storage().getItem(key) ?? 0),\n getBoolean: (key) => Boolean(storage().getItem(key) ?? false),\n getAllKeys: () => Object.keys(storage()),\n contains: (key) => storage().getItem(key) != null,\n };\n};\n"]}
|
package/lib/module/MMKV.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
2
2
|
|
|
3
3
|
import { unstable_batchedUpdates } from 'react-native';
|
|
4
|
+
import { createMMKV } from './createMMKV';
|
|
4
5
|
const onValueChangedListeners = new Map();
|
|
5
6
|
/**
|
|
6
7
|
* A single MMKV instance.
|
|
@@ -20,12 +21,8 @@ export class MMKV {
|
|
|
20
21
|
|
|
21
22
|
_defineProperty(this, "id", void 0);
|
|
22
23
|
|
|
23
|
-
if (global.mmkvCreateNewInstance == null) {
|
|
24
|
-
throw new Error('Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
24
|
this.id = configuration.id;
|
|
28
|
-
this.nativeInstance =
|
|
25
|
+
this.nativeInstance = createMMKV(configuration);
|
|
29
26
|
this.functionCache = {};
|
|
30
27
|
}
|
|
31
28
|
|
package/lib/module/MMKV.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["MMKV.ts"],"names":["unstable_batchedUpdates","onValueChangedListeners","Map","MMKV","constructor","configuration","id","
|
|
1
|
+
{"version":3,"sources":["MMKV.ts"],"names":["unstable_batchedUpdates","createMMKV","onValueChangedListeners","Map","MMKV","constructor","configuration","id","nativeInstance","functionCache","has","set","get","getFunctionFromCache","functionName","onValuesAboutToChange","keys","length","setImmediate","key","listener","value","func","getBoolean","getString","getNumber","contains","delete","getAllKeys","clearAll","addOnValueChangedListener","onValueChanged","push","remove","index","indexOf","splice"],"mappings":"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","sourcesContent":["import { unstable_batchedUpdates } from 'react-native';\nimport { createMMKV } from './createMMKV';\n\ninterface Listener {\n remove: () => void;\n}\n\n/**\n * Used for configuration of a single MMKV instance.\n */\nexport interface MMKVConfiguration {\n /**\n * The MMKV instance's ID. If you want to use multiple instances, make sure to use different IDs!\n *\n * @example\n * ```ts\n * const userStorage = new MMKV({ id: `user-${userId}-storage` })\n * const globalStorage = new MMKV({ id: 'global-app-storage' })\n * ```\n *\n * @default 'mmkv.default'\n */\n id: string;\n /**\n * The MMKV instance's root path. By default, MMKV stores file inside `$(Documents)/mmkv/`. You can customize MMKV's root directory on MMKV initialization:\n *\n * @example\n * ```ts\n * const temporaryStorage = new MMKV({ path: '/tmp/' })\n * ```\n */\n path?: string;\n /**\n * The MMKV instance's encryption/decryption key. By default, MMKV stores all key-values in plain text on file, relying on iOS's sandbox to make sure the file is encrypted. Should you worry about information leaking, you can choose to encrypt MMKV.\n *\n * @example\n * ```ts\n * const secureStorage = new MMKV({ encryptionKey: 'my-encryption-key!' })\n * ```\n */\n encryptionKey?: string;\n}\n\n/**\n * Represents a single MMKV instance.\n */\ninterface MMKVInterface {\n /**\n * Set a value for the given `key`.\n */\n set: (key: string, value: boolean | string | number) => void;\n /**\n * Get a boolean value for the given `key`.\n *\n * @default false\n */\n getBoolean: (key: string) => boolean;\n /**\n * Get a string value for the given `key`.\n *\n * @default undefined\n */\n getString: (key: string) => string | undefined;\n /**\n * Get a number value for the given `key`.\n *\n * @default 0\n */\n getNumber: (key: string) => number;\n /**\n * Checks whether the given `key` is being stored in this MMKV instance.\n */\n contains: (key: string) => boolean;\n /**\n * Delete the given `key`.\n */\n delete: (key: string) => void;\n /**\n * Get all keys.\n *\n * @default []\n */\n getAllKeys: () => string[];\n /**\n * Delete all keys.\n */\n clearAll: () => void;\n /**\n * Adds a value changed listener.\n */\n addOnValueChangedListener: (\n onValueChanged: (key: string) => void\n ) => Listener;\n}\n\nexport type NativeMMKV = Pick<\n MMKVInterface,\n | 'clearAll'\n | 'contains'\n | 'delete'\n | 'getAllKeys'\n | 'getBoolean'\n | 'getNumber'\n | 'getString'\n | 'set'\n>;\n\nconst onValueChangedListeners = new Map<string, ((key: string) => void)[]>();\n\n/**\n * A single MMKV instance.\n */\nexport class MMKV implements MMKVInterface {\n private nativeInstance: NativeMMKV;\n private functionCache: Partial<NativeMMKV>;\n private id: string;\n\n /**\n * Creates a new MMKV instance with the given Configuration.\n * If no custom `id` is supplied, `'default'` will be used.\n */\n constructor(configuration: MMKVConfiguration = { id: 'mmkv.default' }) {\n this.id = configuration.id;\n this.nativeInstance = createMMKV(configuration);\n this.functionCache = {};\n }\n\n private get onValueChangedListeners() {\n if (!onValueChangedListeners.has(this.id)) {\n onValueChangedListeners.set(this.id, []);\n }\n return onValueChangedListeners.get(this.id)!;\n }\n\n private getFunctionFromCache<T extends keyof NativeMMKV>(\n functionName: T\n ): NativeMMKV[T] {\n if (this.functionCache[functionName] == null) {\n this.functionCache[functionName] = this.nativeInstance[functionName];\n }\n return this.functionCache[functionName] as NativeMMKV[T];\n }\n\n private onValuesAboutToChange(keys: string[]) {\n if (this.onValueChangedListeners.length === 0) return;\n\n setImmediate(() => {\n unstable_batchedUpdates(() => {\n for (const key of keys) {\n for (const listener of this.onValueChangedListeners) {\n listener(key);\n }\n }\n });\n });\n }\n\n set(key: string, value: boolean | string | number): void {\n this.onValuesAboutToChange([key]);\n\n const func = this.getFunctionFromCache('set');\n return func(key, value);\n }\n getBoolean(key: string): boolean {\n const func = this.getFunctionFromCache('getBoolean');\n return func(key);\n }\n getString(key: string): string | undefined {\n const func = this.getFunctionFromCache('getString');\n return func(key);\n }\n getNumber(key: string): number {\n const func = this.getFunctionFromCache('getNumber');\n return func(key);\n }\n contains(key: string): boolean {\n const func = this.getFunctionFromCache('contains');\n return func(key);\n }\n delete(key: string): void {\n this.onValuesAboutToChange([key]);\n\n const func = this.getFunctionFromCache('delete');\n return func(key);\n }\n getAllKeys(): string[] {\n const func = this.getFunctionFromCache('getAllKeys');\n return func();\n }\n clearAll(): void {\n const keys = this.getAllKeys();\n this.onValuesAboutToChange(keys);\n\n const func = this.getFunctionFromCache('clearAll');\n return func();\n }\n\n addOnValueChangedListener(onValueChanged: (key: string) => void): Listener {\n this.onValueChangedListeners.push(onValueChanged);\n\n return {\n remove: () => {\n const index = this.onValueChangedListeners.indexOf(onValueChanged);\n if (index !== -1) {\n this.onValueChangedListeners.splice(index, 1);\n }\n },\n };\n }\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// global func declaration for JSI functions
|
|
2
|
+
export const createMMKV = config => {
|
|
3
|
+
if (global.mmkvCreateNewInstance == null) {
|
|
4
|
+
throw new Error('Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!');
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
return global.mmkvCreateNewInstance(config);
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=createMMKV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["createMMKV.ts"],"names":["createMMKV","config","global","mmkvCreateNewInstance","Error"],"mappings":"AAEA;AAKA,OAAO,MAAMA,UAAU,GAAIC,MAAD,IAA2C;AACnE,MAAIC,MAAM,CAACC,qBAAP,IAAgC,IAApC,EAA0C;AACxC,UAAM,IAAIC,KAAJ,CACJ,0MADI,CAAN;AAGD;;AAED,SAAOF,MAAM,CAACC,qBAAP,CAA6BF,MAA7B,CAAP;AACD,CARM","sourcesContent":["import type { MMKVConfiguration, NativeMMKV } from 'react-native-mmkv';\n\n// global func declaration for JSI functions\ndeclare global {\n function mmkvCreateNewInstance(configuration: MMKVConfiguration): NativeMMKV;\n}\n\nexport const createMMKV = (config: MMKVConfiguration): NativeMMKV => {\n if (global.mmkvCreateNewInstance == null) {\n throw new Error(\n 'Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!'\n );\n }\n\n return global.mmkvCreateNewInstance(config);\n};\n"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
var _window$document;
|
|
2
|
+
|
|
3
|
+
/* global localStorage */
|
|
4
|
+
const canUseDOM = typeof window !== 'undefined' && ((_window$document = window.document) === null || _window$document === void 0 ? void 0 : _window$document.createElement) != null;
|
|
5
|
+
export const createMMKV = config => {
|
|
6
|
+
if (config.id !== 'mmkv.default') {
|
|
7
|
+
throw new Error("MMKV: 'id' is not supported on Web!");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (config.encryptionKey != null) {
|
|
11
|
+
throw new Error("MMKV: 'encryptionKey' is not supported on Web!");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (config.path != null) {
|
|
15
|
+
throw new Error("MMKV: 'path' is not supported on Web!");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const storage = () => {
|
|
19
|
+
var _ref, _global$localStorage, _global, _window;
|
|
20
|
+
|
|
21
|
+
if (!canUseDOM) {
|
|
22
|
+
throw new Error('Tried to access storage on the server. Did you forget to call this in useEffect?');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const domStorage = (_ref = (_global$localStorage = (_global = global) === null || _global === void 0 ? void 0 : _global.localStorage) !== null && _global$localStorage !== void 0 ? _global$localStorage : (_window = window) === null || _window === void 0 ? void 0 : _window.localStorage) !== null && _ref !== void 0 ? _ref : localStorage;
|
|
26
|
+
|
|
27
|
+
if (domStorage == null) {
|
|
28
|
+
throw new Error(`Could not find 'localStorage' instance!`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return domStorage;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
clearAll: () => storage().clear(),
|
|
36
|
+
delete: key => storage().removeItem(key),
|
|
37
|
+
set: (key, value) => storage().setItem(key, value.toString()),
|
|
38
|
+
getString: key => {
|
|
39
|
+
var _storage$getItem;
|
|
40
|
+
|
|
41
|
+
return (_storage$getItem = storage().getItem(key)) !== null && _storage$getItem !== void 0 ? _storage$getItem : undefined;
|
|
42
|
+
},
|
|
43
|
+
getNumber: key => {
|
|
44
|
+
var _storage$getItem2;
|
|
45
|
+
|
|
46
|
+
return Number((_storage$getItem2 = storage().getItem(key)) !== null && _storage$getItem2 !== void 0 ? _storage$getItem2 : 0);
|
|
47
|
+
},
|
|
48
|
+
getBoolean: key => {
|
|
49
|
+
var _storage$getItem3;
|
|
50
|
+
|
|
51
|
+
return Boolean((_storage$getItem3 = storage().getItem(key)) !== null && _storage$getItem3 !== void 0 ? _storage$getItem3 : false);
|
|
52
|
+
},
|
|
53
|
+
getAllKeys: () => Object.keys(storage()),
|
|
54
|
+
contains: key => storage().getItem(key) != null
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=createMMKV.web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["createMMKV.web.ts"],"names":["canUseDOM","window","document","createElement","createMMKV","config","id","Error","encryptionKey","path","storage","domStorage","global","localStorage","clearAll","clear","delete","key","removeItem","set","value","setItem","toString","getString","getItem","undefined","getNumber","Number","getBoolean","Boolean","getAllKeys","Object","keys","contains"],"mappings":";;AAAA;AAGA,MAAMA,SAAS,GACb,OAAOC,MAAP,KAAkB,WAAlB,IAAiC,qBAAAA,MAAM,CAACC,QAAP,sEAAiBC,aAAjB,KAAkC,IADrE;AAGA,OAAO,MAAMC,UAAU,GAAIC,MAAD,IAA2C;AACnE,MAAIA,MAAM,CAACC,EAAP,KAAc,cAAlB,EAAkC;AAChC,UAAM,IAAIC,KAAJ,CAAU,qCAAV,CAAN;AACD;;AACD,MAAIF,MAAM,CAACG,aAAP,IAAwB,IAA5B,EAAkC;AAChC,UAAM,IAAID,KAAJ,CAAU,gDAAV,CAAN;AACD;;AACD,MAAIF,MAAM,CAACI,IAAP,IAAe,IAAnB,EAAyB;AACvB,UAAM,IAAIF,KAAJ,CAAU,uCAAV,CAAN;AACD;;AAED,QAAMG,OAAO,GAAG,MAAM;AAAA;;AACpB,QAAI,CAACV,SAAL,EAAgB;AACd,YAAM,IAAIO,KAAJ,CACJ,kFADI,CAAN;AAGD;;AACD,UAAMI,UAAU,8CACdC,MADc,4CACd,QAAQC,YADM,kFACUZ,MADV,4CACU,QAAQY,YADlB,uCACkCA,YADlD;;AAEA,QAAIF,UAAU,IAAI,IAAlB,EAAwB;AACtB,YAAM,IAAIJ,KAAJ,CAAW,yCAAX,CAAN;AACD;;AACD,WAAOI,UAAP;AACD,GAZD;;AAcA,SAAO;AACLG,IAAAA,QAAQ,EAAE,MAAMJ,OAAO,GAAGK,KAAV,EADX;AAELC,IAAAA,MAAM,EAAGC,GAAD,IAASP,OAAO,GAAGQ,UAAV,CAAqBD,GAArB,CAFZ;AAGLE,IAAAA,GAAG,EAAE,CAACF,GAAD,EAAMG,KAAN,KAAgBV,OAAO,GAAGW,OAAV,CAAkBJ,GAAlB,EAAuBG,KAAK,CAACE,QAAN,EAAvB,CAHhB;AAILC,IAAAA,SAAS,EAAGN,GAAD;AAAA;;AAAA,iCAASP,OAAO,GAAGc,OAAV,CAAkBP,GAAlB,CAAT,+DAAmCQ,SAAnC;AAAA,KAJN;AAKLC,IAAAA,SAAS,EAAGT,GAAD;AAAA;;AAAA,aAASU,MAAM,sBAACjB,OAAO,GAAGc,OAAV,CAAkBP,GAAlB,CAAD,iEAA2B,CAA3B,CAAf;AAAA,KALN;AAMLW,IAAAA,UAAU,EAAGX,GAAD;AAAA;;AAAA,aAASY,OAAO,sBAACnB,OAAO,GAAGc,OAAV,CAAkBP,GAAlB,CAAD,iEAA2B,KAA3B,CAAhB;AAAA,KANP;AAOLa,IAAAA,UAAU,EAAE,MAAMC,MAAM,CAACC,IAAP,CAAYtB,OAAO,EAAnB,CAPb;AAQLuB,IAAAA,QAAQ,EAAGhB,GAAD,IAASP,OAAO,GAAGc,OAAV,CAAkBP,GAAlB,KAA0B;AARxC,GAAP;AAUD,CAnCM","sourcesContent":["/* global localStorage */\nimport type { MMKVConfiguration, NativeMMKV } from 'react-native-mmkv';\n\nconst canUseDOM =\n typeof window !== 'undefined' && window.document?.createElement != null;\n\nexport const createMMKV = (config: MMKVConfiguration): NativeMMKV => {\n if (config.id !== 'mmkv.default') {\n throw new Error(\"MMKV: 'id' is not supported on Web!\");\n }\n if (config.encryptionKey != null) {\n throw new Error(\"MMKV: 'encryptionKey' is not supported on Web!\");\n }\n if (config.path != null) {\n throw new Error(\"MMKV: 'path' is not supported on Web!\");\n }\n\n const storage = () => {\n if (!canUseDOM) {\n throw new Error(\n 'Tried to access storage on the server. Did you forget to call this in useEffect?'\n );\n }\n const domStorage =\n global?.localStorage ?? window?.localStorage ?? localStorage;\n if (domStorage == null) {\n throw new Error(`Could not find 'localStorage' instance!`);\n }\n return domStorage;\n };\n\n return {\n clearAll: () => storage().clear(),\n delete: (key) => storage().removeItem(key),\n set: (key, value) => storage().setItem(key, value.toString()),\n getString: (key) => storage().getItem(key) ?? undefined,\n getNumber: (key) => Number(storage().getItem(key) ?? 0),\n getBoolean: (key) => Boolean(storage().getItem(key) ?? false),\n getAllKeys: () => Object.keys(storage()),\n contains: (key) => storage().getItem(key) != null,\n };\n};\n"]}
|
package/lib/typescript/MMKV.d.ts
CHANGED
|
@@ -85,9 +85,7 @@ interface MMKVInterface {
|
|
|
85
85
|
*/
|
|
86
86
|
addOnValueChangedListener: (onValueChanged: (key: string) => void) => Listener;
|
|
87
87
|
}
|
|
88
|
-
declare
|
|
89
|
-
function mmkvCreateNewInstance(configuration: MMKVConfiguration): MMKVInterface;
|
|
90
|
-
}
|
|
88
|
+
export declare type NativeMMKV = Pick<MMKVInterface, 'clearAll' | 'contains' | 'delete' | 'getAllKeys' | 'getBoolean' | 'getNumber' | 'getString' | 'set'>;
|
|
91
89
|
/**
|
|
92
90
|
* A single MMKV instance.
|
|
93
91
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-mmkv",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.6.3",
|
|
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
7
|
"types": "lib/typescript/index.d.ts",
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"typescript": "tsc --noEmit",
|
|
29
29
|
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
30
30
|
"lint-ci": "yarn lint -f ./node_modules/@firmnav/eslint-github-actions-formatter/dist/formatter.js",
|
|
31
|
-
"prepare": "git submodule update --init --recursive
|
|
31
|
+
"prepare": "git submodule update --init --recursive",
|
|
32
|
+
"build": "bob build",
|
|
32
33
|
"update-submodule": "git submodule update --remote --merge",
|
|
33
34
|
"release": "release-it",
|
|
34
35
|
"example": "yarn --cwd example",
|