react-global-state-hooks 16.0.4 → 16.0.5

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/GlobalStore.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var F=Object.create;var g=Object.defineProperty,V=Object.defineProperties,w=Object.getOwnPropertyDescriptor,W=Object.getOwnPropertyDescriptors,B=Object.getOwnPropertyNames,A=Object.getOwnPropertySymbols,G=Object.getPrototypeOf,C=Object.prototype.hasOwnProperty,L=Object.prototype.propertyIsEnumerable;var v=(o,a,t)=>a in o?g(o,a,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[a]=t,u=(o,a)=>{for(var t in a||(a={}))C.call(a,t)&&v(o,t,a[t]);if(A)for(var t of A(a))L.call(a,t)&&v(o,t,a[t]);return o},k=(o,a)=>V(o,W(a));var R=(o,a)=>{for(var t in a)g(o,t,{get:a[t],enumerable:!0})},E=(o,a,t,e)=>{if(a&&typeof a=="object"||typeof a=="function")for(let r of B(a))!C.call(o,r)&&r!==t&&g(o,r,{get:()=>a[r],enumerable:!(e=w(a,r))||e.enumerable});return o};var l=(o,a,t)=>(t=o!=null?F(G(o)):{},E(a||!o||!o.__esModule?g(t,"default",{value:o,enumerable:!0}):t,o)),$=o=>E(g({},"__esModule",{value:!0}),o);var N={};R(N,{GlobalStore:()=>h,default:()=>z});module.exports=$(N);var M=l(require("react-hooks-global-states/GlobalStore")),c=l(require("./tryCatch.cjs")),T=l(require("json-storage-formatter/formatFromStore")),P=l(require("json-storage-formatter/formatToStore")),f=l(require("json-storage-formatter/isNil")),x=l(require("json-storage-formatter/isPrimitive"));var I=-1,h=class o extends M.default{constructor(t,e={metadata:{}}){var i;super(t,e);this.localStorage=null;this.onInit=()=>{let t=this.localStorage;if(!t||!this.isPersistStorageAvailable())return;let e=t.versioning,{result:r,error:i}=(0,c.default)(()=>{var p,y,b;if((p=t.adapter)!=null&&p.getItem)return{s:(y=t.adapter)==null?void 0:y.getItem(t.key),v:(b=e==null?void 0:e.version)!=null?b:I};let n=this.getStorageItem();return n&&t.selector&&!(0,x.default)(n==null?void 0:n.s)?k(u({},n),{s:u(u({},this.getState()),n.s)}):n});if(i){this.handleStorageError(i),this.updateStateWithValidation(this.getState());return}if(!r){this.updateStateWithValidation(this.getState());return}let s=r.v===(e==null?void 0:e.version),S=e==null?void 0:e.migrator;if(s||!S||t.adapter){this.updateStateWithValidation(r.s);return}let{result:d,error:m}=(0,c.default)(()=>S({legacy:r.s,initial:this.getState()},this.storeTools));if(!m){this.updateStateWithValidation(d);return}this.handleStorageError(m),this.updateStateWithValidation(this.getState())};this.onStateChanged=({state:t})=>{let e=this.localStorage;if(!e||!this.isPersistStorageAvailable())return;let{error:r}=(0,c.default)(()=>{var s;let i=(s=e.adapter)==null?void 0:s.setItem;if(i)return i(e.key,t);this.setStorageItem(t)});r&&this.handleStorageError(r)};this.localStorage=(i=e.localStorage)!=null?i:null,this.constructor===o&&this.initialize()}isPersistStorageAvailable(){var t;return!!((t=this.localStorage)!=null&&t.key&&(globalThis!=null&&globalThis.localStorage))}trySetStorageItem(t){let e=this.localStorage;if(!e)return;let{error:r}=(0,c.default)(()=>{var s;let i=(s=e.adapter)==null?void 0:s.setItem;if(!i)return this.setStorageItem(t);i(e.key,t)});r&&this.handleStorageError(r)}updateStateWithValidation(t){let e=this.localStorage;if(!e)return;let{result:r,error:i}=(0,c.default)(()=>{var s;return(s=e.validator)==null?void 0:s.call(e,{restored:t,initial:this.getState()},this.storeTools)});if(i){this.handleStorageError(i),this.trySetStorageItem(this.getState());return}if(r===void 0){if(t===void 0){this.trySetStorageItem(this.getState());return}this.setState(t),this.trySetStorageItem(t);return}this.setState(r),this.trySetStorageItem(r)}getStorageItem(){let t=globalThis.localStorage.getItem(this.localStorage.key),e=(0,f.default)(t)?null:(0,T.default)(t);return j(this.localStorage.key,e),e}setStorageItem(t){var i,s,S,d;let e={s:(i=this.localStorage)!=null&&i.selector?this.localStorage.selector(t):t,v:(d=(S=(s=this.localStorage)==null?void 0:s.versioning)==null?void 0:S.version)!=null?d:I},r=(0,P.default)(e);globalThis.localStorage.setItem(this.localStorage.key,r)}reset(...t){this.isPersistStorageAvailable()&&t.length===0&&globalThis.localStorage.removeItem(this.localStorage.key),super.reset(...t)}handleStorageError(t){var e,r;if((e=this.localStorage)!=null&&e.onError)return this.localStorage.onError(t,this.storeTools);globalThis.console.error([`[react-global-state-hooks]
1
+ "use strict";var F=Object.create;var g=Object.defineProperty,V=Object.defineProperties,w=Object.getOwnPropertyDescriptor,G=Object.getOwnPropertyDescriptors,W=Object.getOwnPropertyNames,A=Object.getOwnPropertySymbols,B=Object.getPrototypeOf,C=Object.prototype.hasOwnProperty,L=Object.prototype.propertyIsEnumerable;var v=(o,a,t)=>a in o?g(o,a,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[a]=t,u=(o,a)=>{for(var t in a||(a={}))C.call(a,t)&&v(o,t,a[t]);if(A)for(var t of A(a))L.call(a,t)&&v(o,t,a[t]);return o},k=(o,a)=>V(o,G(a));var R=(o,a)=>{for(var t in a)g(o,t,{get:a[t],enumerable:!0})},E=(o,a,t,e)=>{if(a&&typeof a=="object"||typeof a=="function")for(let r of W(a))!C.call(o,r)&&r!==t&&g(o,r,{get:()=>a[r],enumerable:!(e=w(a,r))||e.enumerable});return o};var l=(o,a,t)=>(t=o!=null?F(B(o)):{},E(a||!o||!o.__esModule?g(t,"default",{value:o,enumerable:!0}):t,o)),$=o=>E(g({},"__esModule",{value:!0}),o);var N={};R(N,{GlobalStore:()=>h,default:()=>z});module.exports=$(N);var M=l(require("react-hooks-global-states/GlobalStore")),c=l(require("./tryCatch.cjs")),T=l(require("json-storage-formatter/formatFromStore")),P=l(require("json-storage-formatter/formatToStore")),f=l(require("json-storage-formatter/isNil")),x=l(require("json-storage-formatter/isPrimitive"));var I=-1,h=class o extends M.default{constructor(t,e={metadata:{}}){var i;super(t,e);this.localStorage=null;this.onInit=()=>{let t=this.localStorage;if(!t||!this.isPersistStorageAvailable())return;let e=t.versioning,{result:r,error:i}=(0,c.default)(()=>{var p,y,b;if((p=t.adapter)!=null&&p.getItem)return{s:(y=t.adapter)==null?void 0:y.getItem(t.key),v:(b=e==null?void 0:e.version)!=null?b:I};let n=this.getStorageItem();return n&&t.selector&&!(0,x.default)(n==null?void 0:n.s)?k(u({},n),{s:u(u({},this.getState()),n.s)}):n});if(i){this.handleStorageError(i),this.updateStateWithValidation(this.getState());return}if(!r){this.updateStateWithValidation(this.getState());return}let s=r.v===(e==null?void 0:e.version),S=e==null?void 0:e.migrator;if(s||!S||t.adapter){this.updateStateWithValidation(r.s);return}let{result:d,error:m}=(0,c.default)(()=>S({legacy:r.s,initial:this.getState()},this.storeTools));if(!m){this.updateStateWithValidation(d);return}this.handleStorageError(m),this.updateStateWithValidation(this.getState())};this.onStateChanged=({state:t})=>{let e=this.localStorage;if(!e||!this.isPersistStorageAvailable())return;let{error:r}=(0,c.default)(()=>{var s;let i=(s=e.adapter)==null?void 0:s.setItem;if(i)return i(e.key,t);this.setStorageItem(t)});r&&this.handleStorageError(r)};this.localStorage=(i=e.localStorage)!=null?i:null,this.constructor===o&&this.initialize()}isPersistStorageAvailable(){var t;return!!((t=this.localStorage)!=null&&t.key&&(globalThis!=null&&globalThis.localStorage))}trySetStorageItem(t){let e=this.localStorage;if(!e)return;let{error:r}=(0,c.default)(()=>{var s;let i=(s=e.adapter)==null?void 0:s.setItem;if(!i)return this.setStorageItem(t);i(e.key,t)});r&&this.handleStorageError(r)}updateStateWithValidation(t){let e=this.localStorage;if(!e)return;let{result:r,error:i}=(0,c.default)(()=>{var s;return(s=e.validator)==null?void 0:s.call(e,{restored:t,initial:this.getState()},this.storeTools)});if(i){this.handleStorageError(i),this.trySetStorageItem(this.getState());return}if(r===void 0){if(t===void 0){this.trySetStorageItem(this.getState());return}this.setState(t),this.trySetStorageItem(t);return}this.setState(r),this.trySetStorageItem(r)}getStorageItem(){let t=globalThis.localStorage.getItem(this.localStorage.key),e=(0,f.default)(t)?null:(0,T.default)(t);return j(this.localStorage.key,e),e}setStorageItem(t){var i,s,S,d;let e={s:(i=this.localStorage)!=null&&i.selector?this.localStorage.selector(t):t,v:(d=(S=(s=this.localStorage)==null?void 0:s.versioning)==null?void 0:S.version)!=null?d:I},r=(0,P.default)(e);globalThis.localStorage.setItem(this.localStorage.key,r)}reset(...t){this.isPersistStorageAvailable()&&t.length===0&&globalThis.localStorage.removeItem(this.localStorage.key),super.reset(...t)}handleStorageError(t){var e,r;if((e=this.localStorage)!=null&&e.onError)return this.localStorage.onError(t,this.storeTools);globalThis.console.error([`[react-global-state-hooks]
2
2
  `," localStorage sync error:","[hook]:",` ${this._name}`,"[Localstorage Key]:",` ${(r=this.localStorage)==null?void 0:r.key}`,"[Error]:",` ${t!=null?t:"undefined"}
3
3
 
4
4
  `,"Stacktrace:"].join(`
package/GlobalStore.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var F=Object.create;var g=Object.defineProperty,V=Object.defineProperties,w=Object.getOwnPropertyDescriptor,W=Object.getOwnPropertyDescriptors,B=Object.getOwnPropertyNames,A=Object.getOwnPropertySymbols,G=Object.getPrototypeOf,C=Object.prototype.hasOwnProperty,L=Object.prototype.propertyIsEnumerable;var v=(o,a,t)=>a in o?g(o,a,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[a]=t,u=(o,a)=>{for(var t in a||(a={}))C.call(a,t)&&v(o,t,a[t]);if(A)for(var t of A(a))L.call(a,t)&&v(o,t,a[t]);return o},k=(o,a)=>V(o,W(a));var R=(o,a)=>{for(var t in a)g(o,t,{get:a[t],enumerable:!0})},E=(o,a,t,e)=>{if(a&&typeof a=="object"||typeof a=="function")for(let r of B(a))!C.call(o,r)&&r!==t&&g(o,r,{get:()=>a[r],enumerable:!(e=w(a,r))||e.enumerable});return o};var l=(o,a,t)=>(t=o!=null?F(G(o)):{},E(a||!o||!o.__esModule?g(t,"default",{value:o,enumerable:!0}):t,o)),$=o=>E(g({},"__esModule",{value:!0}),o);var N={};R(N,{GlobalStore:()=>h,default:()=>z});module.exports=$(N);var M=l(require("react-hooks-global-states/GlobalStore")),c=l(require("./tryCatch.js")),T=l(require("json-storage-formatter/formatFromStore")),P=l(require("json-storage-formatter/formatToStore")),f=l(require("json-storage-formatter/isNil")),x=l(require("json-storage-formatter/isPrimitive"));var I=-1,h=class o extends M.default{constructor(t,e={metadata:{}}){var i;super(t,e);this.localStorage=null;this.onInit=()=>{let t=this.localStorage;if(!t||!this.isPersistStorageAvailable())return;let e=t.versioning,{result:r,error:i}=(0,c.default)(()=>{var p,y,b;if((p=t.adapter)!=null&&p.getItem)return{s:(y=t.adapter)==null?void 0:y.getItem(t.key),v:(b=e==null?void 0:e.version)!=null?b:I};let n=this.getStorageItem();return n&&t.selector&&!(0,x.default)(n==null?void 0:n.s)?k(u({},n),{s:u(u({},this.getState()),n.s)}):n});if(i){this.handleStorageError(i),this.updateStateWithValidation(this.getState());return}if(!r){this.updateStateWithValidation(this.getState());return}let s=r.v===(e==null?void 0:e.version),S=e==null?void 0:e.migrator;if(s||!S||t.adapter){this.updateStateWithValidation(r.s);return}let{result:d,error:m}=(0,c.default)(()=>S({legacy:r.s,initial:this.getState()},this.storeTools));if(!m){this.updateStateWithValidation(d);return}this.handleStorageError(m),this.updateStateWithValidation(this.getState())};this.onStateChanged=({state:t})=>{let e=this.localStorage;if(!e||!this.isPersistStorageAvailable())return;let{error:r}=(0,c.default)(()=>{var s;let i=(s=e.adapter)==null?void 0:s.setItem;if(i)return i(e.key,t);this.setStorageItem(t)});r&&this.handleStorageError(r)};this.localStorage=(i=e.localStorage)!=null?i:null,this.constructor===o&&this.initialize()}isPersistStorageAvailable(){var t;return!!((t=this.localStorage)!=null&&t.key&&(globalThis!=null&&globalThis.localStorage))}trySetStorageItem(t){let e=this.localStorage;if(!e)return;let{error:r}=(0,c.default)(()=>{var s;let i=(s=e.adapter)==null?void 0:s.setItem;if(!i)return this.setStorageItem(t);i(e.key,t)});r&&this.handleStorageError(r)}updateStateWithValidation(t){let e=this.localStorage;if(!e)return;let{result:r,error:i}=(0,c.default)(()=>{var s;return(s=e.validator)==null?void 0:s.call(e,{restored:t,initial:this.getState()},this.storeTools)});if(i){this.handleStorageError(i),this.trySetStorageItem(this.getState());return}if(r===void 0){if(t===void 0){this.trySetStorageItem(this.getState());return}this.setState(t),this.trySetStorageItem(t);return}this.setState(r),this.trySetStorageItem(r)}getStorageItem(){let t=globalThis.localStorage.getItem(this.localStorage.key),e=(0,f.default)(t)?null:(0,T.default)(t);return j(this.localStorage.key,e),e}setStorageItem(t){var i,s,S,d;let e={s:(i=this.localStorage)!=null&&i.selector?this.localStorage.selector(t):t,v:(d=(S=(s=this.localStorage)==null?void 0:s.versioning)==null?void 0:S.version)!=null?d:I},r=(0,P.default)(e);globalThis.localStorage.setItem(this.localStorage.key,r)}reset(...t){this.isPersistStorageAvailable()&&t.length===0&&globalThis.localStorage.removeItem(this.localStorage.key),super.reset(...t)}handleStorageError(t){var e,r;if((e=this.localStorage)!=null&&e.onError)return this.localStorage.onError(t,this.storeTools);globalThis.console.error([`[react-global-state-hooks]
1
+ "use strict";var F=Object.create;var g=Object.defineProperty,V=Object.defineProperties,w=Object.getOwnPropertyDescriptor,G=Object.getOwnPropertyDescriptors,W=Object.getOwnPropertyNames,A=Object.getOwnPropertySymbols,B=Object.getPrototypeOf,C=Object.prototype.hasOwnProperty,L=Object.prototype.propertyIsEnumerable;var v=(o,a,t)=>a in o?g(o,a,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[a]=t,u=(o,a)=>{for(var t in a||(a={}))C.call(a,t)&&v(o,t,a[t]);if(A)for(var t of A(a))L.call(a,t)&&v(o,t,a[t]);return o},k=(o,a)=>V(o,G(a));var R=(o,a)=>{for(var t in a)g(o,t,{get:a[t],enumerable:!0})},E=(o,a,t,e)=>{if(a&&typeof a=="object"||typeof a=="function")for(let r of W(a))!C.call(o,r)&&r!==t&&g(o,r,{get:()=>a[r],enumerable:!(e=w(a,r))||e.enumerable});return o};var l=(o,a,t)=>(t=o!=null?F(B(o)):{},E(a||!o||!o.__esModule?g(t,"default",{value:o,enumerable:!0}):t,o)),$=o=>E(g({},"__esModule",{value:!0}),o);var N={};R(N,{GlobalStore:()=>h,default:()=>z});module.exports=$(N);var M=l(require("react-hooks-global-states/GlobalStore")),c=l(require("./tryCatch.js")),T=l(require("json-storage-formatter/formatFromStore")),P=l(require("json-storage-formatter/formatToStore")),f=l(require("json-storage-formatter/isNil")),x=l(require("json-storage-formatter/isPrimitive"));var I=-1,h=class o extends M.default{constructor(t,e={metadata:{}}){var i;super(t,e);this.localStorage=null;this.onInit=()=>{let t=this.localStorage;if(!t||!this.isPersistStorageAvailable())return;let e=t.versioning,{result:r,error:i}=(0,c.default)(()=>{var p,y,b;if((p=t.adapter)!=null&&p.getItem)return{s:(y=t.adapter)==null?void 0:y.getItem(t.key),v:(b=e==null?void 0:e.version)!=null?b:I};let n=this.getStorageItem();return n&&t.selector&&!(0,x.default)(n==null?void 0:n.s)?k(u({},n),{s:u(u({},this.getState()),n.s)}):n});if(i){this.handleStorageError(i),this.updateStateWithValidation(this.getState());return}if(!r){this.updateStateWithValidation(this.getState());return}let s=r.v===(e==null?void 0:e.version),S=e==null?void 0:e.migrator;if(s||!S||t.adapter){this.updateStateWithValidation(r.s);return}let{result:d,error:m}=(0,c.default)(()=>S({legacy:r.s,initial:this.getState()},this.storeTools));if(!m){this.updateStateWithValidation(d);return}this.handleStorageError(m),this.updateStateWithValidation(this.getState())};this.onStateChanged=({state:t})=>{let e=this.localStorage;if(!e||!this.isPersistStorageAvailable())return;let{error:r}=(0,c.default)(()=>{var s;let i=(s=e.adapter)==null?void 0:s.setItem;if(i)return i(e.key,t);this.setStorageItem(t)});r&&this.handleStorageError(r)};this.localStorage=(i=e.localStorage)!=null?i:null,this.constructor===o&&this.initialize()}isPersistStorageAvailable(){var t;return!!((t=this.localStorage)!=null&&t.key&&(globalThis!=null&&globalThis.localStorage))}trySetStorageItem(t){let e=this.localStorage;if(!e)return;let{error:r}=(0,c.default)(()=>{var s;let i=(s=e.adapter)==null?void 0:s.setItem;if(!i)return this.setStorageItem(t);i(e.key,t)});r&&this.handleStorageError(r)}updateStateWithValidation(t){let e=this.localStorage;if(!e)return;let{result:r,error:i}=(0,c.default)(()=>{var s;return(s=e.validator)==null?void 0:s.call(e,{restored:t,initial:this.getState()},this.storeTools)});if(i){this.handleStorageError(i),this.trySetStorageItem(this.getState());return}if(r===void 0){if(t===void 0){this.trySetStorageItem(this.getState());return}this.setState(t),this.trySetStorageItem(t);return}this.setState(r),this.trySetStorageItem(r)}getStorageItem(){let t=globalThis.localStorage.getItem(this.localStorage.key),e=(0,f.default)(t)?null:(0,T.default)(t);return j(this.localStorage.key,e),e}setStorageItem(t){var i,s,S,d;let e={s:(i=this.localStorage)!=null&&i.selector?this.localStorage.selector(t):t,v:(d=(S=(s=this.localStorage)==null?void 0:s.versioning)==null?void 0:S.version)!=null?d:I},r=(0,P.default)(e);globalThis.localStorage.setItem(this.localStorage.key,r)}reset(...t){this.isPersistStorageAvailable()&&t.length===0&&globalThis.localStorage.removeItem(this.localStorage.key),super.reset(...t)}handleStorageError(t){var e,r;if((e=this.localStorage)!=null&&e.onError)return this.localStorage.onError(t,this.storeTools);globalThis.console.error([`[react-global-state-hooks]
2
2
  `," localStorage sync error:","[hook]:",` ${this._name}`,"[Localstorage Key]:",` ${(r=this.localStorage)==null?void 0:r.key}`,"[Error]:",` ${t!=null?t:"undefined"}
3
3
 
4
4
  `,"Stacktrace:"].join(`
package/README.md CHANGED
@@ -2,21 +2,21 @@
2
2
 
3
3
  <div align="center">
4
4
 
5
- ![Image John Avatar](https://raw.githubusercontent.com/johnny-quesada-developer/global-hooks-example/main/public/avatar2.jpeg)
5
+ ![Johnny Quesada](https://raw.githubusercontent.com/johnny-quesada-developer/global-hooks-example/main/public/avatar2.jpeg)
6
6
 
7
7
  </div>
8
8
 
9
9
  <div align="center">
10
10
 
11
- **Zero setup. Zero complexity. Maximum performance.** 🚀
11
+ **Shared React state. Precise subscriptions. Built-in DevTools.** 🚀
12
12
 
13
- _One line of code. Infinite possibilities._
13
+ _The familiarity of `useState`, with the power of a shared store._
14
14
 
15
15
  [![npm version](https://img.shields.io/npm/v/react-global-state-hooks.svg)](https://www.npmjs.com/package/react-global-state-hooks)
16
16
  [![Downloads](https://img.shields.io/npm/dm/react-global-state-hooks.svg)](https://www.npmjs.com/package/react-global-state-hooks)
17
- [![License](https://img.shields.io/npm/l/react-global-state-hooks.svg)](https://github.com/johnny-quesada-developer/react-global-state-hooks/blob/main/LICENSE)
17
+ [![License](https://img.shields.io/npm/l/react-global-state-hooks.svg)](https://github.com/johnny-quesada-developer/react-global-state-hooks/blob/master/LICENSE)
18
18
 
19
- [**Live Demo**](https://johnny-quesada-developer.github.io/global-hooks-example/) • [**Video Tutorial**](https://www.youtube.com/watch?v=1UBqXk2MH8I/) • [**CodePen**](https://codepen.io/johnnynabetes/pen/WNmeGwb?editors=0010)
19
+ [**Live Demo**](https://johnny-quesada-developer.github.io/global-hooks-example/) • [**Video Tutorial**](https://www.youtube.com/watch?v=1UBqXk2MH8I) • [**CodePen**](https://codepen.io/johnnynabetes/pen/WNmeGwb?editors=0010)
20
20
 
21
21
  </div>
22
22
 
@@ -30,7 +30,7 @@ import { createGlobalState } from 'react-global-state-hooks';
30
30
  export const useCounter = createGlobalState(0);
31
31
  ```
32
32
 
33
- **That's it.** No providers. No context boilerplate. No configuration files. Just pure, beautiful state management. 🎨
33
+ **That's it.** No providers. No context boilerplate. No configuration files. Shared state with a familiar React API.
34
34
 
35
35
  ```tsx
36
36
  // Use it anywhere, instantly
@@ -42,9 +42,9 @@ function Counter() {
42
42
 
43
43
  ---
44
44
 
45
- ## 🚀 Why Developers Love This Library
45
+ ## 🚀 Built for React applications
46
46
 
47
- ### 🎓 **Zero Learning Curve**
47
+ ### 🎓 **Familiar React API**
48
48
 
49
49
  ```tsx
50
50
  // If you know this...
@@ -54,9 +54,9 @@ const [state, setState] = useState(0);
54
54
  const [state, setState] = useGlobalState();
55
55
  ```
56
56
 
57
- ### ⚡ **Blazing Fast**
57
+ ### ⚡ **Precise subscriptions**
58
58
 
59
- Only components that care about a slice re-render. Surgical precision, maximum performance.
59
+ Subscribe to a slice so unrelated store changes do not trigger component updates.
60
60
 
61
61
  ```tsx
62
62
  // Only re-renders when name changes
@@ -66,7 +66,7 @@ const [name] = useStore((s) => s.user.name);
66
66
  ### 🔗 **Chainable Selectors**
67
67
 
68
68
  ```tsx
69
- const useUsers = store.createSelectorHook((s) => s.users);
69
+ const useUsers = useStore.createSelectorHook((s) => s.users);
70
70
  const useAdmins = useUsers.createSelectorHook((users) => users.filter((u) => u.isAdmin));
71
71
  ```
72
72
 
@@ -142,64 +142,53 @@ function ThemedComponent() {
142
142
  }
143
143
  ```
144
144
 
145
- ### 60 Seconds to Production-Ready
145
+ ### Async state with actions
146
+
147
+ Keep loading and error values in state so components update throughout the request.
146
148
 
147
149
  ```tsx
148
150
  import { createGlobalState } from 'react-global-state-hooks';
149
151
 
152
+ type User = { id: string; name: string };
153
+
150
154
  const useAuth = createGlobalState(
151
- { user: null, token: null },
155
+ () => ({ user: null as User | null, isLoading: false, error: null as string | null }),
152
156
  {
153
- // Non-reactive metadata
154
- metadata: { isLoading: false },
155
-
156
- // Persist to localStorage automatically!
157
- localStorage: {
158
- key: 'auth-token',
159
- },
160
-
161
- // Type-safe actions
162
157
  actions: {
163
- login(email, password) {
164
- return async ({ setState, setMetadata }) => {
165
- setMetadata({ isLoading: true });
158
+ login(authenticate: () => Promise<User>) {
159
+ return async ({ setState }) => {
160
+ setState((state) => ({ ...state, isLoading: true, error: null }));
166
161
  try {
167
- const { user, token } = await api.login(email, password);
168
- setState({ user, token });
169
- return { success: true };
162
+ const user = await authenticate();
163
+ setState({ user, isLoading: false, error: null });
170
164
  } catch (error) {
171
- return { success: false, error };
172
- } finally {
173
- setMetadata({ isLoading: false });
165
+ setState((state) => ({
166
+ ...state,
167
+ isLoading: false,
168
+ error: error instanceof Error ? error.message : 'Sign-in failed',
169
+ }));
174
170
  }
175
171
  };
176
172
  },
177
-
178
173
  logout() {
179
174
  return ({ setState }) => {
180
- setState({ user: null, token: null });
175
+ setState({ user: null, isLoading: false, error: null });
181
176
  };
182
177
  },
183
178
  },
184
179
  },
185
180
  );
186
181
 
187
- // Usage
188
- function LoginForm() {
189
- const [auth, actions] = useAuth();
190
- const { isLoading } = useAuth.getMetadata();
191
-
192
- const handleSubmit = async (e) => {
193
- e.preventDefault();
194
- const result = await actions.login(email, password);
195
- if (!result.success) toast.error(result.error);
196
- };
182
+ function LoginButton({ authenticate }: { authenticate: () => Promise<User> }) {
183
+ const [{ isLoading, error }, actions] = useAuth();
197
184
 
198
185
  return (
199
- <form onSubmit={handleSubmit}>
200
- {/* ... */}
201
- <button disabled={isLoading}>{isLoading ? 'Logging in...' : 'Login'}</button>
202
- </form>
186
+ <div>
187
+ <button disabled={isLoading} onClick={() => void actions.login(authenticate)}>
188
+ {isLoading ? 'Signing in' : 'Sign in'}
189
+ </button>
190
+ {error && <p role="alert">{error}</p>}
191
+ </div>
203
192
  );
204
193
  }
205
194
  ```
@@ -237,7 +226,7 @@ const useExpensiveState = createGlobalState(() => {
237
226
 
238
227
  #### 🎯 Surgical Re-renders with Selectors
239
228
 
240
- The secret sauce: components only re-render when _their specific slice_ changes!
229
+ Selectors keep components subscribed to the state they use.
241
230
 
242
231
  ```tsx
243
232
  const useStore = createGlobalState({
@@ -277,16 +266,16 @@ function NotificationCount() {
277
266
  }
278
267
  ```
279
268
 
280
- **Performance comparison:**
269
+ **Subscription behavior:**
281
270
 
282
- | Approach | Re-renders when ANY state changes? |
283
- | --------------- | ---------------------------------- |
284
- | Context (naive) | YES (performance killer) |
285
- | This library | NO (only selected slices) |
271
+ | Subscription | What triggers an update |
272
+ | --- | --- |
273
+ | `useStore()` | Any store value change |
274
+ | `useStore(selector)` | A change to the selected value |
286
275
 
287
276
  #### ⚡ Computed Values with Dependencies
288
277
 
289
- Derive values efficiently with automatic recomputation control! - selectors can depend on external state (like `useState`)!
278
+ Derive values from both store state and component-local values, with explicit dependencies.
290
279
 
291
280
  ```tsx
292
281
  const useStore = createGlobalState({
@@ -362,9 +351,9 @@ function AdvancedFiltered() {
362
351
  }
363
352
  ```
364
353
 
365
- #### 🔗 Reusable Selector Hooks (The Game Changer!)
354
+ #### 🔗 Reusable Selector Hooks
366
355
 
367
- Create hooks from hooks! Chain them! Compose them! This is where it gets fun! 🎉
356
+ Compose reusable selector hooks. Each hook returns its selected value directly.
368
357
 
369
358
  ```tsx
370
359
  const useStore = createGlobalState({
@@ -392,9 +381,9 @@ const useCurrentUser = useStore.createSelectorHook((state) => {
392
381
 
393
382
  // Now use them anywhere!
394
383
  function UserStats() {
395
- const [totalUsers] = useUsers();
396
- const [activeUsers] = useActiveUsers();
397
- const [activeAdmins] = useActiveAdmins();
384
+ const totalUsers = useUsers();
385
+ const activeUsers = useActiveUsers();
386
+ const activeAdmins = useActiveAdmins();
398
387
 
399
388
  return (
400
389
  <div>
@@ -406,19 +395,24 @@ function UserStats() {
406
395
  }
407
396
 
408
397
  function CurrentUserProfile() {
409
- const [user] = useCurrentUser();
398
+ const user = useCurrentUser();
410
399
  return <div>{user?.name}</div>;
411
400
  }
412
401
 
413
- // 🎯 Key insight: All these hooks share the SAME setState!
414
- function AnyComponent() {
415
- const [, setFromUsers] = useUsers();
416
- const [, setFromAdmins] = useActiveAdmins();
417
- const [, setFromStore] = useStore();
418
-
419
- console.log(setFromUsers === setFromAdmins); // true!
420
- console.log(setFromUsers === setFromStore); // true!
421
- console.log(setFromUsers === useStore.setState); // true!
402
+ // Selector hooks return values. Update the source store through its API.
403
+ function ActivateAll() {
404
+ return (
405
+ <button
406
+ onClick={() =>
407
+ useStore.setState((state) => ({
408
+ ...state,
409
+ users: state.users.map((user) => ({ ...user, active: true })),
410
+ }))
411
+ }
412
+ >
413
+ Activate all users
414
+ </button>
415
+ );
422
416
  }
423
417
  ```
424
418
 
@@ -575,7 +569,7 @@ const unsubscribe = useAuth.subscribe(
575
569
  );
576
570
  ```
577
571
 
578
- #### 🔭 Observable Fragments (RxJS-style)
572
+ #### 🔭 Observable Fragments
579
573
 
580
574
  Create observable slices of your state for reactive programming!
581
575
 
@@ -605,46 +599,23 @@ const doubledObservable = countObservable.createObservable((count) => count * 2)
605
599
 
606
600
  #### 📋 Metadata - Non-Reactive Side Info
607
601
 
608
- Store data that doesn't need to trigger re-renders!
602
+ Keep request counters and timestamps in metadata when they are read only by handlers or background work.
603
+ Put loading indicators and displayed errors in state so components subscribe to their changes.
609
604
 
610
605
  ```tsx
611
606
  const useStore = createGlobalState(
612
- { items: [] },
613
- {
614
- metadata: {
615
- isLoading: false,
616
- lastFetch: null,
617
- error: null,
618
- retryCount: 0,
619
- },
620
- },
607
+ { items: [] as string[] },
608
+ { metadata: { requests: 0, lastFetchedAt: null as number | null } },
621
609
  );
622
610
 
623
- // Metadata changes don't trigger re-renders!
624
- useStore.setMetadata({ isLoading: true });
625
-
626
- // But you can access it anytime
627
- const meta = useStore.getMetadata();
628
- console.log(meta.isLoading); // true
611
+ // Metadata is replaced, so preserve the fields you are not updating.
612
+ useStore.setMetadata((metadata) => ({ ...metadata, requests: metadata.requests + 1 }));
629
613
 
630
- // Perfect for loading states, error tracking, etc.
631
- async function fetchData() {
632
- useStore.setMetadata({ isLoading: true, error: null });
614
+ console.log(useStore.metadata.requests); // 1
633
615
 
634
- try {
635
- const items = await api.fetch();
636
- useStore.setState({ items });
637
- useStore.setMetadata({
638
- isLoading: false,
639
- lastFetch: new Date(),
640
- });
641
- } catch (error) {
642
- useStore.setMetadata({
643
- isLoading: false,
644
- error: error.message,
645
- retryCount: useStore.getMetadata().retryCount + 1,
646
- });
647
- }
616
+ function recordFetchedItems(items: string[]) {
617
+ useStore.setMetadata((metadata) => ({ ...metadata, lastFetchedAt: Date.now() }));
618
+ useStore.setState({ items });
648
619
  }
649
620
  ```
650
621
 
@@ -776,12 +747,14 @@ type AppState = {
776
747
  sessionData: { temp: string }; // Don't persist this!
777
748
  };
778
749
 
779
- const useAppState = createGlobalState<AppState>(
780
- {
781
- user: { name: 'Guest', email: '' },
782
- settings: { theme: 'light' },
783
- sessionData: { temp: 'session-123' },
784
- },
750
+ const initialAppState: AppState = {
751
+ user: { name: 'Guest', email: '' },
752
+ settings: { theme: 'light' },
753
+ sessionData: { temp: 'session-123' },
754
+ };
755
+
756
+ const useAppState = createGlobalState(
757
+ initialAppState,
785
758
  {
786
759
  localStorage: {
787
760
  key: 'app-state',
@@ -880,7 +853,7 @@ function App() {
880
853
 
881
854
  #### 🎯 Context + Selectors = ❤️
882
855
 
883
- Everything that works with `createGlobalState` works with `createContext`!
856
+ Use the same selectors, actions and metadata with state scoped to each provider.
884
857
 
885
858
  ```tsx
886
859
  const FormContext = createContext({
@@ -976,7 +949,7 @@ function App() {
976
949
  }
977
950
 
978
951
  function UserList() {
979
- const [activeUsers] = useActiveUsers();
952
+ const activeUsers = useActiveUsers();
980
953
  return (
981
954
  <ul>
982
955
  {activeUsers.map((u) => (
@@ -1143,7 +1116,7 @@ const SessionContext = createContext(
1143
1116
  },
1144
1117
  );
1145
1118
 
1146
- // Internal actions are not expose through the context
1119
+ // Internal actions are not exposed through the context
1147
1120
  const { loadData } = SessionContext.use.actions();
1148
1121
  console.log(loadData); // undefined
1149
1122
  ```
@@ -1469,9 +1442,9 @@ function TodoApp() {
1469
1442
  }
1470
1443
  ```
1471
1444
 
1472
- **Why this pattern rocks:**
1445
+ **Benefits of this structure:**
1473
1446
 
1474
- - ✅ **KISS** - Keep It Simple, Stupid! Easy to navigate
1447
+ - ✅ **Focused modules** - Keep related state, actions and selectors easy to navigate
1475
1448
  - ✅ **Type-safe** - Everything is strongly typed
1476
1449
  - ✅ **Public/Private APIs** - Internal actions don't pollute public interface
1477
1450
  - ✅ **Namespace pattern** - Everything bundled: `todos$.useActiveTodos()`, `todos$.activeTodos$`
@@ -1675,7 +1648,7 @@ actions.addTodo('Build feature', userId);
1675
1648
  | Resource | Description |
1676
1649
  | ------------------------------------------------------------------------------------ | --------------------------------- |
1677
1650
  | 🎮 [**Live Demo**](https://johnny-quesada-developer.github.io/global-hooks-example/) | Interactive examples |
1678
- | 🎥 [**Video Tutorial**](https://www.youtube.com/watch?v=1UBqXk2MH8I/) | Full walkthrough |
1651
+ | 🎥 [**Video Tutorial**](https://www.youtube.com/watch?v=1UBqXk2MH8I) | Full walkthrough |
1679
1652
  | 💻 [**CodePen**](https://codepen.io/johnnynabetes/pen/WNmeGwb?editors=0010) | Try it online |
1680
1653
  | 📚 **400+ Tests** | Check the test suite for patterns |
1681
1654
 
@@ -1685,7 +1658,7 @@ actions.addTodo('Build feature', userId);
1685
1658
 
1686
1659
  | Package | Platform | Special Feature |
1687
1660
  | -------------------------------------------------------------------------------------------------- | -------------------- | ------------------------ |
1688
- | [`react-global-state-hooks`](https://www.npmjs.com/package/react-global-state-hooks) | React / React Native | Core library |
1661
+ | [`react-hooks-global-states`](https://www.npmjs.com/package/react-hooks-global-states) | React / React Native | Core library |
1689
1662
  | [`react-global-state-hooks`](https://www.npmjs.com/package/react-global-state-hooks) | Web | localStorage integration |
1690
1663
  | [`react-native-global-state-hooks`](https://www.npmjs.com/package/react-native-global-state-hooks) | React Native | AsyncStorage integration |
1691
1664
 
@@ -1693,18 +1666,7 @@ actions.addTodo('Build feature', userId);
1693
1666
 
1694
1667
  ## 🎉 Why Developers Choose This
1695
1668
 
1696
- ```tsx
1697
- "I replaced 500 lines of Redux with 50 lines of this. Mind blown." 🤯
1698
- - Every developer who tries it
1699
-
1700
- "The useState I always wanted." ❤️
1701
- - React developers everywhere
1702
-
1703
- "Finally, state management that doesn't fight me." 🥊
1704
- - Tired developers worldwide
1705
- ```
1706
-
1707
- ### The Bottom Line
1669
+ ### At a glance
1708
1670
 
1709
1671
  | What You Get | What You Don't |
1710
1672
  | --------------------------- | --------------------- |
@@ -1714,7 +1676,7 @@ actions.addTodo('Build feature', userId);
1714
1676
  | ✅ TypeScript inference | ❌ Manual typing |
1715
1677
  | ✅ Global + Context | ❌ Either/or choice |
1716
1678
  | ✅ Actions (optional) | ❌ Required structure |
1717
- | ✅ 30-second learning curve | ❌ Week-long training |
1679
+ | ✅ Familiar hook syntax | ❌ New component APIs |
1718
1680
 
1719
1681
  ---
1720
1682
 
package/debug.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";var e=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var b=(p,o,i,t)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of x(o))!a.call(p,r)&&r!==i&&e(p,r,{get:()=>o[r],enumerable:!(t=m(o,r))||t.enumerable});return p};var c=p=>b(e({},"__esModule",{value:!0}),p);var d={};module.exports=c(d);var g=require("react-hooks-global-states/debug");
package/debug.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import 'react-hooks-global-states/debug';
2
+ export {};
package/debug.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";var e=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var b=(p,o,i,t)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of x(o))!a.call(p,r)&&r!==i&&e(p,r,{get:()=>o[r],enumerable:!(t=m(o,r))||t.enumerable});return p};var c=p=>b(e({},"__esModule",{value:!0}),p);var d={};module.exports=c(d);var g=require("react-hooks-global-states/debug");
package/debug.mjs ADDED
@@ -0,0 +1 @@
1
+ import"react-hooks-global-states/debug";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-global-state-hooks",
3
- "version": "16.0.4",
4
- "description": "This is a package to easily handling global-state across your react components",
3
+ "version": "16.0.5",
4
+ "description": "Shared React state with a useState-style API, selective subscriptions, actions, localStorage persistence and DevTools.",
5
5
  "main": "./bundle.cjs",
6
6
  "module": "./bundle.mjs",
7
7
  "types": "./index.d.ts",
@@ -57,6 +57,11 @@
57
57
  "import": "./actions.mjs",
58
58
  "require": "./actions.cjs"
59
59
  },
60
+ "./debug": {
61
+ "types": "./debug.d.ts",
62
+ "import": "./debug.mjs",
63
+ "require": "./debug.cjs"
64
+ },
60
65
  "./package.json": "./package.json"
61
66
  },
62
67
  "files": [
@@ -98,7 +103,7 @@
98
103
  "homepage": "https://github.com/johnny-quesada-developer/react-global-state-hooks#readme",
99
104
  "dependencies": {
100
105
  "json-storage-formatter": "^4.0.0",
101
- "react-hooks-global-states": "^16.0.4"
106
+ "react-hooks-global-states": "^16.0.5"
102
107
  },
103
108
  "peerDependencies": {
104
109
  "json-storage-formatter": "^4.0.0",
@@ -111,5 +116,8 @@
111
116
  "json-storage-formatter": {
112
117
  "optional": false
113
118
  }
119
+ },
120
+ "bin": {
121
+ "rgsh": "./rgsh.mjs"
114
122
  }
115
123
  }
package/rgsh.mjs ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import 'react-hooks-global-states/rgsh';
package/types.d.ts CHANGED
@@ -128,7 +128,7 @@ export interface CreateGlobalState {
128
128
  * @param args.name optional name for debugging purposes
129
129
  * @param args.metadata optional non-reactive metadata associated with the state
130
130
  * @param args.callbacks optional lifecycle callbacks for the global state
131
- * @param args.actions optional actions to restrict state mutations [if provided `setState` will be nullified]
131
+ * @param args.actions Optional actions returned as the hook’s second item; `setState` remains available on the store API
132
132
  * @param args.localStorage optional configuration to persist the state in local storage
133
133
  * @returns a state hook that you can use in your components
134
134
  *
@@ -185,7 +185,7 @@ export interface CreateGlobalState {
185
185
  * @param args.name optional name for debugging purposes
186
186
  * @param args.metadata optional non-reactive metadata associated with the state
187
187
  * @param args.callbacks optional lifecycle callbacks for the global state
188
- * @param args.actions optional actions to restrict state mutations [if provided `setState` will be nullified]
188
+ * @param args.actions Optional actions returned as the hook’s second item; `setState` remains available on the store API
189
189
  * @param args.localStorage optional configuration to persist the state in local storage
190
190
  * @returns a state hook that you can use in your components
191
191
  *