react-store-context-hooks
Version:
Provides various data store hooks that allow functional components to share the application state within the same React Context or different React Context using persistent storage.
4 lines (3 loc) • 4.48 kB
JavaScript
/*! react-store-context-hooks v4.0.0 | (c) Richard Huang <rickypc@users.noreply.github.com> | MPL-2.0 */
Object.defineProperty(exports,"__esModule",{value:true});var react=require("react");var jsxRuntime=require("react/jsx-runtime");const parseJson=(text,defaultValue)=>{let value;try{value=JSON.parse(text)}catch(_){}return value===undefined?defaultValue:value};const storage={get:(persistence,key,defaultValue)=>{if(!(persistence instanceof Storage)){return defaultValue}return parseJson(persistence.getItem(key)||"undefined",defaultValue)},remove:(persistence,key)=>{if(persistence instanceof Storage&&persistence.getItem(key)!==null){persistence.removeItem(key);return true}return false},set:(persistence,key,value)=>{if(persistence instanceof Storage){const val=JSON.stringify(value);if(persistence.getItem(key)!==val){persistence.setItem(key,val);return true}}return false},sets:(persistence,data)=>{const name=persistence===localStorage?"local":"session";Object.entries(data).forEach((([key,value])=>{if(storage.set(persistence,key,value)){document.dispatchEvent(new CustomEvent(`${name}Storage.setItem`,{detail:{key:key,value:value}}))}}))}};const createStore=()=>{const[store,setStore]=react.useState({});return{get(key,defaultValue,persistence){const value=store[key];return value===undefined?storage.get(persistence,key,defaultValue):value},remove:(key,persistence)=>setStore((prev=>{const removed=storage.remove(persistence,key);if(removed||key in prev){const{[key]:val,...next}=prev;return{...next}}return prev})),set:(key,value,persistence)=>setStore((prev=>{if(prev[key]!==value){storage.set(persistence,key,value);return{...prev,[key]:value}}return prev})),sets:(data,persistence)=>setStore((prev=>{let changes=false;const next=Object.entries(data).filter((([key,value])=>prev[key]!==value)).reduce(((accumulator,[key,value])=>{storage.set(persistence,key,value);accumulator[key]=value;changes=true;return accumulator}),prev);return changes?{...next}:prev}))}};const isEmpty=value=>value==null||typeof value==="object"&&Object.keys(value).length===0||typeof value==="string"&&value.trim().length===0||["boolean","number"].includes(typeof value)&&!value;const StoreContext=react.createContext({});const useStorageStore=(persistence,key,defaultValue)=>{const name=persistence===localStorage?"local":"session";const[val,set]=react.useState(storage.get(persistence,key,defaultValue));react.useEffect((()=>{const removeItem=e=>{if(e.detail.key===key){set(undefined)}};const setItem=e=>{if(e.detail.key===key){set(e.detail.value)}};document.addEventListener(`${name}Storage.removeItem`,removeItem);document.addEventListener(`${name}Storage.setItem`,setItem);return()=>{document.removeEventListener(`${name}Storage.removeItem`,removeItem);document.removeEventListener(`${name}Storage.setItem`,setItem)}}),[]);return[val,react.useCallback((value=>{if(storage.set(persistence,key,value)){document.dispatchEvent(new CustomEvent(`${name}Storage.setItem`,{detail:{key:key,value:value}}))}}),[]),react.useCallback((()=>{if(storage.remove(persistence,key)){document.dispatchEvent(new CustomEvent(`${name}Storage.removeItem`,{detail:{key:key}}))}}),[])]};const useStorageStores=persistence=>({setStores:react.useCallback((data=>storage.sets(persistence,data)),[])});const useLocalStore=(key,defaultValue)=>useStorageStore(localStorage,key,defaultValue);const useLocalStores=()=>useStorageStores(localStorage);const useSessionStore=(key,defaultValue)=>useStorageStore(sessionStorage,key,defaultValue);const useSessionStores=()=>useStorageStores(sessionStorage);const useStore=(key,defaultValue,persistence)=>{const store=react.useContext(StoreContext);return[store.get(key,defaultValue,persistence),react.useCallback((value=>store.set(key,value,persistence)),[store]),react.useCallback((()=>store.remove(key,persistence)),[store])]};const useStores=persistence=>{const store=react.useContext(StoreContext);return{setStores:react.useCallback((data=>store.sets(data,persistence)),[store])}};const withStore=Component=>{const ComponentWithStore=props=>jsxRuntime.jsx(StoreContext.Provider,{value:createStore(),children:jsxRuntime.jsx(Component,{...props})});return ComponentWithStore};exports.isEmpty=isEmpty;exports.useLocalStore=useLocalStore;exports.useLocalStores=useLocalStores;exports.useSessionStore=useSessionStore;exports.useSessionStores=useSessionStores;exports.useStore=useStore;exports.useStores=useStores;exports.withStore=withStore;
//# sourceMappingURL=index.cjs.js.map