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/GlobalStore.d.ts +17 -17
- package/GlobalStore.js +1 -125
- package/GlobalStoreAbstract.d.ts +6 -6
- package/GlobalStoreAbstract.js +1 -41
- package/bundle.js +1 -56
- package/createContext.d.ts +285 -44
- package/createContext.js +1 -70
- package/createGlobalState.d.ts +24 -7
- package/createGlobalState.js +1 -47
- package/index.d.ts +2 -2
- package/isRecord.js +1 -44
- package/package.json +1 -1
- package/shallowCompare.js +1 -53
- package/throwWrongKeyOnActionCollectionConfig.js +1 -16
- package/types.d.ts +204 -27
- package/types.js +1 -4
- package/uniqueId.js +1 -16
- package/webpack.config.js +2 -5
package/createContext.d.ts
CHANGED
|
@@ -1,17 +1,9 @@
|
|
|
1
1
|
import React, { type PropsWithChildren, Context as ReactContext } from 'react';
|
|
2
|
-
import type { ActionCollectionConfig, ActionCollectionResult, BaseMetadata,
|
|
2
|
+
import type { ActionCollectionConfig, ActionCollectionResult, BaseMetadata, GlobalStoreCallbacks, UseHookOptions, AnyFunction, StateApi, StoreTools, ReadonlyStateApi, SelectHook, ObservableFragment } from './types';
|
|
3
3
|
/**
|
|
4
|
-
* @description
|
|
4
|
+
* @description Extensions methods for the ContextProvider component
|
|
5
5
|
*/
|
|
6
|
-
export type
|
|
7
|
-
actions: Actions;
|
|
8
|
-
getMetadata: () => Metadata;
|
|
9
|
-
getState: () => State;
|
|
10
|
-
setMetadata: MetadataSetter<Metadata>;
|
|
11
|
-
setState: React.Dispatch<React.SetStateAction<State>>;
|
|
12
|
-
subscribe: SubscribeToState<State>;
|
|
13
|
-
};
|
|
14
|
-
export type ContextProviderExtensions<State, Actions, Metadata extends BaseMetadata> = {
|
|
6
|
+
export type ContextProviderExtensions<State, StateMutator, Metadata extends BaseMetadata> = {
|
|
15
7
|
/**
|
|
16
8
|
* Creates a provider wrapper which allows to capture the context value,
|
|
17
9
|
* useful for testing purposes.
|
|
@@ -21,20 +13,36 @@ export type ContextProviderExtensions<State, Actions, Metadata extends BaseMetad
|
|
|
21
13
|
* @returns an object containing the wrapper component and a reference to the context value
|
|
22
14
|
*/
|
|
23
15
|
makeProviderWrapper: (options?: {
|
|
16
|
+
/**
|
|
17
|
+
* @description Optional initial state or initializer function, useful for testing, storybooks, etc.
|
|
18
|
+
*/
|
|
24
19
|
value?: State | ((initialValue: State) => State);
|
|
25
|
-
|
|
20
|
+
/**
|
|
21
|
+
* @description Optional callback invoked after the context is created,
|
|
22
|
+
*/
|
|
23
|
+
onCreated?: (
|
|
24
|
+
/**
|
|
25
|
+
* @description Full context instance
|
|
26
|
+
*/
|
|
27
|
+
context: StoreTools<State, StateMutator extends AnyFunction ? null : StateMutator, Metadata>) => void;
|
|
26
28
|
}) => {
|
|
27
29
|
/**
|
|
28
30
|
* Provider for the context
|
|
29
31
|
*/
|
|
30
32
|
wrapper: React.FC<PropsWithChildren<{
|
|
33
|
+
/**
|
|
34
|
+
* @description Optional initial state or initializer function, useful for testing, storybooks, etc.
|
|
35
|
+
*/
|
|
31
36
|
value?: State | ((initialValue: State) => State);
|
|
32
37
|
}>>;
|
|
33
38
|
/**
|
|
34
39
|
* Reference to the current context value
|
|
35
40
|
*/
|
|
36
41
|
context: {
|
|
37
|
-
|
|
42
|
+
/**
|
|
43
|
+
* @description Current context value
|
|
44
|
+
*/
|
|
45
|
+
current: StoreTools<State, StateMutator extends AnyFunction ? null : StateMutator, Metadata>;
|
|
38
46
|
};
|
|
39
47
|
};
|
|
40
48
|
};
|
|
@@ -43,29 +51,45 @@ export type ContextProviderExtensions<State, Actions, Metadata extends BaseMetad
|
|
|
43
51
|
* @param value Optional initial state or initializer function, useful for testing.
|
|
44
52
|
* @param onCreated Optional callback invoked after the context is created, receiving the full context instance.
|
|
45
53
|
*/
|
|
46
|
-
export type ContextProvider<State,
|
|
54
|
+
export type ContextProvider<State, StateMutator, Metadata extends BaseMetadata> = React.FC<PropsWithChildren<{
|
|
55
|
+
/**
|
|
56
|
+
* @description Optional initial state or initializer function, useful for testing, storybooks, etc.
|
|
57
|
+
*/
|
|
47
58
|
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
59
|
/**
|
|
52
|
-
* @description
|
|
60
|
+
* @description Optional callback invoked after the context is created,
|
|
53
61
|
*/
|
|
54
|
-
(
|
|
62
|
+
onCreated?: (
|
|
55
63
|
/**
|
|
56
|
-
* @description
|
|
64
|
+
* @description Full context instance
|
|
65
|
+
*/
|
|
66
|
+
context: StoreTools<State, StateMutator extends AnyFunction ? null : StateMutator, Metadata>) => void;
|
|
67
|
+
}>> & ContextProviderExtensions<State, StateMutator, Metadata>;
|
|
68
|
+
/**
|
|
69
|
+
* @description Represents a hook that returns a readonly state.
|
|
70
|
+
*/
|
|
71
|
+
interface ReadonlyContextHook<State, StateMutator, Metadata extends BaseMetadata> extends ReadonlyContextPublicApi<State, StateMutator, Metadata> {
|
|
72
|
+
/**
|
|
73
|
+
* @description Returns the full state.
|
|
74
|
+
*/
|
|
75
|
+
(): State;
|
|
76
|
+
/**
|
|
77
|
+
* @description Returns a derived value from the state using the provided selector function.
|
|
57
78
|
* @param selector A function that selects a part of the state.
|
|
58
79
|
* @param dependencies Optional array of dependencies to control when the selector is re-evaluated.
|
|
59
|
-
* @returns
|
|
80
|
+
* @returns The derived value from the state.
|
|
60
81
|
*/
|
|
61
|
-
<Derivate>(selector: (state: State) => Derivate, dependencies?: unknown[]):
|
|
82
|
+
<Derivate>(selector: (state: State) => Derivate, dependencies?: unknown[]): Derivate;
|
|
62
83
|
/**
|
|
63
|
-
* @description
|
|
84
|
+
* @description Returns a derived value from the state using the provided selector function.
|
|
64
85
|
* @param selector A function that selects a part of the state.
|
|
65
|
-
* @param
|
|
66
|
-
* @
|
|
86
|
+
* @param options Optional configuration for the selector hook.
|
|
87
|
+
* @param options.isEqual Optional equality function to compare the selected fragment.
|
|
88
|
+
* @param options.isEqualRoot Optional equality function to compare the root state.
|
|
89
|
+
* @param options.dependencies Optional array of dependencies to control when the selector is re-evaluated.
|
|
90
|
+
* @returns The derived value from the state.
|
|
67
91
|
*/
|
|
68
|
-
<Derivate>(selector: (state: State) => Derivate,
|
|
92
|
+
<Derivate>(selector: (state: State) => Derivate, options?: UseHookOptions<Derivate, State>): Derivate;
|
|
69
93
|
}
|
|
70
94
|
/**
|
|
71
95
|
* @description Hook for accessing a context's state, mutator (setState or actions), and metadata.
|
|
@@ -85,11 +109,30 @@ export interface ContextBaseHook<State, StateMutator, Metadata extends BaseMetad
|
|
|
85
109
|
* actions.setTodos(next);
|
|
86
110
|
* ```
|
|
87
111
|
*/
|
|
88
|
-
export interface ContextHook<State, StateMutator, Metadata extends BaseMetadata> extends
|
|
112
|
+
export interface ContextHook<State, StateMutator, Metadata extends BaseMetadata> extends ContextPublicApi<State, StateMutator, Metadata> {
|
|
113
|
+
/**
|
|
114
|
+
* @description Retrieves the full state, state mutator (setState or actions), and metadata.
|
|
115
|
+
*/
|
|
116
|
+
(): Readonly<[state: State, stateMutator: StateMutator, metadata: Metadata]>;
|
|
117
|
+
/**
|
|
118
|
+
* @description Retrieves a derived value from the state using the provided selector function.
|
|
119
|
+
* @param selector A function that selects a part of the state.
|
|
120
|
+
* @param dependencies Optional array of dependencies to control when the selector is re-evaluated.
|
|
121
|
+
* @returns A read-only tuple containing the derived state, state mutator (setState or actions), and metadata.
|
|
122
|
+
*/
|
|
123
|
+
<Derivate>(selector: (state: State) => Derivate, dependencies?: unknown[]): Readonly<[state: Derivate, stateMutator: StateMutator, metadata: Metadata]>;
|
|
124
|
+
/**
|
|
125
|
+
* @description Retrieves a derived value from the state using the provided selector function.
|
|
126
|
+
* @param selector A function that selects a part of the state.
|
|
127
|
+
* @param dependencies Optional array of dependencies to control when the selector is re-evaluated.
|
|
128
|
+
* @returns A read-only tuple containing the derived state, state mutator (setState or actions), and metadata.
|
|
129
|
+
*/
|
|
130
|
+
<Derivate>(selector: (state: State) => Derivate, config?: UseHookOptions<Derivate, State>): Readonly<[state: Derivate, stateMutator: StateMutator, metadata: Metadata]>;
|
|
89
131
|
}
|
|
90
|
-
export type
|
|
132
|
+
export type ContextPublicApi<State, StateMutator, Metadata extends BaseMetadata> = {
|
|
91
133
|
/**
|
|
92
|
-
* @description
|
|
134
|
+
* @description [NOT A HOOK, NON-REACTIVE]
|
|
135
|
+
* Creates a derived hook that subscribes to a selected fragment of the context state.
|
|
93
136
|
* The selector determines which portion of the state the new hook exposes.
|
|
94
137
|
* This hook must be used within the corresponding context provider.
|
|
95
138
|
*
|
|
@@ -130,16 +173,67 @@ export type HookExtensions<State, StateMutator, Metadata extends BaseMetadata> =
|
|
|
130
173
|
* }
|
|
131
174
|
* ```
|
|
132
175
|
*/
|
|
133
|
-
createSelectorHook: <Derivate>(this:
|
|
176
|
+
createSelectorHook: <Derivate>(this: ReadonlyContextPublicApi<State, StateMutator, Metadata>, selector: (state: State) => Derivate, args?: Omit<UseHookOptions<Derivate, State>, 'dependencies'> & {
|
|
134
177
|
name?: string;
|
|
135
|
-
}) =>
|
|
178
|
+
}) => ReadonlyContextHook<Derivate, StateMutator, Metadata>;
|
|
179
|
+
/**
|
|
180
|
+
* @description [NON-REACTIVE]
|
|
181
|
+
* Hook that provides non-reactive access to the context API.
|
|
182
|
+
* This allows direct interaction with the context’s state, metadata, and actions
|
|
183
|
+
* without triggering component re-renders.
|
|
184
|
+
* @returns An object containing the context API methods and properties.
|
|
185
|
+
*/
|
|
186
|
+
api: () => StateApi<State, StateMutator, Metadata>;
|
|
187
|
+
/**
|
|
188
|
+
* @description [NON-REACTIVE]
|
|
189
|
+
* Provides direct access to the context's actions, if available.
|
|
190
|
+
*/
|
|
191
|
+
actions: () => StateMutator extends AnyFunction ? null : StateMutator;
|
|
192
|
+
/**
|
|
193
|
+
* @description Selects a fragment of the state using the provided selector function.
|
|
194
|
+
*/
|
|
195
|
+
select: SelectHook<State>;
|
|
196
|
+
/**
|
|
197
|
+
* @description
|
|
198
|
+
* Creates a hook that allows you to subscribe to a fragment of the state
|
|
199
|
+
* The observable selection will notify the subscribers only if the fragment changes and the equality function returns false
|
|
200
|
+
* you can customize the equality function by passing the isEqualRoot and isEqual parameters
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```tsx
|
|
204
|
+
* const observable = store.use.observable(state => state.count);
|
|
205
|
+
*
|
|
206
|
+
* useEffect(() => {
|
|
207
|
+
* const unsubscribe = observable.subscribe(() => {
|
|
208
|
+
* // do something when the selected fragment changes
|
|
209
|
+
* });
|
|
210
|
+
*
|
|
211
|
+
* return () => {
|
|
212
|
+
* unsubscribe();
|
|
213
|
+
* };
|
|
214
|
+
* }, [observable]);
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
observable: <Selection>(selector: (state: State) => Selection, args?: {
|
|
218
|
+
isEqual?: (current: Selection, next: Selection) => boolean;
|
|
219
|
+
isEqualRoot?: (current: State, next: State) => boolean;
|
|
220
|
+
/**
|
|
221
|
+
* @description Name of the observable fragment for debugging purposes
|
|
222
|
+
*/
|
|
223
|
+
name?: string;
|
|
224
|
+
}) => ObservableFragment<Selection, StateMutator, Metadata>;
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* @description Readonly version of the ContextPublicApi, expose by selectors and observables
|
|
228
|
+
*/
|
|
229
|
+
export type ReadonlyContextPublicApi<State, StateMutator, Metadata extends BaseMetadata> = Pick<ContextPublicApi<State, StateMutator, Metadata>, 'createSelectorHook'> & {
|
|
136
230
|
/**
|
|
137
231
|
* @description Hook that provides non-reactive access to the context API.
|
|
138
232
|
* This allows direct interaction with the context’s state, metadata, and actions
|
|
139
233
|
* without triggering component re-renders.
|
|
140
234
|
* @returns An object containing the context API methods and properties.
|
|
141
235
|
*/
|
|
142
|
-
api: () =>
|
|
236
|
+
api: () => ReadonlyStateApi<State, StateMutator, Metadata>;
|
|
143
237
|
};
|
|
144
238
|
interface CreateContext {
|
|
145
239
|
/**
|
|
@@ -153,10 +247,51 @@ interface CreateContext {
|
|
|
153
247
|
* - **`Context`** — The raw React `Context` object for advanced usage, such as integration with
|
|
154
248
|
* external tools or non-React consumers.
|
|
155
249
|
*/
|
|
156
|
-
<State
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
250
|
+
<State, StateMutator = React.Dispatch<React.SetStateAction<State>>>(value: State | (() => State)): {
|
|
251
|
+
/**
|
|
252
|
+
* @description Hook and API for interacting with the context.
|
|
253
|
+
* This hook provides access to the context state, actions, and metadata.
|
|
254
|
+
*
|
|
255
|
+
* There are two ways to use the hook
|
|
256
|
+
* @example
|
|
257
|
+
* The more simple and familiar way is to use it as a regular hook
|
|
258
|
+
*
|
|
259
|
+
* ```tsx
|
|
260
|
+
* const { Context, Provider, user: useUser} = createContext({ name: 'John', age: 30 });
|
|
261
|
+
*
|
|
262
|
+
* function UserProfile() {
|
|
263
|
+
* const [state, setState, metadata] = useUser();
|
|
264
|
+
*
|
|
265
|
+
* ....
|
|
266
|
+
* }
|
|
267
|
+
* ```
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* The recommended, more sematic and easier to read way:
|
|
271
|
+
*
|
|
272
|
+
* ```tsx
|
|
273
|
+
* const user = createContext({ name: 'John', age: 30 });
|
|
274
|
+
*
|
|
275
|
+
* <user.Provider>
|
|
276
|
+
* <UserProfile />
|
|
277
|
+
* </user.Provider>
|
|
278
|
+
*
|
|
279
|
+
* function UserProfile() {
|
|
280
|
+
* const [state, setState, metadata] = user.use();
|
|
281
|
+
* const userContext = user.use.api();
|
|
282
|
+
* const userName = user.use.select(s => s.name);
|
|
283
|
+
* // ...
|
|
284
|
+
* }
|
|
285
|
+
*/
|
|
286
|
+
use: ContextHook<State, StateMutator, BaseMetadata>;
|
|
287
|
+
/**
|
|
288
|
+
* @description Provider for the context
|
|
289
|
+
*/
|
|
290
|
+
Provider: ContextProvider<State, StateMutator, BaseMetadata>;
|
|
291
|
+
/**
|
|
292
|
+
* @description The raw React Context object
|
|
293
|
+
*/
|
|
294
|
+
Context: ReactContext<ContextHook<State, StateMutator, BaseMetadata> | null>;
|
|
160
295
|
};
|
|
161
296
|
/**
|
|
162
297
|
* @description Creates a highly granular React context with its associated provider and state hook.
|
|
@@ -174,17 +309,70 @@ interface CreateContext {
|
|
|
174
309
|
* - **`Context`** — The raw React `Context` object for advanced usage, such as integration with
|
|
175
310
|
* external tools or non-React consumers.
|
|
176
311
|
*/
|
|
177
|
-
<State, Metadata extends BaseMetadata, ActionsConfig extends ActionCollectionConfig<State, Metadata> | null | {},
|
|
312
|
+
<State, Metadata extends BaseMetadata, ActionsConfig extends ActionCollectionConfig<State, Metadata> | null | {}, StateMutator = keyof ActionsConfig extends never | undefined ? React.Dispatch<React.SetStateAction<State>> : ActionCollectionResult<State, Metadata, NonNullable<ActionsConfig>>>(
|
|
313
|
+
/**
|
|
314
|
+
* @description Initial state value or initializer function.
|
|
315
|
+
*/
|
|
316
|
+
value: State | (() => State),
|
|
317
|
+
/**
|
|
318
|
+
* @description Additional configuration for the context.
|
|
319
|
+
* @param args.name Optional name for debugging purposes.
|
|
320
|
+
* @param args.metadata Optional non-reactive metadata associated with the state.
|
|
321
|
+
* @param args.callbacks Optional lifecycle callbacks for the context.
|
|
322
|
+
* @param args.actions Optional actions to restrict state mutations [if provided `setState` will be nullified].
|
|
323
|
+
*/
|
|
324
|
+
args: {
|
|
178
325
|
name?: string;
|
|
179
326
|
metadata?: Metadata | (() => Metadata);
|
|
180
|
-
callbacks?: GlobalStoreCallbacks<State, Metadata> & {
|
|
327
|
+
callbacks?: GlobalStoreCallbacks<State, StateMutator, Metadata> & {
|
|
181
328
|
onUnMount?: () => void;
|
|
182
329
|
};
|
|
183
330
|
actions?: ActionsConfig;
|
|
184
331
|
}): {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
332
|
+
/**
|
|
333
|
+
* @description Hook and API for interacting with the context.
|
|
334
|
+
* This hook provides access to the context state, actions, and metadata.
|
|
335
|
+
*
|
|
336
|
+
* There are two ways to use the hook
|
|
337
|
+
* @example
|
|
338
|
+
* The more simple and familiar way is to use it as a regular hook
|
|
339
|
+
*
|
|
340
|
+
* ```tsx
|
|
341
|
+
* const { Context, Provider, user: useUser} = createContext({ name: 'John', age: 30 });
|
|
342
|
+
*
|
|
343
|
+
* function UserProfile() {
|
|
344
|
+
* const [state, setState, metadata] = useUser();
|
|
345
|
+
*
|
|
346
|
+
* ....
|
|
347
|
+
* }
|
|
348
|
+
* ```
|
|
349
|
+
*
|
|
350
|
+
* @example
|
|
351
|
+
* The recommended, more sematic and easier to read way:
|
|
352
|
+
*
|
|
353
|
+
* ```tsx
|
|
354
|
+
* const user = createContext({ name: 'John', age: 30 });
|
|
355
|
+
*
|
|
356
|
+
* <user.Provider>
|
|
357
|
+
* <UserProfile />
|
|
358
|
+
* </user.Provider>
|
|
359
|
+
*
|
|
360
|
+
* function UserProfile() {
|
|
361
|
+
* const [state, setState, metadata] = user.use();
|
|
362
|
+
* const userContext = user.use.api();
|
|
363
|
+
* const userName = user.use.select(s => s.name);
|
|
364
|
+
* // ...
|
|
365
|
+
* }
|
|
366
|
+
*/
|
|
367
|
+
use: ContextHook<State, StateMutator, Metadata>;
|
|
368
|
+
/**
|
|
369
|
+
* @description Provider for the context
|
|
370
|
+
*/
|
|
371
|
+
Provider: ContextProvider<State, StateMutator, Metadata>;
|
|
372
|
+
/**
|
|
373
|
+
* @description Raw React Context object
|
|
374
|
+
*/
|
|
375
|
+
Context: ReactContext<ContextHook<State, StateMutator, Metadata> | null>;
|
|
188
376
|
};
|
|
189
377
|
/**
|
|
190
378
|
* @description Creates a highly granular React context with its associated provider and state hook.
|
|
@@ -202,16 +390,69 @@ interface CreateContext {
|
|
|
202
390
|
* - **`Context`** — The raw React `Context` object for advanced usage, such as integration with
|
|
203
391
|
* external tools or non-React consumers.
|
|
204
392
|
*/
|
|
205
|
-
<State, Metadata extends BaseMetadata, ActionsConfig extends ActionCollectionConfig<State, Metadata
|
|
393
|
+
<State, Metadata extends BaseMetadata, ActionsConfig extends ActionCollectionConfig<State, Metadata>, StateMutator = React.Dispatch<React.SetStateAction<State>>>(
|
|
394
|
+
/**
|
|
395
|
+
* @description Initial state value or initializer function.
|
|
396
|
+
*/
|
|
397
|
+
value: State | (() => State),
|
|
398
|
+
/**
|
|
399
|
+
* @description Additional configuration for the context.
|
|
400
|
+
* @param args.name Optional name for debugging purposes.
|
|
401
|
+
* @param args.metadata Optional non-reactive metadata associated with the state.
|
|
402
|
+
* @param args.callbacks Optional lifecycle callbacks for the context.
|
|
403
|
+
* @param args.actions Optional actions to restrict state mutations [if provided `setState` will be nullified].
|
|
404
|
+
*/
|
|
405
|
+
args: {
|
|
206
406
|
name?: string;
|
|
207
407
|
metadata?: Metadata | (() => Metadata);
|
|
208
|
-
callbacks?: GlobalStoreCallbacks<State, Metadata> & {
|
|
408
|
+
callbacks?: GlobalStoreCallbacks<State, StateMutator, Metadata> & {
|
|
209
409
|
onUnMount?: () => void;
|
|
210
410
|
};
|
|
211
411
|
actions: ActionsConfig;
|
|
212
412
|
}): {
|
|
413
|
+
/**
|
|
414
|
+
* @description Hook and API for interacting with the context.
|
|
415
|
+
* This hook provides access to the context state, actions, and metadata.
|
|
416
|
+
*
|
|
417
|
+
* There are two ways to use the hook
|
|
418
|
+
* @example
|
|
419
|
+
* The more simple and familiar way is to use it as a regular hook
|
|
420
|
+
*
|
|
421
|
+
* ```tsx
|
|
422
|
+
* const { Context, Provider, user: useUser} = createContext({ name: 'John', age: 30 });
|
|
423
|
+
*
|
|
424
|
+
* function UserProfile() {
|
|
425
|
+
* const [state, setState, metadata] = useUser();
|
|
426
|
+
*
|
|
427
|
+
* ....
|
|
428
|
+
* }
|
|
429
|
+
* ```
|
|
430
|
+
*
|
|
431
|
+
* @example
|
|
432
|
+
* The recommended, more sematic and easier to read way:
|
|
433
|
+
*
|
|
434
|
+
* ```tsx
|
|
435
|
+
* const user = createContext({ name: 'John', age: 30 });
|
|
436
|
+
*
|
|
437
|
+
* <user.Provider>
|
|
438
|
+
* <UserProfile />
|
|
439
|
+
* </user.Provider>
|
|
440
|
+
*
|
|
441
|
+
* function UserProfile() {
|
|
442
|
+
* const [state, setState, metadata] = user.use();
|
|
443
|
+
* const userContext = user.use.api();
|
|
444
|
+
* const userName = user.use.select(s => s.name);
|
|
445
|
+
* // ...
|
|
446
|
+
* }
|
|
447
|
+
*/
|
|
213
448
|
use: ContextHook<State, ActionCollectionResult<State, Metadata, ActionsConfig>, Metadata>;
|
|
449
|
+
/**
|
|
450
|
+
* @description Provider for the context
|
|
451
|
+
*/
|
|
214
452
|
Provider: ContextProvider<State, ActionCollectionResult<State, Metadata, ActionsConfig>, Metadata>;
|
|
453
|
+
/**
|
|
454
|
+
* @description Raw React Context object
|
|
455
|
+
*/
|
|
215
456
|
Context: ReactContext<ContextHook<State, ActionCollectionResult<State, Metadata, ActionsConfig>, Metadata> | null>;
|
|
216
457
|
};
|
|
217
458
|
}
|
|
@@ -237,5 +478,5 @@ export declare const createContext: CreateContext;
|
|
|
237
478
|
* ContextApi<number, React.Dispatch<React.SetStateAction<number>>, BaseMetadata>;
|
|
238
479
|
* ```
|
|
239
480
|
*/
|
|
240
|
-
export type InferContextApi<Context extends ReactContext<ContextHook<any, any,
|
|
481
|
+
export type InferContextApi<Context extends ReactContext<ContextHook<any, any, BaseMetadata> | null>> = NonNullable<React.ContextType<Context>> extends ContextHook<infer State, infer StateMutator, infer Metadata> ? StateApi<State, StateMutator extends AnyFunction ? null : StateMutator, Metadata> : never;
|
|
241
482
|
export default createContext;
|
package/createContext.js
CHANGED
|
@@ -1,70 +1 @@
|
|
|
1
|
-
var e,t;e=this,t=(e,t,r,o)
|
|
2
|
-
/******/"use strict";
|
|
3
|
-
/******/var n={
|
|
4
|
-
/***/155:
|
|
5
|
-
/***/t=>{t.exports=e;
|
|
6
|
-
/***/},
|
|
7
|
-
/***/506:
|
|
8
|
-
/***/e=>{e.exports=t;
|
|
9
|
-
/***/},
|
|
10
|
-
/***/639:
|
|
11
|
-
/***/(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);
|
|
12
|
-
/**
|
|
13
|
-
* @description Creates a highly granular React context with its associated provider and state hook.
|
|
14
|
-
* Unlike the native `React.createContext`, this version provides fine-grained reactivity and supports
|
|
15
|
-
* state selection, metadata handling, and optional custom actions for controlled mutations.
|
|
16
|
-
*
|
|
17
|
-
* Components using the generated hook only re-render when the selected part of the state changes,
|
|
18
|
-
* making it efficient for large or deeply nested state trees.
|
|
19
|
-
*/
|
|
20
|
-
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),
|
|
21
|
-
/**
|
|
22
|
-
* Required by the global hooks developer tools
|
|
23
|
-
*/
|
|
24
|
-
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={
|
|
25
|
-
/**
|
|
26
|
-
* Store selectors are not created until the first time they are used
|
|
27
|
-
*/
|
|
28
|
-
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}
|
|
29
|
-
/***/,
|
|
30
|
-
/***/773:
|
|
31
|
-
/***/e=>{e.exports=r;
|
|
32
|
-
/***/},
|
|
33
|
-
/***/778:
|
|
34
|
-
/***/e=>{e.exports=o;
|
|
35
|
-
/***/
|
|
36
|
-
/******/}},a={};
|
|
37
|
-
/************************************************************************/
|
|
38
|
-
/******/
|
|
39
|
-
/******/
|
|
40
|
-
/******/
|
|
41
|
-
/******/
|
|
42
|
-
/******/
|
|
43
|
-
/******/
|
|
44
|
-
/******/return function e(t){
|
|
45
|
-
/******/
|
|
46
|
-
/******/var r=a[t];
|
|
47
|
-
/******/if(void 0!==r)
|
|
48
|
-
/******/return r.exports;
|
|
49
|
-
/******/
|
|
50
|
-
/******/
|
|
51
|
-
/******/var o=a[t]={
|
|
52
|
-
/******/
|
|
53
|
-
/******/
|
|
54
|
-
/******/exports:{}
|
|
55
|
-
/******/};
|
|
56
|
-
/******/
|
|
57
|
-
/******/
|
|
58
|
-
/******/
|
|
59
|
-
/******/
|
|
60
|
-
/******/
|
|
61
|
-
/******/return n[t](o,o.exports,e),o.exports;
|
|
62
|
-
/******/}
|
|
63
|
-
/******/
|
|
64
|
-
/************************************************************************/
|
|
65
|
-
/******/
|
|
66
|
-
/******/
|
|
67
|
-
/******/
|
|
68
|
-
/******/
|
|
69
|
-
/******/(639);
|
|
70
|
-
/******/})(),"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"]);
|
|
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);function u(e,t){var r=this,a=function(){var n=r.api();return(0,o.useMemo)((function(){return n.createSelectorHook(e,t)}),[n]).apply(void 0,arguments)},i={createSelectorHook:u.bind(a),api:function(){var a=r.api();return(0,o.useMemo)((function(){var r=a.createObservable(e,t);return Object.assign(Object.assign({},a),{getState:function(){return r.getState()},subscribe:r.subscribe.bind(r),createSelectorHook:n.createSelectorHook.bind(r),createObservable:n.createObservable.bind(r)})}),[a])}};return Object.assign(a,i),a}t.createContext=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=(0,o.createContext)(null),s=function(u){var s=u.children,l=u.value,c=u.onCreated,v=(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=v.callbacks)||void 0===e?void 0:e.onUnMount)||void 0===t||t.call(e,v),null===(o=(r=v).__onUnMountContext)||void 0===o||o.call(r,v),v.dispose()}}),[v]),null==c||c(v.getConfigCallbackParam()),(0,o.createElement)(r.Provider,{value:v.use},s)},l={makeProviderWrapper:function(e){var t={current:void 0};return{wrapper:function(r){var n=r.children;return(0,o.createElement)(s,{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}}},c=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)},v=function(){var e=(0,o.useContext)(r);if(!e)throw new Error("api hook must be used within a ContextProvider");return e},d={createSelectorHook:u.bind(c),api:v,select:function(){return c.apply(void 0,arguments)[0]},observable:function(){for(var e=v(),t=arguments.length,r=new Array(t),n=0;n<t;n++)r[n]=arguments[n];var a=(0,o.useRef)(r);return a.current=r,(0,o.useMemo)((function(){var t,r,o;return e.createObservable((function(e){return(0,a.current[0])(e)}),{isEqualRoot:Boolean(null===(t=a.current[1])||void 0===t?void 0:t.isEqualRoot)?function(e,t){var r,o=null===(r=a.current[1])||void 0===r?void 0:r.isEqualRoot;return Boolean(o(e,t))}:void 0,isEqual:Boolean(null===(r=a.current[1])||void 0===r?void 0:r.isEqual)?function(e,t){var r,o=null===(r=a.current[1])||void 0===r?void 0:r.isEqual;return Boolean(o(e,t))}:void 0,name:null===(o=a.current[1])||void 0===o?void 0:o.name})}),[e])},actions:function(){return v().actions}};return Object.assign(s,l),Object.assign(c,d),{use:c,Provider:s,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
|
@@ -4,7 +4,9 @@ interface CreateGlobalState {
|
|
|
4
4
|
* Creates a global state hook.
|
|
5
5
|
* @param state initial state value
|
|
6
6
|
* @returns a state hook for your components
|
|
7
|
+
*
|
|
7
8
|
* @example
|
|
9
|
+
* ```tsx
|
|
8
10
|
* const useCounter = createGlobalState(0);
|
|
9
11
|
*
|
|
10
12
|
* function Counter() {
|
|
@@ -18,8 +20,23 @@ interface CreateGlobalState {
|
|
|
18
20
|
* </div>
|
|
19
21
|
* );
|
|
20
22
|
* }
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @example You can also use a more semantic and declarative approach
|
|
26
|
+
* ```tsx
|
|
27
|
+
* const counter = createGlobalState(0);
|
|
28
|
+
*
|
|
29
|
+
* function Counter() {
|
|
30
|
+
* const [count, setCount] = counter.use();
|
|
31
|
+
* const count = counter.use.select();
|
|
32
|
+
*
|
|
33
|
+
* counter.setState(prev => prev + 1);
|
|
34
|
+
*
|
|
35
|
+
* // if you have actions
|
|
36
|
+
* counter.actions.someAction();
|
|
37
|
+
* ```
|
|
21
38
|
*/
|
|
22
|
-
<State
|
|
39
|
+
<State>(state: State): StateHook<State, React.Dispatch<React.SetStateAction<State>>, BaseMetadata>;
|
|
23
40
|
/**
|
|
24
41
|
* Creates a global state hook that you can use across your application
|
|
25
42
|
* @param state initial state value
|
|
@@ -72,9 +89,9 @@ interface CreateGlobalState {
|
|
|
72
89
|
<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: {
|
|
73
90
|
name?: string;
|
|
74
91
|
metadata?: Metadata;
|
|
75
|
-
callbacks?: GlobalStoreCallbacks<State, Metadata>;
|
|
92
|
+
callbacks?: GlobalStoreCallbacks<State, PublicStateMutator, Metadata>;
|
|
76
93
|
actions?: ActionsConfig;
|
|
77
|
-
}): StateHook<State,
|
|
94
|
+
}): StateHook<State, PublicStateMutator, Metadata>;
|
|
78
95
|
/**
|
|
79
96
|
* Creates a global state hook that you can use across your application
|
|
80
97
|
* @param state initial state value
|
|
@@ -124,12 +141,12 @@ interface CreateGlobalState {
|
|
|
124
141
|
* }
|
|
125
142
|
* ```
|
|
126
143
|
*/
|
|
127
|
-
<State, Metadata extends BaseMetadata, ActionsConfig extends ActionCollectionConfig<State, Metadata>,
|
|
144
|
+
<State, Metadata extends BaseMetadata, ActionsConfig extends ActionCollectionConfig<State, Metadata>, PublicStateMutator = ActionCollectionResult<State, Metadata, NonNullable<ActionsConfig>>>(state: State, args: {
|
|
128
145
|
name?: string;
|
|
129
146
|
metadata?: Metadata;
|
|
130
|
-
callbacks?: GlobalStoreCallbacks<State, Metadata>;
|
|
147
|
+
callbacks?: GlobalStoreCallbacks<State, PublicStateMutator, Metadata>;
|
|
131
148
|
actions: ActionsConfig;
|
|
132
|
-
}): StateHook<State,
|
|
149
|
+
}): StateHook<State, PublicStateMutator, Metadata>;
|
|
133
150
|
}
|
|
134
151
|
/**
|
|
135
152
|
* Creates a global state hook
|
|
@@ -142,5 +159,5 @@ export declare const createGlobalState: CreateGlobalState;
|
|
|
142
159
|
* type CounterActions = InferActionsType<typeof useCounter>;
|
|
143
160
|
* ```
|
|
144
161
|
*/
|
|
145
|
-
export type InferActionsType<Hook extends StateHook<any, any, any
|
|
162
|
+
export type InferActionsType<Hook extends StateHook<any, any, any>> = ReturnType<Hook['actions']>['1'];
|
|
146
163
|
export default createGlobalState;
|
package/createGlobalState.js
CHANGED
|
@@ -1,47 +1 @@
|
|
|
1
|
-
var e;e=e
|
|
2
|
-
/******/"use strict";
|
|
3
|
-
/******/var t={
|
|
4
|
-
/***/778:
|
|
5
|
-
/***/t=>{t.exports=e;
|
|
6
|
-
/***/},
|
|
7
|
-
/***/840:
|
|
8
|
-
/***/(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.createGlobalState=void 0;var r=o(778);
|
|
9
|
-
/**
|
|
10
|
-
* Creates a global state hook
|
|
11
|
-
*/t.createGlobalState=function(){for(var e=arguments.length,t=new Array(e),o=0;o<e;o++)t[o]=arguments[o];var a=t[0],l=t[1];return new r.GlobalStore(a,l).use},t.default=t.createGlobalState}
|
|
12
|
-
/***/
|
|
13
|
-
/******/},o={};
|
|
14
|
-
/************************************************************************/
|
|
15
|
-
/******/
|
|
16
|
-
/******/
|
|
17
|
-
/******/
|
|
18
|
-
/******/
|
|
19
|
-
/******/
|
|
20
|
-
/******/
|
|
21
|
-
/******/return function e(r){
|
|
22
|
-
/******/
|
|
23
|
-
/******/var a=o[r];
|
|
24
|
-
/******/if(void 0!==a)
|
|
25
|
-
/******/return a.exports;
|
|
26
|
-
/******/
|
|
27
|
-
/******/
|
|
28
|
-
/******/var l=o[r]={
|
|
29
|
-
/******/
|
|
30
|
-
/******/
|
|
31
|
-
/******/exports:{}
|
|
32
|
-
/******/};
|
|
33
|
-
/******/
|
|
34
|
-
/******/
|
|
35
|
-
/******/
|
|
36
|
-
/******/
|
|
37
|
-
/******/
|
|
38
|
-
/******/return t[r](l,l.exports,e),l.exports;
|
|
39
|
-
/******/}
|
|
40
|
-
/******/
|
|
41
|
-
/************************************************************************/
|
|
42
|
-
/******/
|
|
43
|
-
/******/
|
|
44
|
-
/******/
|
|
45
|
-
/******/
|
|
46
|
-
/******/(840);
|
|
47
|
-
/******/})(),"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"]);
|
|
1
|
+
var e;e=e=>(()=>{"use strict";var t={778:t=>{t.exports=e},840:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.createGlobalState=void 0;var r=o(778);t.createGlobalState=function(){for(var e=arguments.length,t=new Array(e),o=0;o<e;o++)t[o]=arguments[o];var a=t[0],l=t[1];return new r.GlobalStore(a,l).use},t.default=t.createGlobalState}},o={};return function e(r){var a=o[r];if(void 0!==a)return a.exports;var l=o[r]={exports:{}};return t[r](l,l.exports,e),l.exports}(840)})(),"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,4 +1,4 @@
|
|
|
1
|
-
export { StateApi, ObservableFragment, MetadataSetter, StateChanges, StoreTools, ActionCollectionResult, GlobalStoreCallbacks,
|
|
1
|
+
export { StateApi, ObservableFragment, MetadataSetter, StateChanges, StoreTools, ActionCollectionResult, GlobalStoreCallbacks, UseHookOptions, UnsubscribeCallback, SubscribeCallbackConfig, SubscribeCallback, BaseMetadata, MetadataGetter, 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';
|
|
@@ -6,4 +6,4 @@ export { shallowCompare } from './shallowCompare';
|
|
|
6
6
|
export { uniqueId } from './uniqueId';
|
|
7
7
|
export { throwWrongKeyOnActionCollectionConfig } from './throwWrongKeyOnActionCollectionConfig';
|
|
8
8
|
export { isRecord } from './isRecord';
|
|
9
|
-
export { type
|
|
9
|
+
export { type ContextProvider, type ContextHook, type InferContextApi, createContext } from './createContext';
|