UNPKG

react-native-mmkv

Version:

The fastest key/value storage for React Native. ~30x faster than AsyncStorage! Works on Android, iOS and Web.

198 lines (189 loc) 6.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useMMKV = useMMKV; exports.useMMKVBuffer = exports.useMMKVBoolean = void 0; exports.useMMKVListener = useMMKVListener; exports.useMMKVNumber = void 0; exports.useMMKVObject = useMMKVObject; exports.useMMKVString = void 0; var _react = require("react"); var _MMKV = require("./MMKV"); function isConfigurationEqual(left, right) { if (left == null || right == null) return left == null && right == null; return left.encryptionKey === right.encryptionKey && left.id === right.id && left.path === right.path && left.mode === right.mode; } let defaultInstance = null; function getDefaultInstance() { if (defaultInstance == null) { defaultInstance = new _MMKV.MMKV(); } return defaultInstance; } /** * Use the default, shared MMKV instance. */ /** * Use a custom MMKV instance with the given configuration. * @param configuration The configuration to initialize the MMKV instance with. Does not have to be memoized. */ function useMMKV(configuration) { const instance = (0, _react.useRef)(); const lastConfiguration = (0, _react.useRef)(); if (configuration == null) return getDefaultInstance(); if (instance.current == null || !isConfigurationEqual(lastConfiguration.current, configuration)) { lastConfiguration.current = configuration; instance.current = new _MMKV.MMKV(configuration); } return instance.current; } function createMMKVHook(getter) { return (key, instance) => { const mmkv = instance ?? getDefaultInstance(); const [bump, setBump] = (0, _react.useState)(0); const value = (0, _react.useMemo)(() => { // bump is here as an additional outside dependency, so this useMemo // re-computes the value each time bump changes, effectively acting as a hint // that the outside value (storage) has changed. setting bump refreshes this value. bump; return getter(mmkv, key); }, [mmkv, key, bump]); // update value by user set const set = (0, _react.useCallback)(v => { const newValue = typeof v === 'function' ? v(getter(mmkv, key)) : v; switch (typeof newValue) { case 'number': case 'string': case 'boolean': mmkv.set(key, newValue); break; case 'undefined': mmkv.delete(key); break; case 'object': if (newValue instanceof ArrayBuffer) { mmkv.set(key, newValue); break; } else { throw new Error(`MMKV: Type object (${newValue}) is not supported!`); } default: throw new Error(`MMKV: Type ${typeof newValue} is not supported!`); } }, [key, mmkv]); // update value if it changes somewhere else (second hook, same key) (0, _react.useEffect)(() => { const listener = mmkv.addOnValueChangedListener(changedKey => { if (changedKey === key) { setBump(b => b + 1); } }); return () => listener.remove(); }, [key, mmkv]); return [value, set]; }; } /** * Use the string value of the given `key` from the given MMKV storage instance. * * If no instance is provided, a shared default instance will be used. * * @example * ```ts * const [username, setUsername] = useMMKVString("user.name") * ``` */ const useMMKVString = exports.useMMKVString = createMMKVHook((instance, key) => instance.getString(key)); /** * Use the number value of the given `key` from the given MMKV storage instance. * * If no instance is provided, a shared default instance will be used. * * @example * ```ts * const [age, setAge] = useMMKVNumber("user.age") * ``` */ const useMMKVNumber = exports.useMMKVNumber = createMMKVHook((instance, key) => instance.getNumber(key)); /** * Use the boolean value of the given `key` from the given MMKV storage instance. * * If no instance is provided, a shared default instance will be used. * * @example * ```ts * const [isPremiumAccount, setIsPremiumAccount] = useMMKVBoolean("user.isPremium") * ``` */ const useMMKVBoolean = exports.useMMKVBoolean = createMMKVHook((instance, key) => instance.getBoolean(key)); /** * Use the buffer value (unsigned 8-bit (0-255)) of the given `key` from the given MMKV storage instance. * * If no instance is provided, a shared default instance will be used. * * @example * ```ts * const [privateKey, setPrivateKey] = useMMKVBuffer("user.privateKey") * ``` */ const useMMKVBuffer = exports.useMMKVBuffer = createMMKVHook((instance, key) => instance.getBuffer(key)); /** * Use an object value of the given `key` from the given MMKV storage instance. * * If no instance is provided, a shared default instance will be used. * * The object will be serialized using `JSON`. * * @example * ```ts * const [user, setUser] = useMMKVObject<User>("user") * ``` */ function useMMKVObject(key, instance) { const [json, setJson] = useMMKVString(key, instance); const value = (0, _react.useMemo)(() => { if (json == null) return undefined; return JSON.parse(json); }, [json]); const setValue = (0, _react.useCallback)(v => { if (v instanceof Function) { setJson(currentJson => { const currentValue = currentJson != null ? JSON.parse(currentJson) : undefined; const newValue = v(currentValue); // Store the Object as a serialized Value or clear the value return newValue != null ? JSON.stringify(newValue) : undefined; }); } else { // Store the Object as a serialized Value or clear the value const newValue = v != null ? JSON.stringify(v) : undefined; setJson(newValue); } }, [setJson]); return [value, setValue]; } /** * Listen for changes in the given MMKV storage instance. * If no instance is passed, the default instance will be used. * @param valueChangedListener The function to call whenever a value inside the storage instance changes * @param instance The instance to listen to changes to (or the default instance) * * @example * ```ts * useMMKVListener((key) => { * console.log(`Value for "${key}" changed!`) * }) * ``` */ function useMMKVListener(valueChangedListener, instance) { const ref = (0, _react.useRef)(valueChangedListener); ref.current = valueChangedListener; const mmkv = instance ?? getDefaultInstance(); (0, _react.useEffect)(() => { const listener = mmkv.addOnValueChangedListener(changedKey => { ref.current(changedKey); }); return () => listener.remove(); }, [mmkv]); } //# sourceMappingURL=hooks.js.map