react-hooks-global-states 11.0.0 → 12.0.0

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/isRecord.js CHANGED
@@ -1,44 +1 @@
1
- var o;o=o=>/******/(()=>{
2
- /******/"use strict";
3
- /******/var t={
4
- /***/35:
5
- /***/(o,t,e)=>{function r(o){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},r(o)}Object.defineProperty(t,"__esModule",{value:!0}),t.isRecord=void 0;var s=e(773);t.isRecord=function(o){return!(0,s.isNil)(o)&&"object"===r(o)},t.default=t.isRecord}
6
- /***/,
7
- /***/773:
8
- /***/t=>{t.exports=o;
9
- /***/
10
- /******/}},e={};
11
- /************************************************************************/
12
- /******/
13
- /******/
14
- /******/
15
- /******/
16
- /******/
17
- /******/
18
- /******/return function o(r){
19
- /******/
20
- /******/var s=e[r];
21
- /******/if(void 0!==s)
22
- /******/return s.exports;
23
- /******/
24
- /******/
25
- /******/var i=e[r]={
26
- /******/
27
- /******/
28
- /******/exports:{}
29
- /******/};
30
- /******/
31
- /******/
32
- /******/
33
- /******/
34
- /******/
35
- /******/return t[r](i,i.exports,o),i.exports;
36
- /******/}
37
- /******/
38
- /************************************************************************/
39
- /******/
40
- /******/
41
- /******/
42
- /******/
43
- /******/(35);
44
- /******/})(),"object"==typeof exports&&"object"==typeof module?module.exports=o(require("json-storage-formatter/isNil")):"function"==typeof define&&define.amd?define(["json-storage-formatter/isNil"],o):"object"==typeof exports?exports["react-hooks-global-states"]=o(require("json-storage-formatter/isNil")):this["react-hooks-global-states"]=o(this["json-storage-formatter/isNil"]);
1
+ var o;o=o=>(()=>{"use strict";var t={35:(o,t,e)=>{function r(o){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},r(o)}Object.defineProperty(t,"__esModule",{value:!0}),t.isRecord=void 0;var s=e(773);t.isRecord=function(o){return!(0,s.isNil)(o)&&"object"===r(o)},t.default=t.isRecord},773:t=>{t.exports=o}},e={};return function o(r){var s=e[r];if(void 0!==s)return s.exports;var i=e[r]={exports:{}};return t[r](i,i.exports,o),i.exports}(35)})(),"object"==typeof exports&&"object"==typeof module?module.exports=o(require("json-storage-formatter/isNil")):"function"==typeof define&&define.amd?define(["json-storage-formatter/isNil"],o):"object"==typeof exports?exports["react-hooks-global-states"]=o(require("json-storage-formatter/isNil")):this["react-hooks-global-states"]=o(this["json-storage-formatter/isNil"]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-hooks-global-states",
3
- "version": "11.0.0",
3
+ "version": "12.0.0",
4
4
  "description": "This is a package to easily handling global-state across your react-components using hooks.",
5
5
  "main": "./bundle.js",
6
6
  "types": "./index.d.ts",
package/shallowCompare.js CHANGED
@@ -1,53 +1 @@
1
- var r,t;r=this,t=(r,t,e,n)=>/******/(()=>{
2
- /******/"use strict";
3
- /******/var o={
4
- /***/38:
5
- /***/t=>{t.exports=r;
6
- /***/},
7
- /***/487:
8
- /***/r=>{r.exports=t;
9
- /***/},
10
- /***/773:
11
- /***/r=>{r.exports=e;
12
- /***/},
13
- /***/955:
14
- /***/r=>{r.exports=n;
15
- /***/},
16
- /***/973:
17
- /***/(r,t,e)=>{function n(r,t){var e="undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(!e){if(Array.isArray(r)||(e=o(r))||t&&r&&"number"==typeof r.length){e&&(r=e);var n=0,i=function(){};return{s:i,n:function(){return n>=r.length?{done:!0}:{done:!1,value:r[n++]}},e:function(r){throw r},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,s=!0,u=!1;return{s:function(){e=e.call(r)},n:function(){var r=e.next();return s=r.done,r},e:function(r){u=!0,a=r},f:function(){try{s||null==e.return||e.return()}finally{if(u)throw a}}}}function o(r,t){if(r){if("string"==typeof r)return i(r,t);var e={}.toString.call(r).slice(8,-1);return"Object"===e&&r.constructor&&(e=r.constructor.name),"Map"===e||"Set"===e?Array.from(r):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?i(r,t):void 0}}function i(r,t){(null==t||t>r.length)&&(t=r.length);for(var e=0,n=Array(t);e<t;e++)n[e]=r[e];return n}function a(r){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},a(r)}Object.defineProperty(t,"__esModule",{value:!0}),t.isEqualObject=t.isEqualSet=t.isEqualMap=t.isEqualArray=t.canCheckSimpleEquality=t.isSet=t.isMap=t.isArray=t.shallowCompare=void 0;var s=e(955),u=e(38),l=e(773),f=e(487);t.shallowCompare=function(r,e){return!(r!==e)||((0,t.canCheckSimpleEquality)(r,e)?r===e:(0,t.isArray)(r)&&(0,t.isArray)(e)?(0,t.isEqualArray)(r,e):(0,t.isMap)(r)&&(0,t.isMap)(e)?(0,t.isEqualMap)(r,e):(0,t.isSet)(r)&&(0,t.isSet)(e)?(0,t.isEqualSet)(r,e):(0,f.isRecord)(r)&&(0,f.isRecord)(e)?(0,t.isEqualObject)(r,e):r===e)},t.isArray=function(r){return Array.isArray(r)},t.isMap=function(r){return r instanceof Map},t.isSet=function(r){return r instanceof Set},t.canCheckSimpleEquality=function(r,t){var e=a(r),n=a(t);return e!==n||(0,l.isNil)(r)||(0,l.isNil)(t)||(0,s.isPrimitive)(r)&&(0,s.isPrimitive)(t)||(0,u.isDate)(r)&&(0,u.isDate)(t)||"function"===e&&"function"===n},t.isEqualArray=function(r,t){if(r.length!==t.length)return!1;for(var e=0;e<r.length;e+=1)if(r[e]!==t[e])return!1;return!0},t.isEqualMap=function(r,t){if(r.size!==t.size)return!1;var e,i,a=n(r);try{for(a.s();!(e=a.n()).done;){var s=function(r){if(Array.isArray(r))return r}(i=e.value)||function(r){var t=null==r?null:"undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(null!=t){var e,n,o,i,a=[],s=!0,u=!1;try{for(o=(t=t.call(r)).next;!(s=(e=o.call(t)).done)&&(a.push(e.value),2!==a.length);s=!0);}catch(r){u=!0,n=r}finally{try{if(!s&&null!=t.return&&(i=t.return(),Object(i)!==i))return}finally{if(u)throw n}}return a}}(i)||o(i,2)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),u=s[0];if(s[1]!==t.get(u))return!1}}catch(r){a.e(r)}finally{a.f()}return!0},t.isEqualSet=function(r,t){if(r.size!==t.size)return!1;var e,o=n(r);try{for(o.s();!(e=o.n()).done;){var i=e.value;if(!t.has(i))return!1}}catch(r){o.e(r)}finally{o.f()}return!0},t.isEqualObject=function(r,t){var e=Object.keys(r),n=Object.keys(t);if(e.length!==n.length)return!1;for(var o=0,i=e;o<i.length;o++){var a=i[o];if(r[a]!==t[a])return!1}return!0},t.default=t.shallowCompare}
18
- /***/
19
- /******/},i={};
20
- /************************************************************************/
21
- /******/
22
- /******/
23
- /******/
24
- /******/
25
- /******/
26
- /******/
27
- /******/return function r(t){
28
- /******/
29
- /******/var e=i[t];
30
- /******/if(void 0!==e)
31
- /******/return e.exports;
32
- /******/
33
- /******/
34
- /******/var n=i[t]={
35
- /******/
36
- /******/
37
- /******/exports:{}
38
- /******/};
39
- /******/
40
- /******/
41
- /******/
42
- /******/
43
- /******/
44
- /******/return o[t](n,n.exports,r),n.exports;
45
- /******/}
46
- /******/
47
- /************************************************************************/
48
- /******/
49
- /******/
50
- /******/
51
- /******/
52
- /******/(973);
53
- /******/})(),"object"==typeof exports&&"object"==typeof module?module.exports=t(require("json-storage-formatter/isDate"),require("./isRecord.js"),require("json-storage-formatter/isNil"),require("json-storage-formatter/isPrimitive")):"function"==typeof define&&define.amd?define(["json-storage-formatter/isDate","./isRecord.js","json-storage-formatter/isNil","json-storage-formatter/isPrimitive"],t):"object"==typeof exports?exports["react-hooks-global-states"]=t(require("json-storage-formatter/isDate"),require("./isRecord.js"),require("json-storage-formatter/isNil"),require("json-storage-formatter/isPrimitive")):r["react-hooks-global-states"]=t(r["json-storage-formatter/isDate"],r["./isRecord.js"],r["json-storage-formatter/isNil"],r["json-storage-formatter/isPrimitive"]);
1
+ var r,t;r=this,t=(r,t,e,n)=>(()=>{"use strict";var o={38:t=>{t.exports=r},487:r=>{r.exports=t},773:r=>{r.exports=e},955:r=>{r.exports=n},973:(r,t,e)=>{function n(r,t){var e="undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(!e){if(Array.isArray(r)||(e=o(r))||t&&r&&"number"==typeof r.length){e&&(r=e);var n=0,i=function(){};return{s:i,n:function(){return n>=r.length?{done:!0}:{done:!1,value:r[n++]}},e:function(r){throw r},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,s=!0,u=!1;return{s:function(){e=e.call(r)},n:function(){var r=e.next();return s=r.done,r},e:function(r){u=!0,a=r},f:function(){try{s||null==e.return||e.return()}finally{if(u)throw a}}}}function o(r,t){if(r){if("string"==typeof r)return i(r,t);var e={}.toString.call(r).slice(8,-1);return"Object"===e&&r.constructor&&(e=r.constructor.name),"Map"===e||"Set"===e?Array.from(r):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?i(r,t):void 0}}function i(r,t){(null==t||t>r.length)&&(t=r.length);for(var e=0,n=Array(t);e<t;e++)n[e]=r[e];return n}function a(r){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},a(r)}Object.defineProperty(t,"__esModule",{value:!0}),t.isEqualObject=t.isEqualSet=t.isEqualMap=t.isEqualArray=t.canCheckSimpleEquality=t.isSet=t.isMap=t.isArray=t.shallowCompare=void 0;var s=e(955),u=e(38),l=e(773),f=e(487);t.shallowCompare=function(r,e){return!(r!==e)||((0,t.canCheckSimpleEquality)(r,e)?r===e:(0,t.isArray)(r)&&(0,t.isArray)(e)?(0,t.isEqualArray)(r,e):(0,t.isMap)(r)&&(0,t.isMap)(e)?(0,t.isEqualMap)(r,e):(0,t.isSet)(r)&&(0,t.isSet)(e)?(0,t.isEqualSet)(r,e):(0,f.isRecord)(r)&&(0,f.isRecord)(e)?(0,t.isEqualObject)(r,e):r===e)},t.isArray=function(r){return Array.isArray(r)},t.isMap=function(r){return r instanceof Map},t.isSet=function(r){return r instanceof Set},t.canCheckSimpleEquality=function(r,t){var e=a(r),n=a(t);return e!==n||(0,l.isNil)(r)||(0,l.isNil)(t)||(0,s.isPrimitive)(r)&&(0,s.isPrimitive)(t)||(0,u.isDate)(r)&&(0,u.isDate)(t)||"function"===e&&"function"===n},t.isEqualArray=function(r,t){if(r.length!==t.length)return!1;for(var e=0;e<r.length;e+=1)if(r[e]!==t[e])return!1;return!0},t.isEqualMap=function(r,t){if(r.size!==t.size)return!1;var e,i,a=n(r);try{for(a.s();!(e=a.n()).done;){var s=function(r){if(Array.isArray(r))return r}(i=e.value)||function(r){var t=null==r?null:"undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(null!=t){var e,n,o,i,a=[],s=!0,u=!1;try{for(o=(t=t.call(r)).next;!(s=(e=o.call(t)).done)&&(a.push(e.value),2!==a.length);s=!0);}catch(r){u=!0,n=r}finally{try{if(!s&&null!=t.return&&(i=t.return(),Object(i)!==i))return}finally{if(u)throw n}}return a}}(i)||o(i,2)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(),u=s[0];if(s[1]!==t.get(u))return!1}}catch(r){a.e(r)}finally{a.f()}return!0},t.isEqualSet=function(r,t){if(r.size!==t.size)return!1;var e,o=n(r);try{for(o.s();!(e=o.n()).done;){var i=e.value;if(!t.has(i))return!1}}catch(r){o.e(r)}finally{o.f()}return!0},t.isEqualObject=function(r,t){var e=Object.keys(r),n=Object.keys(t);if(e.length!==n.length)return!1;for(var o=0,i=e;o<i.length;o++){var a=i[o];if(r[a]!==t[a])return!1}return!0},t.default=t.shallowCompare}},i={};return function r(t){var e=i[t];if(void 0!==e)return e.exports;var n=i[t]={exports:{}};return o[t](n,n.exports,r),n.exports}(973)})(),"object"==typeof exports&&"object"==typeof module?module.exports=t(require("json-storage-formatter/isDate"),require("./isRecord.js"),require("json-storage-formatter/isNil"),require("json-storage-formatter/isPrimitive")):"function"==typeof define&&define.amd?define(["json-storage-formatter/isDate","./isRecord.js","json-storage-formatter/isNil","json-storage-formatter/isPrimitive"],t):"object"==typeof exports?exports["react-hooks-global-states"]=t(require("json-storage-formatter/isDate"),require("./isRecord.js"),require("json-storage-formatter/isNil"),require("json-storage-formatter/isPrimitive")):r["react-hooks-global-states"]=t(r["json-storage-formatter/isDate"],r["./isRecord.js"],r["json-storage-formatter/isNil"],r["json-storage-formatter/isPrimitive"]);
@@ -1,16 +1 @@
1
- var t;t=()=>/******/(()=>{
2
- /******/"use strict";
3
- /******/var t={};
4
- /************************************************************************/
5
- /******/
6
- /******/
7
- /******/
8
- /******/
9
- /******/
10
- /******/
11
- /******/
12
- /******/
13
- /***/return((t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.throwWrongKeyOnActionCollectionConfig=void 0,e.throwWrongKeyOnActionCollectionConfig=function(t){throw new Error("[WRONG CONFIGURATION!]: Every key inside the storeActionsConfig must be a higher order function that returns a function \n[".concat(t,"]: key is not a valid function, try something like this: \n{\n\n ").concat(t,": (param) => ({ setState, getState, setMetadata, getMetadata, actions }) => {\n\n setState((state) => ({ ...state, ...param }))\n\n }\n\n}\n"))},e.default=e.throwWrongKeyOnActionCollectionConfig})
14
- /***/
15
- /******/(0,t),t;
16
- /******/})(),"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["react-hooks-global-states"]=t():this["react-hooks-global-states"]=t();
1
+ var t;t=()=>(()=>{"use strict";var t={};return((t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.throwWrongKeyOnActionCollectionConfig=void 0,e.throwWrongKeyOnActionCollectionConfig=function(t){throw new Error("[WRONG CONFIGURATION!]: Every key inside the storeActionsConfig must be a higher order function that returns a function \n[".concat(t,"]: key is not a valid function, try something like this: \n{\n\n ").concat(t,": (param) => ({ setState, getState, setMetadata, getMetadata, actions }) => {\n\n setState((state) => ({ ...state, ...param }))\n\n }\n\n}\n"))},e.default=e.throwWrongKeyOnActionCollectionConfig})(0,t),t})(),"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["react-hooks-global-states"]=t():this["react-hooks-global-states"]=t();
package/types.d.ts CHANGED
@@ -1,10 +1,46 @@
1
1
  export type AnyFunction = (...args: any[]) => any;
