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/GlobalStore.d.ts +63 -32
- package/GlobalStore.js +1 -1
- package/GlobalStoreAbstract.d.ts +1 -1
- package/README.md +43 -24
- package/bundle.js +1 -1
- package/createContext.d.ts +200 -63
- package/createContext.js +1 -1
- package/createGlobalState.d.ts +134 -8
- package/createGlobalState.js +1 -1
- package/index.d.ts +2 -5
- package/package.json +4 -17
- package/shallowCompare.d.ts +43 -4
- package/types.d.ts +88 -61
- package/webpack.config.js +0 -3
- package/createCustomGlobalState.d.ts +0 -23
- package/createCustomGlobalState.js +0 -1
- package/generateStackHash.d.ts +0 -2
- package/generateStackHash.js +0 -1
- package/useStableState.d.ts +0 -14
- package/useStableState.js +0 -1
package/createContext.d.ts
CHANGED
|
@@ -1,104 +1,241 @@
|
|
|
1
|
-
import { type PropsWithChildren, Context as ReactContext } from 'react';
|
|
2
|
-
import type { ActionCollectionConfig,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
getMetadata: () => Metadata;
|
|
1
|
+
import React, { type PropsWithChildren, Context as ReactContext } from 'react';
|
|
2
|
+
import type { ActionCollectionConfig, ActionCollectionResult, BaseMetadata, MetadataSetter, GlobalStoreCallbacks, UseHookConfig, SubscribeToState, AnyFunction } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* @description Context API
|
|
5
|
+
*/
|
|
6
|
+
export type ContextApi<State, Actions, Metadata extends BaseMetadata> = {
|
|
8
7
|
actions: Actions;
|
|
8
|
+
getMetadata: () => Metadata;
|
|
9
|
+
getState: () => State;
|
|
10
|
+
setMetadata: MetadataSetter<Metadata>;
|
|
11
|
+
setState: React.Dispatch<React.SetStateAction<State>>;
|
|
12
|
+
subscribe: SubscribeToState<State>;
|
|
9
13
|
};
|
|
10
|
-
export type
|
|
11
|
-
value?: State | ((initialValue: State) => State);
|
|
14
|
+
export type ContextProviderExtensions<State, Actions, Metadata extends BaseMetadata> = {
|
|
12
15
|
/**
|
|
13
|
-
* Callback called when the context is created.
|
|
14
|
-
*/
|
|
15
|
-
onCreated?: (context: Context<State, Actions, Metadata>) => void;
|
|
16
|
-
}>> & {
|
|
17
|
-
/**F
|
|
18
16
|
* Creates a provider wrapper which allows to capture the context value,
|
|
19
17
|
* useful for testing purposes.
|
|
18
|
+
* @param options configuration options for the provider wrapper
|
|
19
|
+
* @param options.value optional initial state or initializer function
|
|
20
|
+
* @param options.onCreated optional callback invoked after the context is created
|
|
21
|
+
* @returns an object containing the wrapper component and a reference to the context value
|
|
20
22
|
*/
|
|
21
23
|
makeProviderWrapper: (options?: {
|
|
22
24
|
value?: State | ((initialValue: State) => State);
|
|
23
|
-
onCreated?: (context:
|
|
25
|
+
onCreated?: (context: ContextApi<State, Actions, Metadata>) => void;
|
|
24
26
|
}) => {
|
|
27
|
+
/**
|
|
28
|
+
* Provider for the context
|
|
29
|
+
*/
|
|
25
30
|
wrapper: React.FC<PropsWithChildren<{
|
|
26
31
|
value?: State | ((initialValue: State) => State);
|
|
27
32
|
}>>;
|
|
28
33
|
/**
|
|
29
|
-
*
|
|
30
|
-
* context.current will hold the context value
|
|
34
|
+
* Reference to the current context value
|
|
31
35
|
*/
|
|
32
36
|
context: {
|
|
33
|
-
current:
|
|
37
|
+
current: ContextApi<State, Actions, Metadata>;
|
|
34
38
|
};
|
|
35
39
|
};
|
|
36
40
|
};
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export type
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
41
|
+
/**
|
|
42
|
+
* @description Creates a React context provider component for the given global state.
|
|
43
|
+
* @param value Optional initial state or initializer function, useful for testing.
|
|
44
|
+
* @param onCreated Optional callback invoked after the context is created, receiving the full context instance.
|
|
45
|
+
*/
|
|
46
|
+
export type ContextProvider<State, Actions, Metadata extends BaseMetadata> = React.FC<PropsWithChildren<{
|
|
47
|
+
value?: State | ((initialValue: State) => State);
|
|
48
|
+
onCreated?: (context: ContextApi<State, Actions, Metadata>) => void;
|
|
49
|
+
}>> & ContextProviderExtensions<State, Actions, Metadata>;
|
|
50
|
+
export interface ContextBaseHook<State, StateMutator, Metadata extends BaseMetadata> {
|
|
51
|
+
/**
|
|
52
|
+
* @description Retrieves the full state, state mutator (setState or actions), and metadata.
|
|
53
|
+
*/
|
|
48
54
|
(): Readonly<[state: State, stateMutator: StateMutator, metadata: Metadata]>;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
/**
|
|
56
|
+
* @description Retrieves a derived value from the state using the provided selector function.
|
|
57
|
+
* @param selector A function that selects a part of the state.
|
|
58
|
+
* @param dependencies Optional array of dependencies to control when the selector is re-evaluated.
|
|
59
|
+
* @returns A read-only tuple containing the derived state, state mutator (setState or actions), and metadata.
|
|
60
|
+
*/
|
|
61
|
+
<Derivate>(selector: (state: State) => Derivate, dependencies?: unknown[]): Readonly<[state: Derivate, stateMutator: StateMutator, metadata: Metadata]>;
|
|
62
|
+
/**
|
|
63
|
+
* @description Retrieves a derived value from the state using the provided selector function.
|
|
64
|
+
* @param selector A function that selects a part of the state.
|
|
65
|
+
* @param dependencies Optional array of dependencies to control when the selector is re-evaluated.
|
|
66
|
+
* @returns A read-only tuple containing the derived state, state mutator (setState or actions), and metadata.
|
|
67
|
+
*/
|
|
68
|
+
<Derivate>(selector: (state: State) => Derivate, config?: UseHookConfig<Derivate, State>): Readonly<[state: Derivate, stateMutator: StateMutator, metadata: Metadata]>;
|
|
59
69
|
}
|
|
60
|
-
|
|
70
|
+
/**
|
|
71
|
+
* @description Hook for accessing a context's state, mutator (setState or actions), and metadata.
|
|
72
|
+
* @returns A read-only tuple containing:
|
|
73
|
+
* - state: the current state, or the derived value when a selector is used
|
|
74
|
+
* - stateMutator: a function or actions collection to update the state
|
|
75
|
+
* - metadata: the current context metadata
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```tsx
|
|
79
|
+
* // Simple usage (full state)
|
|
80
|
+
* const [state, setState] = useTodosContext();
|
|
81
|
+
*
|
|
82
|
+
* // With a selector (preferred for render isolation)
|
|
83
|
+
* const [todos, actions] = useTodosContext(s => s.todos);
|
|
84
|
+
*
|
|
85
|
+
* actions.setTodos(next);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export interface ContextHook<State, StateMutator, Metadata extends BaseMetadata> extends HookExtensions<State, StateMutator, Metadata>, ContextBaseHook<State, StateMutator, Metadata> {
|
|
61
89
|
}
|
|
62
|
-
export type HookExtensions<State, StateMutator, Metadata extends BaseMetadata
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
90
|
+
export type HookExtensions<State, StateMutator, Metadata extends BaseMetadata> = {
|
|
91
|
+
/**
|
|
92
|
+
* @description Creates a derived hook that subscribes to a selected fragment of the context state.
|
|
93
|
+
* The selector determines which portion of the state the new hook exposes.
|
|
94
|
+
* This hook must be used within the corresponding context provider.
|
|
95
|
+
*
|
|
96
|
+
* @param selector A function that selects a part of the state.
|
|
97
|
+
* @param args Optional configuration for the derived hook, including:
|
|
98
|
+
* - isEqual: A function to compare the current and next selected fragment for equality.
|
|
99
|
+
* - isEqualRoot: A function to compare the entire state for equality.
|
|
100
|
+
* - name: An optional name for debugging purposes.
|
|
101
|
+
* @returns A new context hook that provides access to the selected fragment of the state,
|
|
102
|
+
* along with the state mutator and metadata.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```tsx
|
|
106
|
+
* const useTodos = createContext({
|
|
107
|
+
* todos: [],
|
|
108
|
+
* filter: '',
|
|
109
|
+
* }, {
|
|
110
|
+
* actions: {
|
|
111
|
+
* setFilter(filter: string) {
|
|
112
|
+
* ...
|
|
113
|
+
* });
|
|
114
|
+
*
|
|
115
|
+
* const useFilter = useTodos.createSelectorHook((state) => {
|
|
116
|
+
* return state.filter;
|
|
117
|
+
* });
|
|
118
|
+
*
|
|
119
|
+
* function FilterComponent() {
|
|
120
|
+
* // The selector only listen to the selected fragment (filter)
|
|
121
|
+
* // But has access to the full actions collection
|
|
122
|
+
* const [filter, { setFilter }] = useFilter();
|
|
123
|
+
*
|
|
124
|
+
* return (
|
|
125
|
+
* <input
|
|
126
|
+
* value={filter}
|
|
127
|
+
* onChange={(e) => setFilter(e.target.value)}
|
|
128
|
+
* />
|
|
129
|
+
* );
|
|
130
|
+
* }
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
67
133
|
createSelectorHook: <Derivate>(this: ContextHook<State, StateMutator, Metadata>, selector: (state: State) => Derivate, args?: Omit<UseHookConfig<Derivate, State>, 'dependencies'> & {
|
|
68
134
|
name?: string;
|
|
69
135
|
}) => ContextBaseHook<Derivate, StateMutator, Metadata>;
|
|
136
|
+
/**
|
|
137
|
+
* @description Hook that provides non-reactive access to the context API.
|
|
138
|
+
* This allows direct interaction with the context’s state, metadata, and actions
|
|
139
|
+
* without triggering component re-renders.
|
|
140
|
+
* @returns An object containing the context API methods and properties.
|
|
141
|
+
*/
|
|
142
|
+
api: () => ContextApi<State, StateMutator, Metadata>;
|
|
70
143
|
};
|
|
71
144
|
export interface CreateContext {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
145
|
+
/**
|
|
146
|
+
* @description Creates a highly granular React context with its associated provider and state hook.
|
|
147
|
+
* @param value Initial state value or initializer function.
|
|
148
|
+
* @returns An object containing:
|
|
149
|
+
* - **`use`** — A custom hook to read and mutate the context state.
|
|
150
|
+
* Supports selectors for granular subscriptions and returns `[state, stateMutator, metadata]`.
|
|
151
|
+
* - **`Provider`** — A React component that provides the context to its descendants.
|
|
152
|
+
* It accepts an optional initial value and `onCreated` callback.
|
|
153
|
+
* - **`Context`** — The raw React `Context` object for advanced usage, such as integration with
|
|
154
|
+
* external tools or non-React consumers.
|
|
155
|
+
*/
|
|
156
|
+
<State>(value: State | (() => State)): {
|
|
157
|
+
use: ContextHook<State, React.Dispatch<React.SetStateAction<State>>, BaseMetadata>;
|
|
158
|
+
Provider: ContextProvider<State, null, BaseMetadata>;
|
|
159
|
+
Context: ReactContext<ContextHook<State, React.Dispatch<React.SetStateAction<State>>, BaseMetadata> | null>;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* @description Creates a highly granular React context with its associated provider and state hook.
|
|
163
|
+
* @param value Initial state value or initializer function.
|
|
164
|
+
* @param args Additional configuration for the context.
|
|
165
|
+
* @param args.name Optional name for debugging purposes.
|
|
166
|
+
* @param args.metadata Optional non-reactive metadata associated with the state.
|
|
167
|
+
* @param args.callbacks Optional lifecycle callbacks for the context.
|
|
168
|
+
* @param args.actions Optional actions to restrict state mutations [if provided `setState` will be nullified].
|
|
169
|
+
* @returns An object containing:
|
|
170
|
+
* - **`use`** — A custom hook to read and mutate the context state.
|
|
171
|
+
* Supports selectors for granular subscriptions and returns `[state, stateMutator, metadata]`.
|
|
172
|
+
* - **`Provider`** — A React component that provides the context to its descendants.
|
|
173
|
+
* It accepts an optional initial value and `onCreated` callback.
|
|
174
|
+
* - **`Context`** — The raw React `Context` object for advanced usage, such as integration with
|
|
175
|
+
* external tools or non-React consumers.
|
|
176
|
+
*/
|
|
177
|
+
<State, Metadata extends BaseMetadata, ActionsConfig extends ActionCollectionConfig<State, Metadata> | null | {}, PublicStateMutator = keyof ActionsConfig extends never | undefined ? React.Dispatch<React.SetStateAction<State>> : ActionCollectionResult<State, Metadata, NonNullable<ActionsConfig>>>(value: State | (() => State), args: {
|
|
78
178
|
name?: string;
|
|
79
179
|
metadata?: Metadata | (() => Metadata);
|
|
80
180
|
callbacks?: GlobalStoreCallbacks<State, Metadata> & {
|
|
81
181
|
onUnMount?: () => void;
|
|
82
182
|
};
|
|
83
183
|
actions?: ActionsConfig;
|
|
84
|
-
}):
|
|
85
|
-
ContextHook<State, PublicStateMutator, Metadata
|
|
86
|
-
ContextProvider<State, PublicStateMutator, Metadata
|
|
87
|
-
ReactContext<
|
|
88
|
-
|
|
89
|
-
|
|
184
|
+
}): {
|
|
185
|
+
use: ContextHook<State, PublicStateMutator, Metadata>;
|
|
186
|
+
Provider: ContextProvider<State, PublicStateMutator, Metadata>;
|
|
187
|
+
Context: ReactContext<ContextHook<State, PublicStateMutator, Metadata> | null>;
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* @description Creates a highly granular React context with its associated provider and state hook.
|
|
191
|
+
* @param value Initial state value or initializer function.
|
|
192
|
+
* @param args Additional configuration for the context.
|
|
193
|
+
* @param args.name Optional name for debugging purposes.
|
|
194
|
+
* @param args.metadata Optional non-reactive metadata associated with the state.
|
|
195
|
+
* @param args.callbacks Optional lifecycle callbacks for the context.
|
|
196
|
+
* @param args.actions Optional actions to restrict state mutations [if provided `setState` will be nullified].
|
|
197
|
+
* @returns An object containing:
|
|
198
|
+
* - **`use`** — A custom hook to read and mutate the context state.
|
|
199
|
+
* Supports selectors for granular subscriptions and returns `[state, stateMutator, metadata]`.
|
|
200
|
+
* - **`Provider`** — A React component that provides the context to its descendants.
|
|
201
|
+
* It accepts an optional initial value and `onCreated` callback.
|
|
202
|
+
* - **`Context`** — The raw React `Context` object for advanced usage, such as integration with
|
|
203
|
+
* external tools or non-React consumers.
|
|
204
|
+
*/
|
|
205
|
+
<State, Metadata extends BaseMetadata, ActionsConfig extends ActionCollectionConfig<State, Metadata>>(value: State | (() => State), args: {
|
|
90
206
|
name?: string;
|
|
91
207
|
metadata?: Metadata | (() => Metadata);
|
|
92
208
|
callbacks?: GlobalStoreCallbacks<State, Metadata> & {
|
|
93
209
|
onUnMount?: () => void;
|
|
94
210
|
};
|
|
95
211
|
actions: ActionsConfig;
|
|
96
|
-
}):
|
|
97
|
-
ContextHook<State, ActionCollectionResult<State, Metadata, ActionsConfig>, Metadata
|
|
98
|
-
ContextProvider<State, ActionCollectionResult<State, Metadata, ActionsConfig>, Metadata
|
|
99
|
-
ReactContext<
|
|
100
|
-
|
|
212
|
+
}): {
|
|
213
|
+
use: ContextHook<State, ActionCollectionResult<State, Metadata, ActionsConfig>, Metadata>;
|
|
214
|
+
Provider: ContextProvider<State, ActionCollectionResult<State, Metadata, ActionsConfig>, Metadata>;
|
|
215
|
+
Context: ReactContext<ContextHook<State, ActionCollectionResult<State, Metadata, ActionsConfig>, Metadata> | null>;
|
|
216
|
+
};
|
|
101
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* @description Creates a highly granular React context with its associated provider and state hook.
|
|
220
|
+
* Unlike the native `React.createContext`, this version provides fine-grained reactivity and supports
|
|
221
|
+
* state selection, metadata handling, and optional custom actions for controlled mutations.
|
|
222
|
+
*
|
|
223
|
+
* Components using the generated hook only re-render when the selected part of the state changes,
|
|
224
|
+
* making it efficient for large or deeply nested state trees.
|
|
225
|
+
*/
|
|
102
226
|
export declare const createContext: CreateContext;
|
|
103
|
-
|
|
227
|
+
/**
|
|
228
|
+
* @description Infers the context API type
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```ts
|
|
232
|
+
* const counter = createContext(0);
|
|
233
|
+
*
|
|
234
|
+
* type CounterContextApi = InferContextApi<typeof counter.Context>;
|
|
235
|
+
*
|
|
236
|
+
* // Equivalent to:
|
|
237
|
+
* ContextApi<number, React.Dispatch<React.SetStateAction<number>>, BaseMetadata>;
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
export type InferContextApi<Context extends ReactContext<ContextHook<any, any, any> | null>> = NonNullable<React.ContextType<Context>> extends ContextHook<infer State, infer StateMutator, infer Metadata> ? ContextApi<State, StateMutator extends AnyFunction ? null : StateMutator, Metadata> : never;
|
|
104
241
|
export default createContext;
|
package/createContext.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e,t;e=this,t=(e,t,r,o)=>(()=>{"use strict";var n={155:t=>{t.exports=e},506:e=>{e.exports=t},639:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.createContext=void 0;var o=r(155),n=r(778),a=r(506),i=r(773);t.createContext=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=(0,o.createContext)(null),u=function(u){var s=u.children,l=u.value,c=u.onCreated,f=(0,o.useMemo)((function(){var r,o=function(){return(0,a.isFunction)(e)?e():e},u=(0,i.isNil)(l)?o():(0,a.isFunction)(l)?l(o()):l
|
|
1
|
+
var e,t;e=this,t=(e,t,r,o)=>(()=>{"use strict";var n={155:t=>{t.exports=e},506:e=>{e.exports=t},639:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.createContext=void 0;var o=r(155),n=r(778),a=r(506),i=r(773);t.createContext=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=(0,o.createContext)(null),u=function(u){var s=u.children,l=u.value,c=u.onCreated,f=(0,o.useMemo)((function(){var r,o=function(){return(0,a.isFunction)(e)?e():e},u=(0,i.isNil)(l)?o():(0,a.isFunction)(l)?l(o()):l;return new n.GlobalStore(u,Object.assign(Object.assign({},t),{metadata:null!==(r=(0,a.isFunction)(t.metadata)?t.metadata():t.metadata)&&void 0!==r?r:{}}))}),[]);return(0,o.useEffect)((function(){return function(){var e,t,r,o;null===(t=null===(e=f.callbacks)||void 0===e?void 0:e.onUnMount)||void 0===t||t.call(e,f),null===(o=(r=f).__onUnMountContext)||void 0===o||o.call(r,f),f.dispose()}}),[f]),null==c||c(f.getConfigCallbackParam()),(0,o.createElement)(r.Provider,{value:f.use},s)},s={makeProviderWrapper:function(e){var t={current:void 0};return{wrapper:function(r){var n=r.children;return(0,o.createElement)(u,{value:null==e?void 0:e.value,onCreated:function(r){var o;t.current=r,null===(o=null==e?void 0:e.onCreated)||void 0===o||o.call(e,r)}},n)},context:t}}},l=function(){var e=(0,o.useContext)(r);if(!e)throw new Error("use hook must be used within a ContextProvider");return e.apply(void 0,arguments)},c={createSelectorHook:function(e,t){return function(){var n=(0,o.useContext)(r);if((0,i.isNil)(n))throw new Error("SelectorHook must be used within a ContextProvider");var a=(0,o.useRef)(e);a.current=e;var u=(0,o.useMemo)((function(){return n.createSelectorHook((function(){return a.current.apply(a,arguments)}),t)}),[n]);return(0,o.useEffect)((function(){return function(){null==u||u.dispose()}}),[u]),u.apply(void 0,arguments)}},api:function(){var e=(0,o.useContext)(r);if(!e)throw new Error("api hook must be used within a ContextProvider");return e}};return Object.assign(u,s),Object.assign(l,c),{use:l,Provider:u,Context:r}},t.default=t.createContext},773:e=>{e.exports=r},778:e=>{e.exports=o}},a={};return function e(t){var r=a[t];if(void 0!==r)return r.exports;var o=a[t]={exports:{}};return n[t](o,o.exports,e),o.exports}(639)})(),"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react"),require("json-storage-formatter/isFunction"),require("json-storage-formatter/isNil"),require("./GlobalStore.js")):"function"==typeof define&&define.amd?define(["react","json-storage-formatter/isFunction","json-storage-formatter/isNil","./GlobalStore.js"],t):"object"==typeof exports?exports["react-hooks-global-states"]=t(require("react"),require("json-storage-formatter/isFunction"),require("json-storage-formatter/isNil"),require("./GlobalStore.js")):e["react-hooks-global-states"]=t(e.react,e["json-storage-formatter/isFunction"],e["json-storage-formatter/isNil"],e["./GlobalStore.js"]);
|
package/createGlobalState.d.ts
CHANGED
|
@@ -1,19 +1,145 @@
|
|
|
1
|
-
import type { ActionCollectionConfig,
|
|
1
|
+
import type { ActionCollectionConfig, ActionCollectionResult, StateHook, BaseMetadata, GlobalStoreCallbacks } from './types';
|
|
2
2
|
export interface CreateGlobalState {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Creates a global state hook.
|
|
5
|
+
* @param state initial state value
|
|
6
|
+
* @returns a state hook for your components
|
|
7
|
+
* @example
|
|
8
|
+
* const useCounter = createGlobalState(0);
|
|
9
|
+
*
|
|
10
|
+
* function Counter() {
|
|
11
|
+
* const [count, setCount] = useCounter();
|
|
12
|
+
* return (
|
|
13
|
+
* <div>
|
|
14
|
+
* <p>Count: {count}</p>
|
|
15
|
+
* <button onClick={() =>
|
|
16
|
+
* setCount(prev => prev + 1)
|
|
17
|
+
* }>Increment</button>
|
|
18
|
+
* </div>
|
|
19
|
+
* );
|
|
20
|
+
* }
|
|
21
|
+
*/
|
|
22
|
+
<State, StateDispatch = React.Dispatch<React.SetStateAction<State>>>(state: State): StateHook<State, StateDispatch, StateDispatch, BaseMetadata>;
|
|
23
|
+
/**
|
|
24
|
+
* Creates a global state hook that you can use across your application
|
|
25
|
+
* @param state initial state value
|
|
26
|
+
* @param args additional configuration for the global state
|
|
27
|
+
* @param args.name optional name for debugging purposes
|
|
28
|
+
* @param args.metadata optional non-reactive metadata associated with the state
|
|
29
|
+
* @param args.callbacks optional lifecycle callbacks for the global state
|
|
30
|
+
* @param args.actions optional actions to restrict state mutations [if provided `setState` will be nullified]
|
|
31
|
+
* @returns a state hook that you can use in your components
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* const useCounter = createGlobalState(0, {
|
|
36
|
+
* actions: {
|
|
37
|
+
* increase() {
|
|
38
|
+
* return ({ setState }) => {
|
|
39
|
+
* setState((c) => c + 1);
|
|
40
|
+
* };
|
|
41
|
+
* },
|
|
42
|
+
* decrease(amount: number) {
|
|
43
|
+
* return ({ setState }) => {
|
|
44
|
+
* setState((c) => c - amount);
|
|
45
|
+
* };
|
|
46
|
+
* },
|
|
47
|
+
* },
|
|
48
|
+
* });
|
|
49
|
+
*
|
|
50
|
+
* function Counter() {
|
|
51
|
+
* const [count, {
|
|
52
|
+
* increase,
|
|
53
|
+
* decrease
|
|
54
|
+
* }] = useCounter();
|
|
55
|
+
*
|
|
56
|
+
* return (
|
|
57
|
+
* <div>
|
|
58
|
+
* <p>Count: {count}</p>
|
|
59
|
+
* <button onClick={increase}>
|
|
60
|
+
* Increment
|
|
61
|
+
* </button>
|
|
62
|
+
* <button onClick={() => {
|
|
63
|
+
* decrease(1);
|
|
64
|
+
* }}>
|
|
65
|
+
* Decrement
|
|
66
|
+
* </button>
|
|
67
|
+
* </div>
|
|
68
|
+
* );
|
|
69
|
+
* }
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
<State, Metadata extends BaseMetadata, ActionsConfig extends ActionCollectionConfig<State, Metadata> | null | {}, PublicStateMutator = keyof ActionsConfig extends never | undefined ? React.Dispatch<React.SetStateAction<State>> : ActionCollectionResult<State, Metadata, NonNullable<ActionsConfig>>, StateDispatch = React.Dispatch<React.SetStateAction<State>>>(state: State, args: {
|
|
5
73
|
name?: string;
|
|
6
74
|
metadata?: Metadata;
|
|
7
75
|
callbacks?: GlobalStoreCallbacks<State, Metadata>;
|
|
8
76
|
actions?: ActionsConfig;
|
|
9
|
-
}): StateHook<State, PublicStateMutator, Metadata>;
|
|
10
|
-
|
|
77
|
+
}): StateHook<State, StateDispatch, PublicStateMutator, Metadata>;
|
|
78
|
+
/**
|
|
79
|
+
* Creates a global state hook that you can use across your application
|
|
80
|
+
* @param state initial state value
|
|
81
|
+
* @param args additional configuration for the global state
|
|
82
|
+
* @param args.name optional name for debugging purposes
|
|
83
|
+
* @param args.metadata optional non-reactive metadata associated with the state
|
|
84
|
+
* @param args.callbacks optional lifecycle callbacks for the global state
|
|
85
|
+
* @param args.actions optional actions to restrict state mutations [if provided `setState` will be nullified]
|
|
86
|
+
* @returns a state hook that you can use in your components
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```tsx
|
|
90
|
+
* const useCounter = createGlobalState(0, {
|
|
91
|
+
* actions: {
|
|
92
|
+
* increase() {
|
|
93
|
+
* return ({ setState }) => {
|
|
94
|
+
* setState((c) => c + 1);
|
|
95
|
+
* };
|
|
96
|
+
* },
|
|
97
|
+
* decrease(amount: number) {
|
|
98
|
+
* return ({ setState }) => {
|
|
99
|
+
* setState((c) => c - amount);
|
|
100
|
+
* };
|
|
101
|
+
* },
|
|
102
|
+
* },
|
|
103
|
+
* });
|
|
104
|
+
*
|
|
105
|
+
* function Counter() {
|
|
106
|
+
* const [count, {
|
|
107
|
+
* increase,
|
|
108
|
+
* decrease
|
|
109
|
+
* }] = useCounter();
|
|
110
|
+
*
|
|
111
|
+
* return (
|
|
112
|
+
* <div>
|
|
113
|
+
* <p>Count: {count}</p>
|
|
114
|
+
* <button onClick={increase}>
|
|
115
|
+
* Increment
|
|
116
|
+
* </button>
|
|
117
|
+
* <button onClick={() => {
|
|
118
|
+
* decrease(1);
|
|
119
|
+
* }}>
|
|
120
|
+
* Decrement
|
|
121
|
+
* </button>
|
|
122
|
+
* </div>
|
|
123
|
+
* );
|
|
124
|
+
* }
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
<State, Metadata extends BaseMetadata, ActionsConfig extends ActionCollectionConfig<State, Metadata>, StateDispatch = React.Dispatch<React.SetStateAction<State>>>(state: State, args: {
|
|
11
128
|
name?: string;
|
|
12
129
|
metadata?: Metadata;
|
|
13
130
|
callbacks?: GlobalStoreCallbacks<State, Metadata>;
|
|
14
131
|
actions: ActionsConfig;
|
|
15
|
-
}): StateHook<State, ActionCollectionResult<State, Metadata, ActionsConfig>, Metadata>;
|
|
132
|
+
}): StateHook<State, StateDispatch, ActionCollectionResult<State, Metadata, ActionsConfig>, Metadata>;
|
|
16
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Creates a global state hook
|
|
136
|
+
*/
|
|
17
137
|
export declare const createGlobalState: CreateGlobalState;
|
|
18
|
-
|
|
19
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Infers the actions type from a StateHook
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* type CounterActions = InferActionsType<typeof useCounter>;
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
export type InferActionsType<Hook extends StateHook<any, any, any, any>> = ReturnType<Hook['actions']>['1'];
|
package/createGlobalState.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e;e=e=>(()=>{"use strict";var t={778:t=>{t.exports=e},
|
|
1
|
+
var e;e=e=>(()=>{"use strict";var t={778:t=>{t.exports=e}},r={};function o(e){var a=r[e];if(void 0!==a)return a.exports;var s=r[e]={exports:{}};return t[e](s,s.exports,o),s.exports}var a={};return(()=>{var e=a;Object.defineProperty(e,"__esModule",{value:!0}),e.createGlobalState=void 0;var t=o(778);e.createGlobalState=function(){for(var e=arguments.length,r=new Array(e),o=0;o<e;o++)r[o]=arguments[o];var a=r[0],s=r[1];return new t.GlobalStore(a,s).use}})(),a})(),"object"==typeof exports&&"object"==typeof module?module.exports=e(require("./GlobalStore.js")):"function"==typeof define&&define.amd?define(["./GlobalStore.js"],e):"object"==typeof exports?exports["react-hooks-global-states"]=e(require("./GlobalStore.js")):this["react-hooks-global-states"]=e(this["./GlobalStore.js"]);
|
package/index.d.ts
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { StateApi as HookExtensions, ObservableFragment, MetadataSetter, StateChanges, StoreTools, ActionCollectionResult, GlobalStoreCallbacks, UseHookConfig, UnsubscribeCallback, SubscribeCallbackConfig, SubscribeCallback, BaseMetadata, MetadataGetter, CustomGlobalHookBuilderParams, SelectorCallback, SubscriberParameters, SubscriptionCallback, StateHook, ActionCollectionConfig, } from './types';
|
|
2
2
|
export { GlobalStore } from './GlobalStore';
|
|
3
3
|
export { GlobalStoreAbstract } from './GlobalStoreAbstract';
|
|
4
4
|
export { createGlobalState, type InferActionsType } from './createGlobalState';
|
|
5
|
-
export { createCustomGlobalState } from './createCustomGlobalState';
|
|
6
5
|
export { shallowCompare } from './shallowCompare';
|
|
7
6
|
export { uniqueId } from './uniqueId';
|
|
8
7
|
export { throwWrongKeyOnActionCollectionConfig } from './throwWrongKeyOnActionCollectionConfig';
|
|
9
8
|
export { isRecord } from './isRecord';
|
|
10
|
-
export {
|
|
11
|
-
export { type Context, type ContextProvider, type ContextHook, type CreateContext, type InferContextType, createContext, } from './createContext';
|
|
12
|
-
export { generateStackHash } from './generateStackHash';
|
|
9
|
+
export { type ContextApi as Context, type ContextProvider, type ContextHook, type CreateContext, type InferContextApi as InferContextType, createContext, } from './createContext';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-hooks-global-states",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.0-beta.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",
|
|
@@ -26,11 +26,6 @@
|
|
|
26
26
|
"require": "./GlobalStoreAbstract.js",
|
|
27
27
|
"types": "./GlobalStoreAbstract.d.ts"
|
|
28
28
|
},
|
|
29
|
-
"./createCustomGlobalState": {
|
|
30
|
-
"import": "./createCustomGlobalState.js",
|
|
31
|
-
"require": "./createCustomGlobalState.js",
|
|
32
|
-
"types": "./createCustomGlobalState.d.ts"
|
|
33
|
-
},
|
|
34
29
|
"./createGlobalState": {
|
|
35
30
|
"import": "./createGlobalState.js",
|
|
36
31
|
"require": "./createGlobalState.js",
|
|
@@ -60,16 +55,6 @@
|
|
|
60
55
|
"import": "./uniqueId.js",
|
|
61
56
|
"require": "./uniqueId.js",
|
|
62
57
|
"types": "./uniqueId.d.ts"
|
|
63
|
-
},
|
|
64
|
-
"./useStableState": {
|
|
65
|
-
"import": "./useStableState.js",
|
|
66
|
-
"require": "./useStableState.js",
|
|
67
|
-
"types": "./useStableState.d.ts"
|
|
68
|
-
},
|
|
69
|
-
"./generateStackHash": {
|
|
70
|
-
"import": "./generateStackHash.js",
|
|
71
|
-
"require": "./generateStackHash.js",
|
|
72
|
-
"types": "./generateStackHash.d.ts"
|
|
73
58
|
}
|
|
74
59
|
},
|
|
75
60
|
"files": [
|
|
@@ -77,7 +62,8 @@
|
|
|
77
62
|
"*.d.ts"
|
|
78
63
|
],
|
|
79
64
|
"scripts": {
|
|
80
|
-
"
|
|
65
|
+
"format": "prettier --write .",
|
|
66
|
+
"test-debug": "node --inspect-brk node_modules/.bin/jest --runInBand --detectOpenHandles",
|
|
81
67
|
"test:quick": "jest --maxWorkers=4 -c --no-watchman -u",
|
|
82
68
|
"test:coverage": "jest --maxWorkers=4 -c --colors --no-watchman --verbose --coverage",
|
|
83
69
|
"build": "yarn clean && webpack --config webpack.config.js",
|
|
@@ -137,6 +123,7 @@
|
|
|
137
123
|
"jest": "^29.7.0",
|
|
138
124
|
"jest-environment-jsdom": "^30.0.4",
|
|
139
125
|
"json-storage-formatter": "^2.0.9",
|
|
126
|
+
"prettier": "^3.6.2",
|
|
140
127
|
"react": "^18.2.0",
|
|
141
128
|
"react-dom": "^18.2.0",
|
|
142
129
|
"ts-jest": "^29.1.1",
|
package/shallowCompare.d.ts
CHANGED
|
@@ -1,13 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* @description It performs a shallow comparison of the values.
|
|
3
|
+
* @param value1 - The first value to compare.
|
|
4
|
+
* @param value2 - The second value to compare.
|
|
5
|
+
* @returns True if the values are equal, false otherwise.
|
|
3
6
|
*/
|
|
4
7
|
export declare const shallowCompare: <T>(value1: T, value2: T) => boolean;
|
|
5
8
|
export declare const isArray: (value: unknown) => value is unknown[];
|
|
6
9
|
export declare const isMap: (value: unknown) => value is Map<unknown, unknown>;
|
|
7
10
|
export declare const isSet: (value: unknown) => value is Set<unknown>;
|
|
11
|
+
/**
|
|
12
|
+
* @description Determines whether a simple equality check (using `===`) is sufficient
|
|
13
|
+
* to compare the provided values. This helps decide when a deep equality check
|
|
14
|
+
* is unnecessary or inefficient.
|
|
15
|
+
*
|
|
16
|
+
* Simple equality checks are considered valid when:
|
|
17
|
+
* - The values have different types (comparison will trivially return false)
|
|
18
|
+
* - Either value is null or undefined
|
|
19
|
+
* - Both values are primitive types (string, number, boolean, symbol, bigint)
|
|
20
|
+
* - Both values are Date objects
|
|
21
|
+
* - Both values are functions
|
|
22
|
+
*
|
|
23
|
+
* @param value1 - The first value to compare.
|
|
24
|
+
* @param value2 - The second value to compare.
|
|
25
|
+
* @returns `true` if a simple `===` check is sufficient, `false` if a deep comparison may be required.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* canCheckSimpleEquality(42, 42); // true (primitive numbers)
|
|
30
|
+
* canCheckSimpleEquality({ a: 1 }, { a: 1 }); // false (objects)
|
|
31
|
+
* canCheckSimpleEquality([1, 2], [1, 2]); // false (arrays)
|
|
32
|
+
* canCheckSimpleEquality('a', 1); // true (different types, shallow check enough)
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
8
35
|
export declare const canCheckSimpleEquality: (value1: unknown, value2: unknown) => boolean;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
36
|
+
/**
|
|
37
|
+
* @description Performs a shallow comparison between two arrays.
|
|
38
|
+
*/
|
|
39
|
+
export declare const isEqualArray: <T>(array1: T[], array2: T[]) => array1 is T[];
|
|
40
|
+
/**
|
|
41
|
+
* @description Performs a shallow comparison between two maps.
|
|
42
|
+
*/
|
|
43
|
+
export declare const isEqualMap: <K, V>(map1: Map<K, V>, map2: Map<K, V>) => map1 is Map<K, V>;
|
|
44
|
+
/**
|
|
45
|
+
* @description Performs a shallow comparison between two sets.
|
|
46
|
+
*/
|
|
47
|
+
export declare const isEqualSet: <T>(set1: Set<T>, set2: Set<T>) => set1 is Set<T>;
|
|
48
|
+
/**
|
|
49
|
+
* @description Performs a shallow comparison between two objects.
|
|
50
|
+
*/
|
|
12
51
|
export declare const isEqualObject: <T extends Record<string, unknown>>(value1: T, value2: T) => boolean;
|
|
13
52
|
export default shallowCompare;
|