react-native-mmkv 1.5.2 → 1.6.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.
package/README.md CHANGED
@@ -32,6 +32,7 @@
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
 
@@ -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
@@ -12,10 +12,23 @@ 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
+ set (
21
+ INCLUDE_JSIDYNAMIC_CPP
22
+ "${NODE_MODULES_DIR}/react-native/ReactCommon/jsi/jsi/JSIDynamic.cpp"
23
+ )
24
+ endif()
25
+
15
26
  add_library(reactnativemmkv # <-- Library name
16
27
  SHARED
17
28
  src/main/cpp/cpp-adapter.cpp
18
29
  src/main/cpp/MmkvHostObject.cpp
30
+ ${INCLUDE_JSI_CPP} # only on older RN versions
31
+ ${INCLUDE_JSIDYNAMIC_CPP} # only on older RN versions
19
32
  )
20
33
 
21
34
  set_target_properties(
@@ -31,18 +44,24 @@ find_library(
31
44
  log-lib
32
45
  log
33
46
  )
34
- find_library(
35
- JSI_LIB
36
- jsi
37
- PATHS ${LIBRN_DIR}
38
- NO_CMAKE_FIND_ROOT_PATH
39
- )
40
47
  find_library(
41
48
  REACT_NATIVE_JNI_LIB
42
49
  reactnativejni
43
50
  PATHS ${LIBRN_DIR}
44
51
  NO_CMAKE_FIND_ROOT_PATH
45
52
  )
53
+ if(${REACT_NATIVE_VERSION} LESS 66)
54
+ # JSI lib didn't exist on RN 0.65 and before. Simply omit it.
55
+ set (JSI_LIB "")
56
+ else()
57
+ # RN 0.66 distributes libjsi.so, can be used instead of compiling jsi.cpp manually.
58
+ find_library(
59
+ JSI_LIB
60
+ jsi
61
+ PATHS ${LIBRN_DIR}
62
+ NO_CMAKE_FIND_ROOT_PATH
63
+ )
64
+ endif()
46
65
 
47
66
  target_link_libraries(
48
67
  reactnativemmkv
@@ -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,6 +46,28 @@ def getExtOrIntegerDefault(name) {
28
46
  return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['Mmkv_' + name]).toInteger()
29
47
  }
30
48
 
49
+ def defaultDir = null
50
+ def androidSourcesDir = null
51
+ def androidSourcesName = 'React Native sources'
52
+
53
+ if (rootProject.ext.has('reactNativeAndroidRoot')) {
54
+ defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
55
+ androidSourcesDir = defaultDir.parentFile.toString()
56
+ } else {
57
+ defaultDir = file("$nodeModules/react-native/android")
58
+ androidSourcesDir = defaultDir.parentFile.toString()
59
+ }
60
+
61
+ if (!defaultDir.exists()) {
62
+ throw new GradleException(
63
+ "${project.name}: React Native android directory (node_modules/react-native/android) does not exist! Resolved node_modules to: ${nodeModules}"
64
+ )
65
+ }
66
+
67
+ def reactProperties = new Properties()
68
+ file("$nodeModules/react-native/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
69
+ def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME").split("\\.")[1].toInteger()
70
+
31
71
  android {
32
72
  compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
33
73
  buildToolsVersion getExtOrDefault('buildToolsVersion')
@@ -43,7 +83,8 @@ android {
43
83
  cppFlags "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID"
44
84
  abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
45
85
  arguments '-DANDROID_STL=c++_shared',
46
- "-DNODE_MODULES_DIR=${rootDir}/../node_modules"
86
+ "-DREACT_NATIVE_VERSION=${REACT_NATIVE_VERSION}",
87
+ "-DNODE_MODULES_DIR=${nodeModules}"
47
88
  }
48
89
  }
49
90
  }
@@ -85,69 +126,9 @@ repositories {
85
126
  mavenCentral()
86
127
  google()
87
128
 
88
- def found = false
89
- def defaultDir = null
90
- def androidSourcesName = 'React Native sources'
91
-
92
- if (rootProject.ext.has('reactNativeAndroidRoot')) {
93
- defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
94
- } else {
95
- defaultDir = new File(
96
- projectDir,
97
- '/../../../node_modules/react-native/android'
98
- )
99
- }
100
-
101
- if (defaultDir.exists()) {
102
- maven {
103
- url defaultDir.toString()
104
- name androidSourcesName
105
- }
106
-
107
- logger.info(":${project.name}:reactNativeAndroidRoot ${defaultDir.canonicalPath}")
108
- found = true
109
- } else {
110
- def parentDir = rootProject.projectDir
111
-
112
- 1.upto(5, {
113
- if (found) return true
114
- parentDir = parentDir.parentFile
115
-
116
- def androidSourcesDir = new File(
117
- parentDir,
118
- 'node_modules/react-native'
119
- )
120
-
121
- def androidPrebuiltBinaryDir = new File(
122
- parentDir,
123
- 'node_modules/react-native/android'
124
- )
125
-
126
- if (androidPrebuiltBinaryDir.exists()) {
127
- maven {
128
- url androidPrebuiltBinaryDir.toString()
129
- name androidSourcesName
130
- }
131
-
132
- logger.info(":${project.name}:reactNativeAndroidRoot ${androidPrebuiltBinaryDir.canonicalPath}")
133
- found = true
134
- } else if (androidSourcesDir.exists()) {
135
- maven {
136
- url androidSourcesDir.toString()
137
- name androidSourcesName
138
- }
139
-
140
- logger.info(":${project.name}:reactNativeAndroidRoot ${androidSourcesDir.canonicalPath}")
141
- found = true
142
- }
143
- })
144
- }
145
-
146
- if (!found) {
147
- throw new GradleException(
148
- "${project.name}: unable to locate React Native android sources. " +
149
- "Ensure you have you installed React Native as a dependency in your project and try again."
150
- )
129
+ maven {
130
+ url defaultDir.toString()
131
+ name androidSourcesName
151
132
  }
152
133
  }
153
134
 
@@ -160,17 +141,18 @@ dependencies {
160
141
  //noinspection GradleDynamicVersion
161
142
  extractJNI("com.facebook.fbjni:fbjni:+")
162
143
 
163
- def rnAAR = fileTree("${rootDir}/../node_modules/react-native/android").matching({ it.include "**/**/*.aar" }).singleFile
144
+ def rnAAR = fileTree("${defaultDir.toString()}").matching({ it.include "**/**/*.aar" }).singleFile
164
145
  extractJNI(files(rnAAR))
165
146
  }
166
147
 
167
-
168
148
  // third-party-ndk deps headers
169
149
  // mostly a copy of https://github.com/software-mansion/react-native-reanimated/blob/master/android/build.gradle#L115
170
150
 
151
+
152
+
171
153
  def downloadsDir = new File("$buildDir/downloads")
172
154
  def thirdPartyNdkDir = new File("$buildDir/third-party-ndk")
173
- def thirdPartyVersionsFile = new File("${rootDir}/../node_modules/react-native/ReactAndroid/gradle.properties")
155
+ def thirdPartyVersionsFile = new File("${androidSourcesDir.toString()}/ReactAndroid/gradle.properties")
174
156
  def thirdPartyVersions = new Properties()
175
157
  thirdPartyVersions.load(new FileInputStream(thirdPartyVersionsFile))
176
158
 
@@ -330,7 +312,7 @@ task extractJNIFiles {
330
312
  extractJNIFiles.mustRunAfter extractAARHeaders
331
313
 
332
314
  tasks.whenTaskAdded { task ->
333
- if (task.name == 'externalNativeBuildDebug' || task.name == 'externalNativeBuildRelease') {
315
+ if (!task.name.contains('Clean') && (task.name.contains('externalNative') || task.name.contains('CMake'))) {
334
316
  task.dependsOn(extractAARHeaders)
335
317
  task.dependsOn(extractJNIFiles)
336
318
  task.dependsOn(prepareThirdPartyNdkHeaders)
@@ -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 = global.mmkvCreateNewInstance(configuration);
34
+ this.nativeInstance = (0, _createMMKV.createMMKV)(configuration);
37
35
  this.functionCache = {};
38
36
  }
39
37
 
@@ -1 +1 @@
1
- {"version":3,"sources":["MMKV.ts"],"names":["onValueChangedListeners","Map","MMKV","constructor","configuration","id","global","mmkvCreateNewInstance","Error","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';\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 */\nexport interface 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\n// global func declaration for JSI functions\ndeclare global {\n function mmkvCreateNewInstance(\n configuration: MMKVConfiguration\n ): MMKVInterface;\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: MMKVInterface;\n private functionCache: Partial<MMKVInterface>;\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 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 this.id = configuration.id;\n this.nativeInstance = global.mmkvCreateNewInstance(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 MMKVInterface>(\n functionName: T\n ): MMKVInterface[T] {\n if (this.functionCache[functionName] == null) {\n this.functionCache[functionName] = this.nativeInstance[functionName];\n }\n return this.functionCache[functionName] as MMKVInterface[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"]}
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"]}
@@ -28,9 +28,10 @@ function getDefaultInstance() {
28
28
 
29
29
  function useMMKV(configuration) {
30
30
  const instance = (0, _react.useRef)();
31
- const lastConfiguration = (0, _react.useRef)(configuration);
31
+ const lastConfiguration = (0, _react.useRef)();
32
32
 
33
- if (!isConfigurationEqual(lastConfiguration.current, configuration)) {
33
+ if (lastConfiguration.current == null || !isConfigurationEqual(lastConfiguration.current, configuration)) {
34
+ lastConfiguration.current = configuration;
34
35
  instance.current = new _MMKV.MMKV(configuration);
35
36
  } // @ts-expect-error it's not null, I promise.
36
37
 
@@ -42,8 +43,10 @@ function createMMKVHook(getter) {
42
43
  return (key, instance) => {
43
44
  const mmkv = instance !== null && instance !== void 0 ? instance : getDefaultInstance();
44
45
  const [value, setValue] = (0, _react.useState)(() => getter(mmkv, key));
46
+ const valueRef = (0, _react.useRef)(value);
47
+ valueRef.current = value;
45
48
  const set = (0, _react.useCallback)(v => {
46
- const newValue = typeof v === 'function' ? v(value) : v;
49
+ const newValue = typeof v === 'function' ? v(valueRef.current) : v;
47
50
 
48
51
  switch (typeof newValue) {
49
52
  case 'number':
@@ -59,7 +62,7 @@ function createMMKVHook(getter) {
59
62
  default:
60
63
  throw new Error(`MMKV: Type ${typeof newValue} is not supported!`);
61
64
  }
62
- }, [key, mmkv, value]);
65
+ }, [key, mmkv]);
63
66
  (0, _react.useEffect)(() => {
64
67
  const listener = mmkv.addOnValueChangedListener(changedKey => {
65
68
  if (changedKey === key) {
@@ -1 +1 @@
1
- {"version":3,"sources":["hooks.ts"],"names":["isConfigurationEqual","left","right","encryptionKey","id","path","defaultInstance","getDefaultInstance","MMKV","useMMKV","configuration","instance","lastConfiguration","current","createMMKVHook","getter","key","mmkv","value","setValue","set","v","newValue","delete","Error","listener","addOnValueChangedListener","changedKey","remove","useMMKVString","getString","useMMKVNumber","getNumber","useMMKVBoolean","getBoolean","useMMKVObject","string","setString","undefined","JSON","parse","stringify"],"mappings":"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","sourcesContent":["import React, {\n useRef,\n useState,\n useMemo,\n useCallback,\n useEffect,\n} from 'react';\nimport { MMKV, MMKVConfiguration, MMKVInterface } from './MMKV';\n\nfunction isConfigurationEqual(\n left: MMKVConfiguration,\n right: MMKVConfiguration\n): boolean {\n return (\n left.encryptionKey === right.encryptionKey &&\n left.id === right.id &&\n left.path === right.path\n );\n}\n\nlet defaultInstance: MMKVInterface | null = null;\nfunction getDefaultInstance(): MMKVInterface {\n if (defaultInstance == null) {\n defaultInstance = new MMKV();\n }\n return defaultInstance;\n}\n\nexport function useMMKV(\n configuration: MMKVConfiguration\n): React.RefObject<MMKVInterface> {\n const instance = useRef<MMKVInterface>();\n\n const lastConfiguration = useRef<MMKVConfiguration>(configuration);\n if (!isConfigurationEqual(lastConfiguration.current, configuration)) {\n instance.current = new MMKV(configuration);\n }\n\n // @ts-expect-error it's not null, I promise.\n return instance;\n}\n\nfunction createMMKVHook<\n T extends boolean | number | (string | undefined),\n TSet extends T | undefined,\n TSetAction extends TSet | ((current: T) => TSet)\n>(getter: (instance: MMKVInterface, key: string) => T) {\n return (\n key: string,\n instance?: MMKVInterface\n ): [value: T, setValue: (value: TSetAction) => void] => {\n const mmkv = instance ?? getDefaultInstance();\n const [value, setValue] = useState(() => getter(mmkv, key));\n\n const set = useCallback(\n (v: TSetAction) => {\n const newValue = typeof v === 'function' ? v(value) : v;\n switch (typeof newValue) {\n case 'number':\n case 'string':\n case 'boolean':\n mmkv.set(key, newValue);\n break;\n case 'undefined':\n mmkv.delete(key);\n break;\n default:\n throw new Error(`MMKV: Type ${typeof newValue} is not supported!`);\n }\n },\n [key, mmkv, value]\n );\n\n useEffect(() => {\n const listener = mmkv.addOnValueChangedListener((changedKey) => {\n if (changedKey === key) {\n setValue(getter(mmkv, key));\n }\n });\n return () => listener.remove();\n }, [key, mmkv]);\n\n return useMemo(() => [value, set], [value, set]);\n };\n}\n\n/**\n * Use the string value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [username, setUsername] = useMMKVString(\"user.name\")\n * ```\n */\nexport const useMMKVString = createMMKVHook((instance, key) =>\n instance.getString(key)\n);\n\n/**\n * Use the number value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [age, setAge] = useMMKVNumber(\"user.age\")\n * ```\n */\nexport const useMMKVNumber = createMMKVHook((instance, key) =>\n instance.getNumber(key)\n);\n/**\n * Use the boolean value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [isPremiumAccount, setIsPremiumAccount] = useMMKVBoolean(\"user.isPremium\")\n * ```\n */\nexport const useMMKVBoolean = createMMKVHook((instance, key) =>\n instance.getBoolean(key)\n);\n/**\n * Use an object value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * The object will be serialized using `JSON`.\n *\n * @example\n * ```ts\n * const [user, setUser] = useMMKVObject<User>(\"user\")\n * ```\n */\nexport function useMMKVObject<T>(\n key: string,\n instance?: MMKVInterface\n): [value: T | undefined, setValue: (value: T) => void] {\n const [string, setString] = useMMKVString(key, instance);\n\n const value = useMemo(() => {\n if (string == null) return undefined;\n return JSON.parse(string) as T;\n }, [string]);\n const setValue = useCallback(\n (v: T) => {\n setString(JSON.stringify(v));\n },\n [setString]\n );\n\n return [value, setValue];\n}\n"]}
1
+ {"version":3,"sources":["hooks.ts"],"names":["isConfigurationEqual","left","right","encryptionKey","id","path","defaultInstance","getDefaultInstance","MMKV","useMMKV","configuration","instance","lastConfiguration","current","createMMKVHook","getter","key","mmkv","value","setValue","valueRef","set","v","newValue","delete","Error","listener","addOnValueChangedListener","changedKey","remove","useMMKVString","getString","useMMKVNumber","getNumber","useMMKVBoolean","getBoolean","useMMKVObject","string","setString","undefined","JSON","parse","stringify"],"mappings":"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","sourcesContent":["import React, {\n useRef,\n useState,\n useMemo,\n useCallback,\n useEffect,\n} from 'react';\nimport { MMKV, MMKVConfiguration } from './MMKV';\n\nfunction isConfigurationEqual(\n left: MMKVConfiguration,\n right: MMKVConfiguration\n): boolean {\n return (\n left.encryptionKey === right.encryptionKey &&\n left.id === right.id &&\n left.path === right.path\n );\n}\n\nlet defaultInstance: MMKV | null = null;\nfunction getDefaultInstance(): MMKV {\n if (defaultInstance == null) {\n defaultInstance = new MMKV();\n }\n return defaultInstance;\n}\n\nexport function useMMKV(\n configuration: MMKVConfiguration\n): React.RefObject<MMKV> {\n const instance = useRef<MMKV>();\n\n const lastConfiguration = useRef<MMKVConfiguration>();\n if (\n lastConfiguration.current == null ||\n !isConfigurationEqual(lastConfiguration.current, configuration)\n ) {\n lastConfiguration.current = configuration;\n instance.current = new MMKV(configuration);\n }\n\n // @ts-expect-error it's not null, I promise.\n return instance;\n}\n\nfunction createMMKVHook<\n T extends boolean | number | (string | undefined),\n TSet extends T | undefined,\n TSetAction extends TSet | ((current: T) => TSet)\n>(getter: (instance: MMKV, key: string) => T) {\n return (\n key: string,\n instance?: MMKV\n ): [value: T, setValue: (value: TSetAction) => void] => {\n const mmkv = instance ?? getDefaultInstance();\n const [value, setValue] = useState(() => getter(mmkv, key));\n const valueRef = useRef<T>(value);\n valueRef.current = value;\n\n const set = useCallback(\n (v: TSetAction) => {\n const newValue = typeof v === 'function' ? v(valueRef.current) : v;\n switch (typeof newValue) {\n case 'number':\n case 'string':\n case 'boolean':\n mmkv.set(key, newValue);\n break;\n case 'undefined':\n mmkv.delete(key);\n break;\n default:\n throw new Error(`MMKV: Type ${typeof newValue} is not supported!`);\n }\n },\n [key, mmkv]\n );\n\n useEffect(() => {\n const listener = mmkv.addOnValueChangedListener((changedKey) => {\n if (changedKey === key) {\n setValue(getter(mmkv, key));\n }\n });\n return () => listener.remove();\n }, [key, mmkv]);\n\n return useMemo(() => [value, set], [value, set]);\n };\n}\n\n/**\n * Use the string value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [username, setUsername] = useMMKVString(\"user.name\")\n * ```\n */\nexport const useMMKVString = createMMKVHook((instance, key) =>\n instance.getString(key)\n);\n\n/**\n * Use the number value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [age, setAge] = useMMKVNumber(\"user.age\")\n * ```\n */\nexport const useMMKVNumber = createMMKVHook((instance, key) =>\n instance.getNumber(key)\n);\n/**\n * Use the boolean value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [isPremiumAccount, setIsPremiumAccount] = useMMKVBoolean(\"user.isPremium\")\n * ```\n */\nexport const useMMKVBoolean = createMMKVHook((instance, key) =>\n instance.getBoolean(key)\n);\n/**\n * Use an object value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * The object will be serialized using `JSON`.\n *\n * @example\n * ```ts\n * const [user, setUser] = useMMKVObject<User>(\"user\")\n * ```\n */\nexport function useMMKVObject<T>(\n key: string,\n instance?: MMKV\n): [value: T | undefined, setValue: (value: T) => void] {\n const [string, setString] = useMMKVString(key, instance);\n\n const value = useMemo(() => {\n if (string == null) return undefined;\n return JSON.parse(string) as T;\n }, [string]);\n const setValue = useCallback(\n (v: T) => {\n setString(JSON.stringify(v));\n },\n [setString]\n );\n\n return [value, setValue];\n}\n"]}
@@ -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 = global.mmkvCreateNewInstance(configuration);
25
+ this.nativeInstance = createMMKV(configuration);
29
26
  this.functionCache = {};
30
27
  }
31
28
 
@@ -1 +1 @@
1
- {"version":3,"sources":["MMKV.ts"],"names":["unstable_batchedUpdates","onValueChangedListeners","Map","MMKV","constructor","configuration","id","global","mmkvCreateNewInstance","Error","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';\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 */\nexport interface 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\n// global func declaration for JSI functions\ndeclare global {\n function mmkvCreateNewInstance(\n configuration: MMKVConfiguration\n ): MMKVInterface;\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: MMKVInterface;\n private functionCache: Partial<MMKVInterface>;\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 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 this.id = configuration.id;\n this.nativeInstance = global.mmkvCreateNewInstance(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 MMKVInterface>(\n functionName: T\n ): MMKVInterface[T] {\n if (this.functionCache[functionName] == null) {\n this.functionCache[functionName] = this.nativeInstance[functionName];\n }\n return this.functionCache[functionName] as MMKVInterface[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"]}
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":";;AAAA,SAASA,uBAAT,QAAwC,cAAxC;AACA,SAASC,UAAT,QAA2B,cAA3B;AA0GA,MAAMC,uBAAuB,GAAG,IAAIC,GAAJ,EAAhC;AAEA;AACA;AACA;;AACA,OAAO,MAAMC,IAAN,CAAoC;AAKzC;AACF;AACA;AACA;AACEC,EAAAA,WAAW,CAACC,aAAgC,GAAG;AAAEC,IAAAA,EAAE,EAAE;AAAN,GAApC,EAA4D;AAAA;;AAAA;;AAAA;;AACrE,SAAKA,EAAL,GAAUD,aAAa,CAACC,EAAxB;AACA,SAAKC,cAAL,GAAsBP,UAAU,CAACK,aAAD,CAAhC;AACA,SAAKG,aAAL,GAAqB,EAArB;AACD;;AAEkC,MAAvBP,uBAAuB,GAAG;AACpC,QAAI,CAACA,uBAAuB,CAACQ,GAAxB,CAA4B,KAAKH,EAAjC,CAAL,EAA2C;AACzCL,MAAAA,uBAAuB,CAACS,GAAxB,CAA4B,KAAKJ,EAAjC,EAAqC,EAArC;AACD;;AACD,WAAOL,uBAAuB,CAACU,GAAxB,CAA4B,KAAKL,EAAjC,CAAP;AACD;;AAEOM,EAAAA,oBAAoB,CAC1BC,YAD0B,EAEX;AACf,QAAI,KAAKL,aAAL,CAAmBK,YAAnB,KAAoC,IAAxC,EAA8C;AAC5C,WAAKL,aAAL,CAAmBK,YAAnB,IAAmC,KAAKN,cAAL,CAAoBM,YAApB,CAAnC;AACD;;AACD,WAAO,KAAKL,aAAL,CAAmBK,YAAnB,CAAP;AACD;;AAEOC,EAAAA,qBAAqB,CAACC,IAAD,EAAiB;AAC5C,QAAI,KAAKd,uBAAL,CAA6Be,MAA7B,KAAwC,CAA5C,EAA+C;AAE/CC,IAAAA,YAAY,CAAC,MAAM;AACjBlB,MAAAA,uBAAuB,CAAC,MAAM;AAC5B,aAAK,MAAMmB,GAAX,IAAkBH,IAAlB,EAAwB;AACtB,eAAK,MAAMI,QAAX,IAAuB,KAAKlB,uBAA5B,EAAqD;AACnDkB,YAAAA,QAAQ,CAACD,GAAD,CAAR;AACD;AACF;AACF,OANsB,CAAvB;AAOD,KARW,CAAZ;AASD;;AAEDR,EAAAA,GAAG,CAACQ,GAAD,EAAcE,KAAd,EAAsD;AACvD,SAAKN,qBAAL,CAA2B,CAACI,GAAD,CAA3B;AAEA,UAAMG,IAAI,GAAG,KAAKT,oBAAL,CAA0B,KAA1B,CAAb;AACA,WAAOS,IAAI,CAACH,GAAD,EAAME,KAAN,CAAX;AACD;;AACDE,EAAAA,UAAU,CAACJ,GAAD,EAAuB;AAC/B,UAAMG,IAAI,GAAG,KAAKT,oBAAL,CAA0B,YAA1B,CAAb;AACA,WAAOS,IAAI,CAACH,GAAD,CAAX;AACD;;AACDK,EAAAA,SAAS,CAACL,GAAD,EAAkC;AACzC,UAAMG,IAAI,GAAG,KAAKT,oBAAL,CAA0B,WAA1B,CAAb;AACA,WAAOS,IAAI,CAACH,GAAD,CAAX;AACD;;AACDM,EAAAA,SAAS,CAACN,GAAD,EAAsB;AAC7B,UAAMG,IAAI,GAAG,KAAKT,oBAAL,CAA0B,WAA1B,CAAb;AACA,WAAOS,IAAI,CAACH,GAAD,CAAX;AACD;;AACDO,EAAAA,QAAQ,CAACP,GAAD,EAAuB;AAC7B,UAAMG,IAAI,GAAG,KAAKT,oBAAL,CAA0B,UAA1B,CAAb;AACA,WAAOS,IAAI,CAACH,GAAD,CAAX;AACD;;AACDQ,EAAAA,MAAM,CAACR,GAAD,EAAoB;AACxB,SAAKJ,qBAAL,CAA2B,CAACI,GAAD,CAA3B;AAEA,UAAMG,IAAI,GAAG,KAAKT,oBAAL,CAA0B,QAA1B,CAAb;AACA,WAAOS,IAAI,CAACH,GAAD,CAAX;AACD;;AACDS,EAAAA,UAAU,GAAa;AACrB,UAAMN,IAAI,GAAG,KAAKT,oBAAL,CAA0B,YAA1B,CAAb;AACA,WAAOS,IAAI,EAAX;AACD;;AACDO,EAAAA,QAAQ,GAAS;AACf,UAAMb,IAAI,GAAG,KAAKY,UAAL,EAAb;AACA,SAAKb,qBAAL,CAA2BC,IAA3B;AAEA,UAAMM,IAAI,GAAG,KAAKT,oBAAL,CAA0B,UAA1B,CAAb;AACA,WAAOS,IAAI,EAAX;AACD;;AAEDQ,EAAAA,yBAAyB,CAACC,cAAD,EAAkD;AACzE,SAAK7B,uBAAL,CAA6B8B,IAA7B,CAAkCD,cAAlC;AAEA,WAAO;AACLE,MAAAA,MAAM,EAAE,MAAM;AACZ,cAAMC,KAAK,GAAG,KAAKhC,uBAAL,CAA6BiC,OAA7B,CAAqCJ,cAArC,CAAd;;AACA,YAAIG,KAAK,KAAK,CAAC,CAAf,EAAkB;AAChB,eAAKhC,uBAAL,CAA6BkC,MAA7B,CAAoCF,KAApC,EAA2C,CAA3C;AACD;AACF;AANI,KAAP;AAQD;;AAhGwC","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"]}
@@ -17,9 +17,10 @@ function getDefaultInstance() {
17
17
 
18
18
  export function useMMKV(configuration) {
19
19
  const instance = useRef();
20
- const lastConfiguration = useRef(configuration);
20
+ const lastConfiguration = useRef();
21
21
 
22
- if (!isConfigurationEqual(lastConfiguration.current, configuration)) {
22
+ if (lastConfiguration.current == null || !isConfigurationEqual(lastConfiguration.current, configuration)) {
23
+ lastConfiguration.current = configuration;
23
24
  instance.current = new MMKV(configuration);
24
25
  } // @ts-expect-error it's not null, I promise.
25
26
 
@@ -31,8 +32,10 @@ function createMMKVHook(getter) {
31
32
  return (key, instance) => {
32
33
  const mmkv = instance !== null && instance !== void 0 ? instance : getDefaultInstance();
33
34
  const [value, setValue] = useState(() => getter(mmkv, key));
35
+ const valueRef = useRef(value);
36
+ valueRef.current = value;
34
37
  const set = useCallback(v => {
35
- const newValue = typeof v === 'function' ? v(value) : v;
38
+ const newValue = typeof v === 'function' ? v(valueRef.current) : v;
36
39
 
37
40
  switch (typeof newValue) {
38
41
  case 'number':
@@ -48,7 +51,7 @@ function createMMKVHook(getter) {
48
51
  default:
49
52
  throw new Error(`MMKV: Type ${typeof newValue} is not supported!`);
50
53
  }
51
- }, [key, mmkv, value]);
54
+ }, [key, mmkv]);
52
55
  useEffect(() => {
53
56
  const listener = mmkv.addOnValueChangedListener(changedKey => {
54
57
  if (changedKey === key) {
@@ -1 +1 @@
1
- {"version":3,"sources":["hooks.ts"],"names":["useRef","useState","useMemo","useCallback","useEffect","MMKV","isConfigurationEqual","left","right","encryptionKey","id","path","defaultInstance","getDefaultInstance","useMMKV","configuration","instance","lastConfiguration","current","createMMKVHook","getter","key","mmkv","value","setValue","set","v","newValue","delete","Error","listener","addOnValueChangedListener","changedKey","remove","useMMKVString","getString","useMMKVNumber","getNumber","useMMKVBoolean","getBoolean","useMMKVObject","string","setString","undefined","JSON","parse","stringify"],"mappings":"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","sourcesContent":["import React, {\n useRef,\n useState,\n useMemo,\n useCallback,\n useEffect,\n} from 'react';\nimport { MMKV, MMKVConfiguration, MMKVInterface } from './MMKV';\n\nfunction isConfigurationEqual(\n left: MMKVConfiguration,\n right: MMKVConfiguration\n): boolean {\n return (\n left.encryptionKey === right.encryptionKey &&\n left.id === right.id &&\n left.path === right.path\n );\n}\n\nlet defaultInstance: MMKVInterface | null = null;\nfunction getDefaultInstance(): MMKVInterface {\n if (defaultInstance == null) {\n defaultInstance = new MMKV();\n }\n return defaultInstance;\n}\n\nexport function useMMKV(\n configuration: MMKVConfiguration\n): React.RefObject<MMKVInterface> {\n const instance = useRef<MMKVInterface>();\n\n const lastConfiguration = useRef<MMKVConfiguration>(configuration);\n if (!isConfigurationEqual(lastConfiguration.current, configuration)) {\n instance.current = new MMKV(configuration);\n }\n\n // @ts-expect-error it's not null, I promise.\n return instance;\n}\n\nfunction createMMKVHook<\n T extends boolean | number | (string | undefined),\n TSet extends T | undefined,\n TSetAction extends TSet | ((current: T) => TSet)\n>(getter: (instance: MMKVInterface, key: string) => T) {\n return (\n key: string,\n instance?: MMKVInterface\n ): [value: T, setValue: (value: TSetAction) => void] => {\n const mmkv = instance ?? getDefaultInstance();\n const [value, setValue] = useState(() => getter(mmkv, key));\n\n const set = useCallback(\n (v: TSetAction) => {\n const newValue = typeof v === 'function' ? v(value) : v;\n switch (typeof newValue) {\n case 'number':\n case 'string':\n case 'boolean':\n mmkv.set(key, newValue);\n break;\n case 'undefined':\n mmkv.delete(key);\n break;\n default:\n throw new Error(`MMKV: Type ${typeof newValue} is not supported!`);\n }\n },\n [key, mmkv, value]\n );\n\n useEffect(() => {\n const listener = mmkv.addOnValueChangedListener((changedKey) => {\n if (changedKey === key) {\n setValue(getter(mmkv, key));\n }\n });\n return () => listener.remove();\n }, [key, mmkv]);\n\n return useMemo(() => [value, set], [value, set]);\n };\n}\n\n/**\n * Use the string value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [username, setUsername] = useMMKVString(\"user.name\")\n * ```\n */\nexport const useMMKVString = createMMKVHook((instance, key) =>\n instance.getString(key)\n);\n\n/**\n * Use the number value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [age, setAge] = useMMKVNumber(\"user.age\")\n * ```\n */\nexport const useMMKVNumber = createMMKVHook((instance, key) =>\n instance.getNumber(key)\n);\n/**\n * Use the boolean value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [isPremiumAccount, setIsPremiumAccount] = useMMKVBoolean(\"user.isPremium\")\n * ```\n */\nexport const useMMKVBoolean = createMMKVHook((instance, key) =>\n instance.getBoolean(key)\n);\n/**\n * Use an object value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * The object will be serialized using `JSON`.\n *\n * @example\n * ```ts\n * const [user, setUser] = useMMKVObject<User>(\"user\")\n * ```\n */\nexport function useMMKVObject<T>(\n key: string,\n instance?: MMKVInterface\n): [value: T | undefined, setValue: (value: T) => void] {\n const [string, setString] = useMMKVString(key, instance);\n\n const value = useMemo(() => {\n if (string == null) return undefined;\n return JSON.parse(string) as T;\n }, [string]);\n const setValue = useCallback(\n (v: T) => {\n setString(JSON.stringify(v));\n },\n [setString]\n );\n\n return [value, setValue];\n}\n"]}
1
+ {"version":3,"sources":["hooks.ts"],"names":["useRef","useState","useMemo","useCallback","useEffect","MMKV","isConfigurationEqual","left","right","encryptionKey","id","path","defaultInstance","getDefaultInstance","useMMKV","configuration","instance","lastConfiguration","current","createMMKVHook","getter","key","mmkv","value","setValue","valueRef","set","v","newValue","delete","Error","listener","addOnValueChangedListener","changedKey","remove","useMMKVString","getString","useMMKVNumber","getNumber","useMMKVBoolean","getBoolean","useMMKVObject","string","setString","undefined","JSON","parse","stringify"],"mappings":"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","sourcesContent":["import React, {\n useRef,\n useState,\n useMemo,\n useCallback,\n useEffect,\n} from 'react';\nimport { MMKV, MMKVConfiguration } from './MMKV';\n\nfunction isConfigurationEqual(\n left: MMKVConfiguration,\n right: MMKVConfiguration\n): boolean {\n return (\n left.encryptionKey === right.encryptionKey &&\n left.id === right.id &&\n left.path === right.path\n );\n}\n\nlet defaultInstance: MMKV | null = null;\nfunction getDefaultInstance(): MMKV {\n if (defaultInstance == null) {\n defaultInstance = new MMKV();\n }\n return defaultInstance;\n}\n\nexport function useMMKV(\n configuration: MMKVConfiguration\n): React.RefObject<MMKV> {\n const instance = useRef<MMKV>();\n\n const lastConfiguration = useRef<MMKVConfiguration>();\n if (\n lastConfiguration.current == null ||\n !isConfigurationEqual(lastConfiguration.current, configuration)\n ) {\n lastConfiguration.current = configuration;\n instance.current = new MMKV(configuration);\n }\n\n // @ts-expect-error it's not null, I promise.\n return instance;\n}\n\nfunction createMMKVHook<\n T extends boolean | number | (string | undefined),\n TSet extends T | undefined,\n TSetAction extends TSet | ((current: T) => TSet)\n>(getter: (instance: MMKV, key: string) => T) {\n return (\n key: string,\n instance?: MMKV\n ): [value: T, setValue: (value: TSetAction) => void] => {\n const mmkv = instance ?? getDefaultInstance();\n const [value, setValue] = useState(() => getter(mmkv, key));\n const valueRef = useRef<T>(value);\n valueRef.current = value;\n\n const set = useCallback(\n (v: TSetAction) => {\n const newValue = typeof v === 'function' ? v(valueRef.current) : v;\n switch (typeof newValue) {\n case 'number':\n case 'string':\n case 'boolean':\n mmkv.set(key, newValue);\n break;\n case 'undefined':\n mmkv.delete(key);\n break;\n default:\n throw new Error(`MMKV: Type ${typeof newValue} is not supported!`);\n }\n },\n [key, mmkv]\n );\n\n useEffect(() => {\n const listener = mmkv.addOnValueChangedListener((changedKey) => {\n if (changedKey === key) {\n setValue(getter(mmkv, key));\n }\n });\n return () => listener.remove();\n }, [key, mmkv]);\n\n return useMemo(() => [value, set], [value, set]);\n };\n}\n\n/**\n * Use the string value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [username, setUsername] = useMMKVString(\"user.name\")\n * ```\n */\nexport const useMMKVString = createMMKVHook((instance, key) =>\n instance.getString(key)\n);\n\n/**\n * Use the number value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [age, setAge] = useMMKVNumber(\"user.age\")\n * ```\n */\nexport const useMMKVNumber = createMMKVHook((instance, key) =>\n instance.getNumber(key)\n);\n/**\n * Use the boolean value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * @example\n * ```ts\n * const [isPremiumAccount, setIsPremiumAccount] = useMMKVBoolean(\"user.isPremium\")\n * ```\n */\nexport const useMMKVBoolean = createMMKVHook((instance, key) =>\n instance.getBoolean(key)\n);\n/**\n * Use an object value of the given `key` from the given MMKV storage instance.\n *\n * If no instance is provided, a shared default instance will be used.\n *\n * The object will be serialized using `JSON`.\n *\n * @example\n * ```ts\n * const [user, setUser] = useMMKVObject<User>(\"user\")\n * ```\n */\nexport function useMMKVObject<T>(\n key: string,\n instance?: MMKV\n): [value: T | undefined, setValue: (value: T) => void] {\n const [string, setString] = useMMKVString(key, instance);\n\n const value = useMemo(() => {\n if (string == null) return undefined;\n return JSON.parse(string) as T;\n }, [string]);\n const setValue = useCallback(\n (v: T) => {\n setString(JSON.stringify(v));\n },\n [setString]\n );\n\n return [value, setValue];\n}\n"]}
@@ -39,7 +39,7 @@ export interface MMKVConfiguration {
39
39
  /**
40
40
  * Represents a single MMKV instance.
41
41
  */
42
- export interface MMKVInterface {
42
+ interface MMKVInterface {
43
43
  /**
44
44
  * Set a value for the given `key`.
45
45
  */
@@ -85,9 +85,7 @@ export interface MMKVInterface {
85
85
  */
86
86
  addOnValueChangedListener: (onValueChanged: (key: string) => void) => Listener;
87
87
  }
88
- declare global {
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
  */
@@ -0,0 +1,5 @@
1
+ import type { MMKVConfiguration, NativeMMKV } from 'react-native-mmkv';
2
+ declare global {
3
+ function mmkvCreateNewInstance(configuration: MMKVConfiguration): NativeMMKV;
4
+ }
5
+ export declare const createMMKV: (config: MMKVConfiguration) => NativeMMKV;
@@ -0,0 +1,2 @@
1
+ import type { MMKVConfiguration, NativeMMKV } from 'react-native-mmkv';
2
+ export declare const createMMKV: (config: MMKVConfiguration) => NativeMMKV;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import { MMKVConfiguration, MMKVInterface } from './MMKV';
3
- export declare function useMMKV(configuration: MMKVConfiguration): React.RefObject<MMKVInterface>;
2
+ import { MMKV, MMKVConfiguration } from './MMKV';
3
+ export declare function useMMKV(configuration: MMKVConfiguration): React.RefObject<MMKV>;
4
4
  /**
5
5
  * Use the string value of the given `key` from the given MMKV storage instance.
6
6
  *
@@ -11,7 +11,7 @@ export declare function useMMKV(configuration: MMKVConfiguration): React.RefObje
11
11
  * const [username, setUsername] = useMMKVString("user.name")
12
12
  * ```
13
13
  */
14
- export declare const useMMKVString: (key: string, instance?: MMKVInterface | undefined) => [value: string | undefined, setValue: (value: string | ((current: string | undefined) => string | undefined) | undefined) => void];
14
+ export declare const useMMKVString: (key: string, instance?: MMKV | undefined) => [value: string | undefined, setValue: (value: string | ((current: string | undefined) => string | undefined) | undefined) => void];
15
15
  /**
16
16
  * Use the number value of the given `key` from the given MMKV storage instance.
17
17
  *
@@ -22,7 +22,7 @@ export declare const useMMKVString: (key: string, instance?: MMKVInterface | und
22
22
  * const [age, setAge] = useMMKVNumber("user.age")
23
23
  * ```
24
24
  */
25
- export declare const useMMKVNumber: (key: string, instance?: MMKVInterface | undefined) => [value: number, setValue: (value: number | ((current: number) => number | undefined) | undefined) => void];
25
+ export declare const useMMKVNumber: (key: string, instance?: MMKV | undefined) => [value: number, setValue: (value: number | ((current: number) => number | undefined) | undefined) => void];
26
26
  /**
27
27
  * Use the boolean value of the given `key` from the given MMKV storage instance.
28
28
  *
@@ -33,7 +33,7 @@ export declare const useMMKVNumber: (key: string, instance?: MMKVInterface | und
33
33
  * const [isPremiumAccount, setIsPremiumAccount] = useMMKVBoolean("user.isPremium")
34
34
  * ```
35
35
  */
36
- export declare const useMMKVBoolean: (key: string, instance?: MMKVInterface | undefined) => [value: boolean, setValue: (value: boolean | ((current: boolean) => boolean | undefined) | undefined) => void];
36
+ export declare const useMMKVBoolean: (key: string, instance?: MMKV | undefined) => [value: boolean, setValue: (value: boolean | ((current: boolean) => boolean | undefined) | undefined) => void];
37
37
  /**
38
38
  * Use an object value of the given `key` from the given MMKV storage instance.
39
39
  *
@@ -46,4 +46,4 @@ export declare const useMMKVBoolean: (key: string, instance?: MMKVInterface | un
46
46
  * const [user, setUser] = useMMKVObject<User>("user")
47
47
  * ```
48
48
  */
49
- export declare function useMMKVObject<T>(key: string, instance?: MMKVInterface): [value: T | undefined, setValue: (value: T) => void];
49
+ export declare function useMMKVObject<T>(key: string, instance?: MMKV): [value: T | undefined, setValue: (value: T) => void];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-native-mmkv",
3
- "version": "1.5.2",
4
- "description": "An efficient, small mobile key-value storage framework developed by WeChat. Works on Android and iOS.",
3
+ "version": "1.6.1",
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 && bob build",
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",
@@ -10,7 +10,7 @@ Pod::Spec.new do |s|
10
10
  s.license = package["license"]
11
11
  s.authors = package["author"]
12
12
 
13
- s.platforms = { :ios => "11.0" }
13
+ s.platforms = { :ios => "11.0", :tvos => "12.0" }
14
14
  s.source = { :git => "https://github.com/mrousavy/react-native-mmkv.git", :tag => "#{s.version}" }
15
15
 
16
16
  # All source files that should be publicly visible