2
+ /**
3
+ * @description Represents a hook that returns a readonly state.
4
+ */
5
+ export interface ReadonlyHook<State, StateMutator, Metadata extends BaseMetadata> extends ReadonlyStateApi<State, StateMutator, Metadata> {
6
+ /**
7
+ * @description Returns the current state value.
8
+ */
9
+ (): State;
10
+ /**
11
+ * @description Returns a derived state based on the provided selector function.
12
+ */
13
+ <Derivate>(selector: (state: State) => Derivate, dependencies?: unknown[]): Derivate;
14
+ /**
15
+ * @description Returns a derived state based on the provided selector function and configuration.
16
+ */
17
+ <Derivate>(selector: (state: State) => Derivate, config?: UseHookOptions<Derivate, State>): Derivate;
18
+ }
19
+ /**
20
+ * @description Hook to select a fragment of the state
21
+ */
22
+ export interface SelectHook<State> {
23
+ /**
24
+ * @description Selects a fragment of the state using the provided selector function.
25
+ * @param selector - The function to select a fragment of the state.
26
+ * @param dependencies - Optional dependencies array to control re-evaluation.
27
+ * @returns The selected fragment of the state.
28
+ */
29
+ <Selection>(selector: (state: State) => Selection, dependencies?: unknown[]): Selection;
30
+ /**
31
+ * @description Selects a fragment of the state using the provided selector function and configuration.
32
+ * @param selector - The function to select a fragment of the state.
33
+ * @param args - Configuration options for the selection.
34
+ * @returns The selected fragment of the state.
35
+ */
36
+ <Selection>(selector: (state: State) => Selection, args?: UseHookOptions<Selection, State>): Selection;
37
+ }
2
38
  /**
3
39
  * @description Represents the complete non-reactive API of a global state instance.
4
40
  * This API provides full control over the state, including reading, writing, subscribing,
5
41
  * and creating derived hooks or observable fragments.
6
42
  */
