react-hooks-global-states 10.2.0 → 11.0.0-beta.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/types.d.ts CHANGED
@@ -1,68 +1,75 @@
1
- export type StateSetter<State> = (setter: State | ((state: State) => State), meta?: {
1
+ export type AnyFunction = (...args: any[]) => any;
2
+ /**
3
+ * @description Represents the complete non-reactive API of a global state instance.
4
+ * This API provides full control over the state, including reading, writing, subscribing,
5
+ * and creating derived hooks or observable fragments.
6
+ */
7
+ export type StateApi<State, StateDispatch, StateMutator, Metadata extends BaseMetadata> = {
2
8
  /**
3
- * @description you can add an identifier to the state call
4
- * this will show up in the devtools to help you identify from where the state change was called
9
+ * Returns the metadata
10
+ * Metadata is additional non reactive information associated with the global state
5
11
  */
6
- identifier?: string | undefined;
12
+ getMetadata: MetadataGetter<Metadata>;
7
13
  /**
8
- * @deprecated forceUpdate normally should not be used inside components
9
- * Use this flag just in custom implementations of the global store
14
+ * Sets the metadata value
15
+ * The metadata value is not reactive and wont trigger re-renders
10
16
  */
11
- forceUpdate?: boolean | undefined;
12
- }) => void;
13
- export type HookExtensions<State, StateMutator, Metadata extends BaseMetadata | unknown> = {
17
+ setMetadata: MetadataSetter<Metadata>;
18
+ /**
19
+ * @description Contains the generated action functions if custom actions are defined.
20
+ * When actions exist, direct state mutation via `setState` is disabled and setState will be `null`.
21
+ * If no actions are provided, this property is `null`.
22
+ */
23
+ actions: StateMutator extends AnyFunction ? null : StateMutator;
24
+ /**
25
+ * @description Provides direct access to the state updater when no custom actions are defined.
26
+ * When actions exist, direct state mutation via `setState` is disabled and this property will be `null`.
27
+ * If no actions are provided, this property exposes the `setState` function.
28
+ */
29
+ setState: StateMutator extends AnyFunction ? StateDispatch : null;
14
30
  /**
15
- * @description Return the state controls of the hook
16
- * This selectors includes:
17
- * - stateRetriever: a function to get the current state or subscribe a callback to the state changes
18
- * - stateMutator: a function to set the state or a collection of actions if you pass an storeActionsConfig configuration
19
- * - metadataRetriever: a function to get the metadata of the global state
31
+ * @description Get the current state value
20
32
  */
21
- stateControls: () => Readonly<[
22
- retriever: StateGetter<State>,
23
- mutator: StateMutator,
24
- metadata: MetadataGetter<Metadata>
25
- ]>;
33
+ getState: () => State;
34
+ /**
35
+ * @description Subscribe to the state changes
36
+ * You can subscribe to the whole state or to a fragment of the state by passing a selector as first parameter,
37
+ * this can be used in non react environments to listen to the state changes
38
+ */
39
+ subscribe: SubscribeToState<State>;
26
40
  /***
27
41
  * @description Creates a new hooks that returns the result of the selector passed as a parameter
28
42
  * Your can create selector hooks of other selectors hooks and extract as many derived states as or fragments of the state as you want
29
43
  * The selector hook will be evaluated only if the result of the selector changes and the equality function returns false
30
44
  * you can customize the equality function by passing the isEqualRoot and isEqual parameters
31
45
  */
32
- createSelectorHook: <Derivate>(this: StateHook<State, StateMutator, Metadata>, selector: (state: State) => Derivate, args?: Omit<UseHookConfig<Derivate, State>, 'dependencies'> & {
33
- name?: string;
34
- }) => StateHook<Derivate, StateMutator, Metadata>;
35
- createObservable: <Fragment>(this: StateHook<State, StateMutator, Metadata>, mainSelector: (state: State) => Fragment, args?: {
36
- isEqual?: (current: Fragment, next: Fragment) => boolean;
37
- isEqualRoot?: (current: State, next: State) => boolean;
46
+ createSelectorHook: <Selection>(selector: (state: State) => Selection, args?: Omit<UseHookConfig<Selection, State>, 'dependencies'> & {
38
47
  name?: string;
39
- }) => ObservableFragment<Fragment>;
40
- removeSubscriptions: () => void;
41
- dispose: () => void;
42
- };
43
- export type ObservableFragment<State> = StateGetter<State> & {
44
- createObservable: <Fragment>(this: ObservableFragment<State>, mainSelector: (state: State) => Fragment, args?: {
45
- isEqual?: (current: Fragment, next: Fragment) => boolean;
48
+ }) => StateHook<Selection, StateDispatch, StateMutator, Metadata>;
49
+ /**
50
+ * @description Creates a function that allows you to subscribe to a fragment of the state
51
+ * The observable selection will notify the subscribers only if the fragment changes and the equality function returns false
52
+ * you can customize the equality function by passing the isEqualRoot and isEqual parameters
53
+ */
54
+ createObservable: <Selection>(this: StateApi<State, StateDispatch, StateMutator, Metadata>, selector: (state: State) => Selection, args?: {
55
+ isEqual?: (current: Selection, next: Selection) => boolean;
46
56
  isEqualRoot?: (current: State, next: State) => boolean;
57
+ /**
58
+ * @description Name of the observable fragment for debugging purposes
59
+ */
47
60
  name?: string;
48
- }) => ObservableFragment<Fragment>;
49
- removeSubscriptions: () => void;
50
- _name: string | undefined;
61
+ }) => ObservableFragment<Selection, StateDispatch, StateMutator, Metadata>;
51
62
  };
52
- export interface StateHook<State, StateMutator, Metadata extends BaseMetadata | unknown> extends HookExtensions<State, StateMutator, Metadata> {
63
+ /**
64
+ * @description Function that allows you to subscribe to a fragment of the state
65
+ */
66
+ export type ObservableFragment<State, StateDispatch, StateMutator, Metadata extends BaseMetadata> = SubscribeToState<State> & StateApi<State, StateDispatch, StateMutator, Metadata>;
67
+ export interface StateHook<State, StateDispatch, StateMutator, Metadata extends BaseMetadata> extends StateApi<State, StateDispatch, StateMutator, Metadata> {
53
68
  (): Readonly<[state: State, stateMutator: StateMutator, metadata: Metadata]>;
54
- <Derivate>(selector: (state: State) => Derivate, dependencies?: unknown[]): Readonly<[
55
- state: Derivate,
56
- stateMutator: StateMutator,
57
- metadata: Metadata
58
- ]>;
59
- <Derivate>(selector: (state: State) => Derivate, config?: UseHookConfig<Derivate, State>): Readonly<[
60
- state: Derivate,
61
- stateMutator: StateMutator,
62
- metadata: Metadata
63
- ]>;
69
+ <Derivate>(selector: (state: State) => Derivate, dependencies?: unknown[]): Readonly<[state: Derivate, stateMutator: StateMutator, metadata: Metadata]>;
70
+ <Derivate>(selector: (state: State) => Derivate, config?: UseHookConfig<Derivate, State>): Readonly<[state: Derivate, stateMutator: StateMutator, metadata: Metadata]>;
64
71
  }
65
- export type MetadataSetter<Metadata extends BaseMetadata | unknown> = (setter: Metadata | ((metadata: Metadata) => Metadata)) => void;
72
+ export type MetadataSetter<Metadata extends BaseMetadata> = (setter: Metadata | ((metadata: Metadata) => Metadata)) => void;
66
73
  export type StateChanges<State> = {
67
74
  state: State;
68
75
  previousState: State | undefined;
@@ -71,31 +78,51 @@ export type StateChanges<State> = {
71
78
  /**
72
79
  * API for the actions of the global states
73
80
  **/
74
- export type StoreTools<State, Metadata extends BaseMetadata | unknown = BaseMetadata, Actions extends undefined | unknown | Record<string, (...args: any[]) => any> = unknown> = {
81
+ export type StoreTools<State, Metadata extends BaseMetadata = BaseMetadata, Actions extends undefined | unknown | Record<string, AnyFunction> = unknown> = {
75
82
  setMetadata: MetadataSetter<Metadata>;
76
- setState: StateSetter<State>;
77
- getState: StateGetter<State>;
83
+ setState: React.Dispatch<React.SetStateAction<State>>;
84
+ getState: () => State;
85
+ subscribe: SubscribeToState<State>;
78
86
  getMetadata: () => Metadata;
79
87
  actions: Actions;
80
88
  };
81
89
  /**
82
90
  * contract for the storeActionsConfig configuration
83
91
  */
84
- export interface ActionCollectionConfig<State, Metadata extends BaseMetadata | unknown, ThisAPI = Record<string, (...parameters: any[]) => unknown>> {
92
+ export interface ActionCollectionConfig<State, Metadata extends BaseMetadata, ThisAPI = Record<string, (...parameters: any[]) => unknown>> {
85
93
  readonly [key: string]: {
86
94
  (this: ThisAPI, ...parameters: any[]): (this: ThisAPI, storeTools: StoreTools<State, Metadata, Record<string, (...parameters: any[]) => unknown | void>>) => unknown | void;
87
95
  };
88
96
  }
89
- export type ActionCollectionResult<State, Metadata extends BaseMetadata | unknown, ActionsConfig extends ActionCollectionConfig<State, Metadata>> = {
97
+ export type ActionCollectionResult<State, Metadata extends BaseMetadata, ActionsConfig extends ActionCollectionConfig<State, Metadata>> = {
90
98
  [key in keyof ActionsConfig]: {
91
99
  (...params: Parameters<ActionsConfig[key]>): ReturnType<ReturnType<ActionsConfig[key]>>;
92
100
  };
93
101
  };
94
- export type GlobalStoreCallbacks<State, Metadata extends BaseMetadata | unknown> = {
102
+ /**
103
+ * Callbacks for the global store lifecycle events
104
+ */
105
+ export type GlobalStoreCallbacks<State, Metadata extends BaseMetadata> = {
106
+ /**
107
+ * @description Called when the store is initialized
108
+ */
95
109
  onInit?: (args: StoreTools<State, Metadata>) => void;
110
+ /**
111
+ * @description Called when the state has changed
112
+ */
96
113
  onStateChanged?: (args: StoreTools<State, Metadata> & StateChanges<State>) => void;
114
+ /**
115
+ * @description Called when a new subscription is created
116
+ */
97
117
  onSubscribed?: (args: StoreTools<State, Metadata>, subscription: SubscriberParameters) => void;
118
+ /**
119
+ * @description Called to determine whether to prevent a state change
120
+ */
98
121
  computePreventStateChange?: (args: StoreTools<State, Metadata> & StateChanges<State>) => boolean;
122
+ /**
123
+ * @description Called when the store is unmounted, only applicable in context stores
124
+ */
125
+ onUnMount?: (store: StateApi<State, any, any, Metadata>) => void;
99
126
  };
100
127
  export type UseHookConfig<State, TRoot = any> = {
101
128
  isEqual?: (current: State, next: State) => boolean;
@@ -114,24 +141,24 @@ export type SubscribeCallbackConfig<State> = UseHookConfig<State> & {
114
141
  */
115
142
  export type SubscribeCallback<State> = (state: State) => void;
116
143
  /**
117
- * get the current state or subscribe to the state changes
144
+ * @description Subscribe to the state changes
145
+ * You can subscribe to the whole state or to a fragment of the state by passing a selector as first parameter
146
+ * This can be used in non react environments to listen to the state changes
118
147
  */
119
- export type StateGetter<State> = {
120
- (): State;
148
+ export type SubscribeToState<State> = {
121
149
  (subscription: SubscribeCallback<State>, config?: SubscribeCallbackConfig<State>): UnsubscribeCallback;
122
150
  <TDerivate>(selector: SelectorCallback<State, TDerivate>, subscription: SubscribeCallback<TDerivate>, config?: SubscribeCallbackConfig<TDerivate>): UnsubscribeCallback;
123
151
  };
124
152
  export type BaseMetadata = Record<string, unknown>;
125
- export type MetadataGetter<Metadata extends BaseMetadata | unknown> = () => Metadata;
126
- export type CustomGlobalHookBuilderParams<TCustomConfig extends BaseMetadata | unknown, Metadata extends BaseMetadata | unknown> = {
153
+ export type MetadataGetter<Metadata extends BaseMetadata> = () => Metadata;
154
+ export type CustomGlobalHookBuilderParams<TCustomConfig extends BaseMetadata | unknown, Metadata extends BaseMetadata> = {
127
155
  onInitialize?: (args: StoreTools<unknown, Metadata, unknown>, config: TCustomConfig | undefined) => void;
128
156
  onChange?: (args: StoreTools<unknown, Metadata, unknown> & StateChanges<unknown>, config: TCustomConfig | undefined) => void;
129
157
  };
130
158
  export type SelectorCallback<State, TDerivate> = (state: State) => TDerivate;
131
159
  export type SubscriberParameters = {
132
- subscriptionId: string;
133
- selector: SelectorCallback<unknown, unknown> | undefined;
134
- getConfig: () => UseHookConfig<unknown> | SubscribeCallbackConfig<unknown> | undefined;
160
+ selector: SelectorCallback<any, any> | undefined;
161
+ getConfig: () => UseHookConfig<any> | SubscribeCallbackConfig<any> | undefined;
135
162
  currentState: unknown;
136
163
  callback: SubscriptionCallback | (() => void);
137
164
  };
package/webpack.config.js CHANGED
@@ -5,15 +5,12 @@ const individualEntries = {
5
5
  createContext: './src/createContext.ts',
6
6
  GlobalStore: './src/GlobalStore.ts',
7
7
  GlobalStoreAbstract: './src/GlobalStoreAbstract.ts',
8
- createCustomGlobalState: './src/createCustomGlobalState.ts',
9
8
  createGlobalState: './src/createGlobalState.ts',
10
9
  types: './src/types.ts',
11
10
  isRecord: './src/isRecord.ts',
12
11
  shallowCompare: './src/shallowCompare.ts',
13
12
  throwWrongKeyOnActionCollectionConfig: './src/throwWrongKeyOnActionCollectionConfig.ts',
14
13
  uniqueId: './src/uniqueId.ts',
15
- useStableState: './src/useStableState.ts',
16
- generateStackHash: './src/generateStackHash.ts',
17
14
  };
18
15
 
19
16
  const getExternalsForEntries = () => {
@@ -1,23 +0,0 @@
1
- import type { ActionCollectionConfig, StateSetter, ActionCollectionResult, StateHook, CustomGlobalHookBuilderParams, BaseMetadata, GlobalStoreCallbacks } from './types';
2
- export interface CustomCreateGlobalState<TCustomConfig extends BaseMetadata | unknown, InheritMetadata extends BaseMetadata | unknown = BaseMetadata> {
3
- <State>(state: State): StateHook<State, StateSetter<State>, BaseMetadata>;
4
- <State, Metadata extends BaseMetadata | unknown, ActionsConfig extends ActionCollectionConfig<State, InheritMetadata & Metadata> | null | {}, PublicStateMutator = keyof ActionsConfig extends never | undefined ? StateSetter<State> : ActionCollectionResult<State, InheritMetadata & Metadata, NonNullable<ActionsConfig>>>(state: State, args: {
5
- name?: string;
6
- metadata?: Metadata;
7
- callbacks?: GlobalStoreCallbacks<State, InheritMetadata & Metadata>;
8
- actions?: ActionsConfig;
9
- config?: TCustomConfig;
10
- }): StateHook<State, PublicStateMutator, InheritMetadata & Metadata>;
11
- <State, Metadata extends BaseMetadata | unknown, ActionsConfig extends Readonly<ActionCollectionConfig<State, InheritMetadata & Metadata>>>(state: State, args: {
12
- name?: string;
13
- metadata?: Metadata;
14
- callbacks?: GlobalStoreCallbacks<State, InheritMetadata & Metadata>;
15
- actions: ActionsConfig;
16
- config?: TCustomConfig;
17
- }): StateHook<State, ActionCollectionResult<State, InheritMetadata & Metadata, ActionsConfig>, InheritMetadata & Metadata>;
18
- }
19
- /**
20
- * @description Simple custom global state hook builder
21
- */
22
- export declare const createCustomGlobalState: <TCustomConfig extends BaseMetadata | unknown, InheritMetadata extends BaseMetadata | unknown = BaseMetadata>({ onInitialize, onChange, }: CustomGlobalHookBuilderParams<TCustomConfig, InheritMetadata>) => CustomCreateGlobalState<TCustomConfig, InheritMetadata>;
23
- export default createCustomGlobalState;
@@ -1 +0,0 @@
1
- var e;e=e=>(()=>{"use strict";var t={154:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.createCustomGlobalState=void 0;var a=o(670);t.createCustomGlobalState=function(e){var t=e.onInitialize,o=e.onChange;return function(e){var l=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=l.callbacks,r=function(e,t){var o={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&t.indexOf(a)<0&&(o[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var l=0;for(a=Object.getOwnPropertySymbols(e);l<a.length;l++)t.indexOf(a[l])<0&&Object.prototype.propertyIsEnumerable.call(e,a[l])&&(o[a[l]]=e[a[l]])}return o}(l,["callbacks"]);return(0,a.createGlobalState)(e,Object.assign(Object.assign({},r),{callbacks:Object.assign(Object.assign({},null!=n?n:{}),{onInit:function(e){var o;null==t||t(e,null==r?void 0:r.config),null===(o=null==n?void 0:n.onInit)||void 0===o||o.call(n,e)},onStateChanged:function(e){var t;null==o||o(e,null==r?void 0:r.config),null===(t=null==n?void 0:n.onStateChanged)||void 0===t||t.call(n,e)}})}))}},t.default=t.createCustomGlobalState},670:t=>{t.exports=e}},o={};return function e(a){var l=o[a];if(void 0!==l)return l.exports;var n=o[a]={exports:{}};return t[a](n,n.exports,e),n.exports}(154)})(),"object"==typeof exports&&"object"==typeof module?module.exports=e(require("./createGlobalState.js")):"function"==typeof define&&define.amd?define(["./createGlobalState.js"],e):"object"==typeof exports?exports["react-hooks-global-states"]=e(require("./createGlobalState.js")):this["react-hooks-global-states"]=e(this["./createGlobalState.js"]);
@@ -1,2 +0,0 @@
1
- export declare const generateStackHash: (stack: string) => string;
2
- export default generateStackHash;
@@ -1 +0,0 @@
1
- var e;e=()=>(()=>{"use strict";var e={};return((e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.generateStackHash=void 0,t.generateStackHash=function(e){if(!e.trim())return"unknown";e=e.replace(/\s/g,"");for(var t=2166136261,o=0;o<e.length;o++)t^=e.charCodeAt(o),t*=16777619,t&=4294967295;return function(e){for(var t="";e>0;)t="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"[e%62]+t,e=Math.floor(e/62);return t||"0"}(t>>>0)},t.default=t.generateStackHash})(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();
@@ -1,14 +0,0 @@
1
- type Cleanup = () => void;
2
- type StateBuilder<T> = () => [state: T, cleanup?: Cleanup];
3
- type RefObject<T> = {
4
- current: T;
5
- };
6
- /**
7
- * @deprecated
8
- * - Only one stable initial render
9
- * - Only one stable cleanup every time dependencies change
10
- * - Initial render doesn't trigger cleanup
11
- * - Starts cold, returns null until the first render or fallback if provided
12
- */
13
- export declare const useStableState: <T, F extends T | never>(builder: StateBuilder<T>, dependencies: unknown[], fallbackArg?: F) => F extends T ? RefObject<T> : RefObject<T> | null;
14
- export default useStableState;
package/useStableState.js DELETED
@@ -1 +0,0 @@
1
- var t;t=t=>(()=>{"use strict";var e={155:e=>{e.exports=t},163:(t,e,r)=>{function n(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,a,u,l=[],i=!0,c=!1;try{if(a=(r=r.call(t)).next,0===e){if(Object(r)!==r)return;i=!1}else for(;!(i=(n=a.call(r)).done)&&(l.push(n.value),l.length!==e);i=!0);}catch(t){c=!0,o=t}finally{try{if(!i&&null!=r.return&&(u=r.return(),Object(u)!==u))return}finally{if(c)throw o}}return l}}(t,e)||o(t,e)||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.")}()}function o(t,e){if(t){if("string"==typeof t)return a(t,e);var r={}.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?a(t,e):void 0}}function a(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r<e;r++)n[r]=t[r];return n}Object.defineProperty(e,"__esModule",{value:!0}),e.useStableState=void 0;var u=r(155);e.useStableState=function(t,e,r){var l,i,c=n((0,u.useState)({}),2)[1],f=(0,u.useCallback)((function(){c({})}),[]),s=(0,u.useRef)({builder:t,stateRef:null,fallback:r?{current:r}:void 0,isMounted:!1});s.current.builder=t,(0,u.useEffect)((function(){var t=n((0,s.current.builder)(),2),e=t[0],r=t[1];if(s.current.stateRef={current:e},f(),s.current.isMounted)return function(){null==r||r()};s.current.isMounted=!0}),[f].concat(function(t){if(Array.isArray(t))return a(t)}(i=e)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(i)||o(i)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()));var d=s.current,b=d.stateRef,y=d.fallback;return null!==(l=null!=b?b:y)&&void 0!==l?l:null},e.default=e.useStableState}},r={};return function t(n){var o=r[n];if(void 0!==o)return o.exports;var a=r[n]={exports:{}};return e[n](a,a.exports,t),a.exports}(163)})(),"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define(["react"],t):"object"==typeof exports?exports["react-hooks-global-states"]=t(require("react")):this["react-hooks-global-states"]=t(this.react);