react-native-mmkv 1.5.0 → 1.5.4
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/android/build.gradle +52 -35
- package/lib/commonjs/MMKV.js.map +1 -1
- package/lib/commonjs/hooks.js +10 -7
- package/lib/commonjs/hooks.js.map +1 -1
- package/lib/module/MMKV.js.map +1 -1
- package/lib/module/hooks.js +8 -5
- package/lib/module/hooks.js.map +1 -1
- package/lib/typescript/MMKV.d.ts +1 -1
- package/lib/typescript/hooks.d.ts +6 -6
- package/package.json +1 -1
- package/react-native-mmkv.podspec +1 -1
package/android/build.gradle
CHANGED
|
@@ -28,6 +28,50 @@ def getExtOrIntegerDefault(name) {
|
|
|
28
28
|
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['Mmkv_' + name]).toInteger()
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
def found = false
|
|
32
|
+
def defaultDir = null
|
|
33
|
+
def androidSourcesDir = null
|
|
34
|
+
def androidSourcesName = 'React Native sources'
|
|
35
|
+
|
|
36
|
+
if (rootProject.ext.has('reactNativeAndroidRoot')) {
|
|
37
|
+
defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
|
|
38
|
+
androidSourcesDir = defaultDir.parentFile.toString()
|
|
39
|
+
} else {
|
|
40
|
+
defaultDir = new File(
|
|
41
|
+
projectDir,
|
|
42
|
+
'/../../../node_modules/react-native/android'
|
|
43
|
+
)
|
|
44
|
+
androidSourcesDir = defaultDir.parentFile.toString()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (defaultDir.exists()) {
|
|
48
|
+
found = true
|
|
49
|
+
} else {
|
|
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'
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
def androidPrebuiltBinaryDir = new File(
|
|
63
|
+
parentDir,
|
|
64
|
+
'node_modules/react-native/android'
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
if (androidPrebuiltBinaryDir.exists()) {
|
|
68
|
+
found = true
|
|
69
|
+
} else if (androidSourcesDir.exists()) {
|
|
70
|
+
found = true
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
|
|
31
75
|
android {
|
|
32
76
|
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
|
|
33
77
|
buildToolsVersion getExtOrDefault('buildToolsVersion')
|
|
@@ -43,7 +87,7 @@ android {
|
|
|
43
87
|
cppFlags "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID"
|
|
44
88
|
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
|
|
45
89
|
arguments '-DANDROID_STL=c++_shared',
|
|
46
|
-
"-DNODE_MODULES_DIR=${
|
|
90
|
+
"-DNODE_MODULES_DIR=${defaultDir.parentFile.parentFile.toString()}"
|
|
47
91
|
}
|
|
48
92
|
}
|
|
49
93
|
}
|
|
@@ -59,7 +103,7 @@ android {
|
|
|
59
103
|
}
|
|
60
104
|
|
|
61
105
|
packagingOptions {
|
|
62
|
-
excludes = ["**/libc++_shared.so", "**/libfbjni.so", "**/libjsi.so"]
|
|
106
|
+
excludes = ["**/libc++_shared.so", "**/libfbjni.so", "**/libreactnativejni.so", "**/libjsi.so", "**/MANIFEST.MF"]
|
|
63
107
|
}
|
|
64
108
|
|
|
65
109
|
buildTypes {
|
|
@@ -85,19 +129,6 @@ repositories {
|
|
|
85
129
|
mavenCentral()
|
|
86
130
|
google()
|
|
87
131
|
|
|
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
132
|
if (defaultDir.exists()) {
|
|
102
133
|
maven {
|
|
103
134
|
url defaultDir.toString()
|
|
@@ -105,24 +136,11 @@ repositories {
|
|
|
105
136
|
}
|
|
106
137
|
|
|
107
138
|
logger.info(":${project.name}:reactNativeAndroidRoot ${defaultDir.canonicalPath}")
|
|
108
|
-
found = true
|
|
109
139
|
} else {
|
|
110
140
|
def parentDir = rootProject.projectDir
|
|
141
|
+
defaultDir = new File(parentDir, '../node_modules/react-native/android')
|
|
111
142
|
|
|
112
143
|
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
144
|
if (androidPrebuiltBinaryDir.exists()) {
|
|
127
145
|
maven {
|
|
128
146
|
url androidPrebuiltBinaryDir.toString()
|
|
@@ -130,7 +148,6 @@ repositories {
|
|
|
130
148
|
}
|
|
131
149
|
|
|
132
150
|
logger.info(":${project.name}:reactNativeAndroidRoot ${androidPrebuiltBinaryDir.canonicalPath}")
|
|
133
|
-
found = true
|
|
134
151
|
} else if (androidSourcesDir.exists()) {
|
|
135
152
|
maven {
|
|
136
153
|
url androidSourcesDir.toString()
|
|
@@ -138,7 +155,6 @@ repositories {
|
|
|
138
155
|
}
|
|
139
156
|
|
|
140
157
|
logger.info(":${project.name}:reactNativeAndroidRoot ${androidSourcesDir.canonicalPath}")
|
|
141
|
-
found = true
|
|
142
158
|
}
|
|
143
159
|
})
|
|
144
160
|
}
|
|
@@ -160,17 +176,18 @@ dependencies {
|
|
|
160
176
|
//noinspection GradleDynamicVersion
|
|
161
177
|
extractJNI("com.facebook.fbjni:fbjni:+")
|
|
162
178
|
|
|
163
|
-
def rnAAR = fileTree("${
|
|
179
|
+
def rnAAR = fileTree("${defaultDir.toString()}").matching({ it.include "**/**/*.aar" }).singleFile
|
|
164
180
|
extractJNI(files(rnAAR))
|
|
165
181
|
}
|
|
166
182
|
|
|
167
|
-
|
|
168
183
|
// third-party-ndk deps headers
|
|
169
184
|
// mostly a copy of https://github.com/software-mansion/react-native-reanimated/blob/master/android/build.gradle#L115
|
|
170
185
|
|
|
186
|
+
|
|
187
|
+
|
|
171
188
|
def downloadsDir = new File("$buildDir/downloads")
|
|
172
189
|
def thirdPartyNdkDir = new File("$buildDir/third-party-ndk")
|
|
173
|
-
def thirdPartyVersionsFile = new File("${
|
|
190
|
+
def thirdPartyVersionsFile = new File("${androidSourcesDir.toString()}/ReactAndroid/gradle.properties")
|
|
174
191
|
def thirdPartyVersions = new Properties()
|
|
175
192
|
thirdPartyVersions.load(new FileInputStream(thirdPartyVersionsFile))
|
|
176
193
|
|
|
@@ -330,7 +347,7 @@ task extractJNIFiles {
|
|
|
330
347
|
extractJNIFiles.mustRunAfter extractAARHeaders
|
|
331
348
|
|
|
332
349
|
tasks.whenTaskAdded { task ->
|
|
333
|
-
if (task.name
|
|
350
|
+
if (task.name.contains('externalNative') || task.name.contains('CMake')) {
|
|
334
351
|
task.dependsOn(extractAARHeaders)
|
|
335
352
|
task.dependsOn(extractJNIFiles)
|
|
336
353
|
task.dependsOn(prepareThirdPartyNdkHeaders)
|
package/lib/commonjs/MMKV.js.map
CHANGED
|
@@ -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":";;;;;;;AAAA;;;;AAqGA,MAAMA,uBAAuB,GAAG,IAAIC,GAAJ,EAAhC;AAEA;AACA;AACA;;AACO,MAAMC,IAAN,CAAoC;AAKzC;AACF;AACA;AACA;AACEC,EAAAA,WAAW,CAACC,aAAgC,GAAG;AAAEC,IAAAA,EAAE,EAAE;AAAN,GAApC,EAA4D;AAAA;;AAAA;;AAAA;;AACrE,QAAIC,MAAM,CAACC,qBAAP,IAAgC,IAApC,EAA0C;AACxC,YAAM,IAAIC,KAAJ,CACJ,0MADI,CAAN;AAGD;;AACD,SAAKH,EAAL,GAAUD,aAAa,CAACC,EAAxB;AACA,SAAKI,cAAL,GAAsBH,MAAM,CAACC,qBAAP,CAA6BH,aAA7B,CAAtB;AACA,SAAKM,aAAL,GAAqB,EAArB;AACD;;AAEkC,MAAvBV,uBAAuB,
|
|
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 */\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\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"]}
|
package/lib/commonjs/hooks.js
CHANGED
|
@@ -10,7 +10,7 @@ exports.useMMKVString = void 0;
|
|
|
10
10
|
|
|
11
11
|
var _react = require("react");
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _MMKV = require("./MMKV");
|
|
14
14
|
|
|
15
15
|
function isConfigurationEqual(left, right) {
|
|
16
16
|
return left.encryptionKey === right.encryptionKey && left.id === right.id && left.path === right.path;
|
|
@@ -20,7 +20,7 @@ let defaultInstance = null;
|
|
|
20
20
|
|
|
21
21
|
function getDefaultInstance() {
|
|
22
22
|
if (defaultInstance == null) {
|
|
23
|
-
defaultInstance = new
|
|
23
|
+
defaultInstance = new _MMKV.MMKV();
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
return defaultInstance;
|
|
@@ -28,10 +28,11 @@ function getDefaultInstance() {
|
|
|
28
28
|
|
|
29
29
|
function useMMKV(configuration) {
|
|
30
30
|
const instance = (0, _react.useRef)();
|
|
31
|
-
const lastConfiguration = (0, _react.useRef)(
|
|
31
|
+
const lastConfiguration = (0, _react.useRef)();
|
|
32
32
|
|
|
33
|
-
if (!isConfigurationEqual(lastConfiguration.current, configuration)) {
|
|
34
|
-
|
|
33
|
+
if (lastConfiguration.current == null || !isConfigurationEqual(lastConfiguration.current, configuration)) {
|
|
34
|
+
lastConfiguration.current = configuration;
|
|
35
|
+
instance.current = new _MMKV.MMKV(configuration);
|
|
35
36
|
} // @ts-expect-error it's not null, I promise.
|
|
36
37
|
|
|
37
38
|
|
|
@@ -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(
|
|
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
|
|
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":";;;;;;;;;;AAAA;;AAOA;;AAEA,SAASA,oBAAT,CACEC,IADF,EAEEC,KAFF,EAGW;AACT,SACED,IAAI,CAACE,aAAL,KAAuBD,KAAK,CAACC,aAA7B,IACAF,IAAI,CAACG,EAAL,KAAYF,KAAK,CAACE,EADlB,IAEAH,IAAI,CAACI,IAAL,KAAcH,KAAK,CAACG,IAHtB;AAKD;;AAED,IAAIC,
|
|
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"]}
|
package/lib/module/MMKV.js.map
CHANGED
|
@@ -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":";;AAAA,SAASA,uBAAT,QAAwC,cAAxC;AAqGA,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,QAAIC,MAAM,CAACC,qBAAP,IAAgC,IAApC,EAA0C;AACxC,YAAM,IAAIC,KAAJ,CACJ,0MADI,CAAN;AAGD;;AACD,SAAKH,EAAL,GAAUD,aAAa,CAACC,EAAxB;AACA,SAAKI,cAAL,GAAsBH,MAAM,CAACC,qBAAP,CAA6BH,aAA7B,CAAtB;AACA,SAAKM,aAAL,GAAqB,EAArB;AACD;;AAEkC,MAAvBV,uBAAuB,
|
|
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":";;AAAA,SAASA,uBAAT,QAAwC,cAAxC;AAqGA,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,QAAIC,MAAM,CAACC,qBAAP,IAAgC,IAApC,EAA0C;AACxC,YAAM,IAAIC,KAAJ,CACJ,0MADI,CAAN;AAGD;;AACD,SAAKH,EAAL,GAAUD,aAAa,CAACC,EAAxB;AACA,SAAKI,cAAL,GAAsBH,MAAM,CAACC,qBAAP,CAA6BH,aAA7B,CAAtB;AACA,SAAKM,aAAL,GAAqB,EAArB;AACD;;AAEkC,MAAvBV,uBAAuB,GAAG;AACpC,QAAI,CAACA,uBAAuB,CAACW,GAAxB,CAA4B,KAAKN,EAAjC,CAAL,EAA2C;AACzCL,MAAAA,uBAAuB,CAACY,GAAxB,CAA4B,KAAKP,EAAjC,EAAqC,EAArC;AACD;;AACD,WAAOL,uBAAuB,CAACa,GAAxB,CAA4B,KAAKR,EAAjC,CAAP;AACD;;AAEOS,EAAAA,oBAAoB,CAC1BC,YAD0B,EAER;AAClB,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,KAAKjB,uBAAL,CAA6BkB,MAA7B,KAAwC,CAA5C,EAA+C;AAE/CC,IAAAA,YAAY,CAAC,MAAM;AACjBpB,MAAAA,uBAAuB,CAAC,MAAM;AAC5B,aAAK,MAAMqB,GAAX,IAAkBH,IAAlB,EAAwB;AACtB,eAAK,MAAMI,QAAX,IAAuB,KAAKrB,uBAA5B,EAAqD;AACnDqB,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,SAAKhC,uBAAL,CAA6BiC,IAA7B,CAAkCD,cAAlC;AAEA,WAAO;AACLE,MAAAA,MAAM,EAAE,MAAM;AACZ,cAAMC,KAAK,GAAG,KAAKnC,uBAAL,CAA6BoC,OAA7B,CAAqCJ,cAArC,CAAd;;AACA,YAAIG,KAAK,KAAK,CAAC,CAAf,EAAkB;AAChB,eAAKnC,uBAAL,CAA6BqC,MAA7B,CAAoCF,KAApC,EAA2C,CAA3C;AACD;AACF;AANI,KAAP;AAQD;;AArGwC","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 */\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\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"]}
|
package/lib/module/hooks.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useRef, useState, useMemo, useCallback, useEffect } from 'react';
|
|
2
|
-
import { MMKV } from '
|
|
2
|
+
import { MMKV } from './MMKV';
|
|
3
3
|
|
|
4
4
|
function isConfigurationEqual(left, right) {
|
|
5
5
|
return left.encryptionKey === right.encryptionKey && left.id === right.id && left.path === right.path;
|
|
@@ -17,9 +17,10 @@ function getDefaultInstance() {
|
|
|
17
17
|
|
|
18
18
|
export function useMMKV(configuration) {
|
|
19
19
|
const instance = useRef();
|
|
20
|
-
const lastConfiguration = useRef(
|
|
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(
|
|
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
|
|
54
|
+
}, [key, mmkv]);
|
|
52
55
|
useEffect(() => {
|
|
53
56
|
const listener = mmkv.addOnValueChangedListener(changedKey => {
|
|
54
57
|
if (changedKey === key) {
|
package/lib/module/hooks.js.map
CHANGED
|
@@ -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":"AAAA,SACEA,MADF,EAEEC,QAFF,EAGEC,OAHF,EAIEC,WAJF,EAKEC,SALF,QAMO,OANP;AAOA,SAASC,IAAT,
|
|
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"]}
|
package/lib/typescript/MMKV.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
export declare function useMMKV(configuration: MMKVConfiguration): React.RefObject<
|
|
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?:
|
|
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?:
|
|
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?:
|
|
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?:
|
|
49
|
+
export declare function useMMKVObject<T>(key: string, instance?: MMKV): [value: T | undefined, setValue: (value: T) => void];
|
package/package.json
CHANGED
|
@@ -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
|