7
- export type StateApi<State, StateDispatch, StateMutator, Metadata extends BaseMetadata> = {
43
+ export type StateApi<State, StateMutator, Metadata extends BaseMetadata> = {
8
44
  /**
9
45
  * Returns the metadata
10
46
  * Metadata is additional non reactive information associated with the global state
@@ -26,7 +62,7 @@ export type StateApi<State, StateDispatch, StateMutator, Metadata extends BaseMe
26
62
  * When actions exist, direct state mutation via `setState` is disabled and this property will be `null`.
27
63
  * If no actions are provided, this property exposes the `setState` function.
28
64
  */
29
- setState: StateMutator extends AnyFunction ? StateDispatch : null;
65
+ setState: StateMutator extends AnyFunction ? React.Dispatch<React.SetStateAction<State>> : null;
30
66
  /**
31
67
  * @description Get the current state value
32
68
  */
@@ -43,37 +79,91 @@ export type StateApi<State, StateDispatch, StateMutator, Metadata extends BaseMe
43
79
  * The selector hook will be evaluated only if the result of the selector changes and the equality function returns false
44
80
  * you can customize the equality function by passing the isEqualRoot and isEqual parameters
45
81
  */
46
- createSelectorHook: <Selection>(selector: (state: State) => Selection, args?: Omit<UseHookConfig<Selection, State>, 'dependencies'> & {
82
+ createSelectorHook: <Selection>(selector: (state: State) => Selection, args?: Omit<UseHookOptions<Selection, State>, 'dependencies'> & {
47
83
  name?: string;
48
- }) => StateHook<Selection, StateDispatch, StateMutator, Metadata>;
84
+ }) => ReadonlyHook<Selection, StateMutator, Metadata>;
49
85
  /**
50
86
  * @description Creates a function that allows you to subscribe to a fragment of the state
51
87
  * The observable selection will notify the subscribers only if the fragment changes and the equality function returns false
52
88
  * you can customize the equality function by passing the isEqualRoot and isEqual parameters
53
89
  */
54
- createObservable: <Selection>(this: StateApi<State, StateDispatch, StateMutator, Metadata>, selector: (state: State) => Selection, args?: {
90
+ createObservable: <Selection>(this: ReadonlyStateApi<State, StateMutator, Metadata>, selector: (state: State) => Selection, args?: {
55
91
  isEqual?: (current: Selection, next: Selection) => boolean;
56
92
  isEqualRoot?: (current: State, next: State) => boolean;
57
93
  /**
58
94
  * @description Name of the observable fragment for debugging purposes
59
95
  */
60
96
  name?: string;
61
- }) => ObservableFragment<Selection, StateDispatch, StateMutator, Metadata>;
97
+ }) => ObservableFragment<Selection, StateMutator, Metadata>;
98
+ /**
99
+ * @description Selects a fragment of the state using the provided selector function.
100
+ */
101
+ select: SelectHook<State>;
102
+ /**
103
+ * @description Sugared hook to use the global state in React components
104
+ * Allows you to tread the global hook as an store, with better semantics
105
+ *
106
+ * @example
107
+ * ```tsx
108
+ * const contacts = createContext<ContactType[]>([]);
109
+ *
110
+ * function ContactsList() {
111
+ * const [contacts, setContacts] = contacts.use();
112
+ * ```
113
+ *
114
+ * This is more practical since the StateApi is slightly more complex than a simple hook
115
+ *
116
+ * @example
117
+ * Using a global state:
118
+ *
119
+ * ```tsx
120
+ * const [state, setState, metadata] = state.use();
121
+ *
122
+ * const selection = state.select((state) => state.someFragment);
123
+ *
124
+ * const unsubscribe = state.subscribe((state) => { ... });
125
+ *
126
+ * const useFragment = state.createSelectorHook((state) => state.someFragment);
127
+ *
128
+ * const observable = state.createObservable((state) => state.someFragment);
129
+ * ```
130
+ */
131
+ use: StateHook<State, StateMutator, Metadata>;
62
132
  /**
63
133
  * @description Disposes the global state instance, cleaning up all resources and subscriptions.
64
134
  */
65
135
  dispose: () => void;
66
136
  };
137
+ /**
138
+ * @description Readonly version of the StateApi, excluding mutative methods.
139
+ */
140
+ export type ReadonlyStateApi<State, StateMutator, Metadata extends BaseMetadata> = Pick<StateApi<State, StateMutator, Metadata>, 'dispose' | 'getState' | 'subscribe' | 'createSelectorHook' | 'createObservable'>;
67
141
  /**
68
142
  * @description Function that allows you to subscribe to a fragment of the state
69
143
  */
70
- export type ObservableFragment<State, StateDispatch, StateMutator, Metadata extends BaseMetadata> = SubscribeToState<State> & StateApi<State, StateDispatch, StateMutator, Metadata>;
71
- export interface StateHook<State, StateDispatch, StateMutator, Metadata extends BaseMetadata> extends StateApi<State, StateDispatch, StateMutator, Metadata> {
144
+ export type ObservableFragment<State, StateMutator, Metadata extends BaseMetadata> = SubscribeToState<State> & Pick<StateApi<State, StateMutator, Metadata>, 'getState' | 'subscribe' | 'createSelectorHook' | 'createObservable' | 'dispose'>;
145
+ export interface StateHook<State, StateMutator, Metadata extends BaseMetadata> extends StateApi<State, StateMutator, Metadata> {
146
+ /**
147
+ * @description React hook that provides access to the state, state mutator, and metadata.
148
+ */
72
149
  (): Readonly<[state: State, stateMutator: StateMutator, metadata: Metadata]>;
150
+ /**
151
+ * @description React hook that provides a derived state based on the provided selector function.
152
+ */
73
153
  <Derivate>(selector: (state: State) => Derivate, dependencies?: unknown[]): Readonly<[state: Derivate, stateMutator: StateMutator, metadata: Metadata]>;
74
- <Derivate>(selector: (state: State) => Derivate, config?: UseHookConfig<Derivate, State>): Readonly<[state: Derivate, stateMutator: StateMutator, metadata: Metadata]>;
154
+ /**
155
+ * @description React hook that provides a derived state based on the provided selector function and configuration.
156
+ */
157
+ <Derivate>(selector: (state: State) => Derivate, config?: UseHookOptions<Derivate, State>): Readonly<[state: Derivate, stateMutator: StateMutator, metadata: Metadata]>;
75
158
  }
159
+ /**
160
+ * @description Function to set the metadata value
161
+ * The metadata value is not reactive and wont trigger re-renders
162
+ */
76
163
  export type MetadataSetter<Metadata extends BaseMetadata> = (setter: Metadata | ((metadata: Metadata) => Metadata)) => void;
164
+ /**
165
+ * @description Represents the changes in the state
166
+ */
77
167
  export type StateChanges<State> = {
78
168
  state: State;
79
169
  previousState: State | undefined;
@@ -82,22 +172,55 @@ export type StateChanges<State> = {
82
172
  /**
83
173
  * API for the actions of the global states
84
174
  **/
85
- export type StoreTools<State, Metadata extends BaseMetadata = BaseMetadata, Actions extends undefined | unknown | Record<string, AnyFunction> = unknown> = {
175
+ export type StoreTools<State, StateMutator = React.Dispatch<React.SetStateAction<State>>, Metadata extends BaseMetadata = BaseMetadata> = {
176
+ /**
177
+ * The actions available for the global state
178
+ */
179
+ actions: StateMutator extends AnyFunction ? null : StateMutator;
180
+ /**
181
+ * @description Metadata associated with the global state
182
+ */
183
+ getMetadata: () => Metadata;
184
+ /**
185
+ * @description Current state value
186
+ */
187
+ getState: () => State;
188
+ /**
189
+ * @description Sets the metadata value
190
+ */
86
191
  setMetadata: MetadataSetter<Metadata>;
192
+ /**
193
+ * @description Function to set the state value
194
+ */
87
195
  setState: React.Dispatch<React.SetStateAction<State>>;
88
- getState: () => State;
196
+ /**
197
+ * @description Subscribe to the state changes
198
+ * You can subscribe to the whole state or to a fragment of the state by passing a selector as first parameter,
199
+ * this can be used in non react environments to listen to the state changes
200
+ *
201
+ * @example
202
+ * ```ts
203
+ * const unsubscribe = storeTools.subscribe((state) => {
204
+ * console.log('State changed:', state);
205
+ * });
206
+ *
207
+ * // To unsubscribe later
208
+ * unsubscribe();
209
+ * ```
210
+ */
89
211
  subscribe: SubscribeToState<State>;
90
- getMetadata: () => Metadata;
91
- actions: Actions;
92
212
  };
93
213
  /**
94
214
  * contract for the storeActionsConfig configuration
95
215
  */
96
216
  export interface ActionCollectionConfig<State, Metadata extends BaseMetadata, ThisAPI = Record<string, (...parameters: any[]) => unknown>> {
97
217
  readonly [key: string]: {
98
- (this: ThisAPI, ...parameters: any[]): (this: ThisAPI, storeTools: StoreTools<State, Metadata, Record<string, (...parameters: any[]) => unknown | void>>) => unknown | void;
218
+ (this: ThisAPI, ...parameters: any[]): (this: ThisAPI, storeTools: StoreTools<State, Record<string, (...parameters: any[]) => unknown | void>, Metadata>) => unknown | void;
99
219
  };
100
220
  }
221
+ /**
222
+ * @description Resulting type of the action collection configuration
223
+ */
101
224
  export type ActionCollectionResult<State, Metadata extends BaseMetadata, ActionsConfig extends ActionCollectionConfig<State, Metadata>> = {
102
225
  [key in keyof ActionsConfig]: {
103
226
  (...params: Parameters<ActionsConfig[key]>): ReturnType<ReturnType<ActionsConfig[key]>>;
@@ -106,35 +229,44 @@ export type ActionCollectionResult<State, Metadata extends BaseMetadata, Actions
106
229
  /**
107
230
  * Callbacks for the global store lifecycle events
108
231
  */
109
- export type GlobalStoreCallbacks<State, Metadata extends BaseMetadata> = {
232
+ export type GlobalStoreCallbacks<State, StateMutator, Metadata extends BaseMetadata> = {
110
233
  /**
111
234
  * @description Called when the store is initialized
112
235
  */
113
- onInit?: (args: StoreTools<State, Metadata>) => void;
236
+ onInit?: (args: StoreTools<State, StateMutator, Metadata>) => void;
114
237
  /**
115
238
  * @description Called when the state has changed
116
239
  */
117
- onStateChanged?: (args: StoreTools<State, Metadata> & StateChanges<State>) => void;
240
+ onStateChanged?: (args: StoreTools<State, StateMutator, Metadata> & StateChanges<State>) => void;
118
241
  /**
119
242
  * @description Called when a new subscription is created
120
243
  */
121
- onSubscribed?: (args: StoreTools<State, Metadata>, subscription: SubscriberParameters) => void;
244
+ onSubscribed?: (args: StoreTools<State, StateMutator, Metadata>, subscription: SubscriberParameters) => void;
122
245
  /**
123
246
  * @description Called to determine whether to prevent a state change
124
247
  */
125
- computePreventStateChange?: (args: StoreTools<State, Metadata> & StateChanges<State>) => boolean;
248
+ computePreventStateChange?: (args: StoreTools<State, StateMutator, Metadata> & StateChanges<State>) => boolean;
126
249
  /**
127
250
  * @description Called when the store is unmounted, only applicable in context stores
128
251
  */
129
- onUnMount?: (store: StateApi<State, any, any, Metadata>) => void;
252
+ onUnMount?: (store: StoreTools<State, StateMutator, Metadata>) => void;
130
253
  };
131
- export type UseHookConfig<State, TRoot = any> = {
254
+ /**
255
+ * @description Configuration options for the use hook
256
+ */
257
+ export type UseHookOptions<State, TRoot = any> = {
132
258
  isEqual?: (current: State, next: State) => boolean;
133
259
  isEqualRoot?: (current: TRoot, next: TRoot) => boolean;
134
260
  dependencies?: unknown[];
135
261
  };
262
+ /**
263
+ * @description Callback function to unsubscribe from the store changes
264
+ */
136
265
  export type UnsubscribeCallback = () => void;
137
- export type SubscribeCallbackConfig<State> = UseHookConfig<State> & {
266
+ /**
267
+ * @description Configuration for the subscribe callback
268
+ */
269
+ export type SubscribeCallbackConfig<State> = UseHookOptions<State> & {
138
270
  /**
139
271
  * By default the callback is executed immediately after the subscription
140
272
  */
@@ -150,20 +282,65 @@ export type SubscribeCallback<State> = (state: State) => void;
150
282
  * This can be used in non react environments to listen to the state changes
151
283
  */
152
284
  export type SubscribeToState<State> = {
285
+ /**
286
+ * @description Subscribe to the whole state changes
287
+ *
288
+ * @example
289
+ * ```ts
290
+ * const unsubscribe = store.subscribe((state) => {
291
+ * console.log('State changed:', state);
292
+ * });
293
+ *
294
+ * // To unsubscribe later
295
+ * unsubscribe();
296
+ * ```
297
+ */
153
298
  (subscription: SubscribeCallback<State>, config?: SubscribeCallbackConfig<State>): UnsubscribeCallback;
299
+ /**
300
+ * @description Subscribe to a fragment of the state changes
301
+ *
302
+ * @example
303
+ * ```ts
304
+ * const unsubscribe = store.subscribe(
305
+ * (fragment) => {
306
+ * console.log('Fragment changed:', fragment);
307
+ * },
308
+ * (state) => {
309
+ * console.log('Selected fragment changed:', state.someFragment);
310
+ * }
311
+ * );
312
+ *
313
+ * // To unsubscribe later
314
+ * unsubscribe();
315
+ * ```
316
+ */
154
317
  <TDerivate>(selector: SelectorCallback<State, TDerivate>, subscription: SubscribeCallback<TDerivate>, config?: SubscribeCallbackConfig<TDerivate>): UnsubscribeCallback;
155
318
  };
319
+ /**
320
+ * @description Metadata, non reactive additional information associated with the global state
321
+ */
156
322
  export type BaseMetadata = Record<string, unknown>;
323
+ /**
324
+ * @description Function to get the metadata
325
+ */
157
326
  export type MetadataGetter<Metadata extends BaseMetadata> = () => Metadata;
158
- export type CustomGlobalHookBuilderParams<TCustomConfig extends BaseMetadata | unknown, Metadata extends BaseMetadata> = {
159
- onInitialize?: (args: StoreTools<unknown, Metadata, unknown>, config: TCustomConfig | undefined) => void;
160
- onChange?: (args: StoreTools<unknown, Metadata, unknown> & StateChanges<unknown>, config: TCustomConfig | undefined) => void;
161
- };
327
+ /**
328
+ * @description Selector function to derive a fragment of the state
329
+ */
162
330
  export type SelectorCallback<State, TDerivate> = (state: State) => TDerivate;
331
+ /**
332
+ * @description Parameters for the store subscription
333
+ */
163
334
  export type SubscriberParameters = {
164
335
  selector: SelectorCallback<any, any> | undefined;
165
- getConfig: () => UseHookConfig<any> | SubscribeCallbackConfig<any> | undefined;
336
+ /**
337
+ * Uses a function to avoid losing the reference when the subscription is created
338
+ */
339
+ getConfig: () => UseHookOptions<any> | SubscribeCallbackConfig<any> | undefined;
166
340
  currentState: unknown;
341
+ /**
342
+ * @description notification callback
343
+ */
167
344
  callback: SubscriptionCallback | (() => void);
168
345
  };
169
346
  /**
package/types.js CHANGED
@@ -1,4 +1 @@
1
- var e;e=()=>/******/(()=>{
2
- /******/"use strict";var e={};
3
- /******/return(()=>{var t=e;Object.defineProperty(t,"__esModule",{value:!0})})(),e;
4
- /******/})(),"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports["react-hooks-global-states"]=e():this["react-hooks-global-states"]=e();
1
+ var e;e=()=>(()=>{"use strict";var e={};return(()=>{var t=e;Object.defineProperty(t,"__esModule",{value:!0})})(),e})(),"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports["react-hooks-global-states"]=e():this["react-hooks-global-states"]=e();
package/uniqueId.js CHANGED
@@ -1,16 +1 @@
1
- var e;e=()=>/******/(()=>{
2
- /******/"use strict";
3
- /******/var e={};
4
- /************************************************************************/
5
- /******/
6
- /******/
7
- /******/
8
- /******/
9
- /******/
10
- /******/
11
- /******/
12
- /******/
13
- /***/return((e,t)=>{var o;Object.defineProperty(t,"__esModule",{value:!0}),t.uniqueId=void 0,t.uniqueId=(o=0,function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return o===Number.MAX_SAFE_INTEGER&&(o=0),e+Date.now().toString(36)+(o++).toString(36)}),t.default=t.uniqueId})
14
- /***/
15
- /******/(0,e),e;
16
- /******/})(),"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports["react-hooks-global-states"]=e():this["react-hooks-global-states"]=e();
1
+ var e;e=()=>(()=>{"use strict";var e={};return((e,t)=>{var o;Object.defineProperty(t,"__esModule",{value:!0}),t.uniqueId=void 0,t.uniqueId=(o=0,function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return o===Number.MAX_SAFE_INTEGER&&(o=0),e+Date.now().toString(36)+(o++).toString(36)}),t.default=t.uniqueId})(0,e),e})(),"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports["react-hooks-global-states"]=e():this["react-hooks-global-states"]=e();
package/webpack.config.js CHANGED
@@ -103,11 +103,8 @@ module.exports = {
103
103
  toplevel: true,
104
104
  properties: false,
105
105
  },
106
- output: {
107
- // Keep only JSDoc-style comments (/** ... */)
108
- comments: (_node, comment) => {
109
- return comment.type === 'comment2' && comment.value.startsWith('*');
110
- },
106
+ format: {
107
+ comments: false,
111
108
  },
112
109
  },
113
110
  }),