react-hooks-global-states 1.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.
@@ -0,0 +1,316 @@
1
+ /**
2
+ * @param {StateSetter<TState>} setter - set the state
3
+ * @returns {void} result - void
4
+ */
5
+ export type StateSetter<TState> = (
6
+ /**
7
+ * @param {StateSetter<TState>} setter - set the state
8
+ * @param {{ forceUpdate?: boolean }} options - Options to be passed to the setter
9
+ * @param {{ forceUpdate?: boolean }} options.forceUpdate - Force the re-render of the subscribers even if the state is the same
10
+ * @returns {void} result - void
11
+ * */
12
+ setter: TState | ((state: TState) => TState),
13
+ /**
14
+ * This parameter indicate whether we should force the re-render of the subscribers even if the state is the same,
15
+ * Do
16
+ */
17
+ { forceUpdate, }?: {
18
+ /**
19
+ * @deprecated forceUpdate normally should not be used inside components
20
+ * Use this flag just in custom implementations of the global store
21
+ */
22
+ forceUpdate?: boolean;
23
+ }) => void;
24
+ /**
25
+ * @description
26
+ * The hook to use the global state
27
+ * @returns {[State, StateSetter<TState>, TMetadata]} result - the state, the setter and the metadata
28
+ */
29
+ export type StateHook<TState, TSetter, TMetadata> = <State = TState>(selector?: (state: TState) => State, config?: UseHookConfig<State>) => [state: State, setter: TSetter, metadata: TMetadata];
30
+ /**
31
+ * @description
32
+ * Type that prevent ts issues with merging never with other types
33
+ */
34
+ export type AvoidNever<T> = T extends never | null | undefined ? {} : T;
35
+ /**
36
+ * @param {TMetadata} setter - set the metadata
37
+ * @returns {void} result - void
38
+ */
39
+ export type MetadataSetter<TMetadata> = (
40
+ /**
41
+ * @param {TMetadata} setter - set the metadata
42
+ * @returns {void} result - void
43
+ * */
44
+ setter: TMetadata | ((metadata: TMetadata) => TMetadata)) => void;
45
+ /**
46
+ * Parameters of the onStateChanged callback function
47
+ * @param {TState} state - the new state
48
+ * @param {TState} previousState - the previous state
49
+ **/
50
+ export type StateChanges<TState> = {
51
+ /**
52
+ * The new state
53
+ * */
54
+ state: TState;
55
+ /**
56
+ * The previous state
57
+ * */
58
+ previousState?: TState;
59
+ };
60
+ /**
61
+ * Callbacks to be passed to the configurations function of the store
62
+ * @template {TState} TState - The state type
63
+ * @template {TMetadata} TMetadata - The metadata type
64
+ * @property {StateSetter<TState>} setMetadata - Set the metadata
65
+ * @property {StateSetter<TState>} setState - Set the state
66
+ * @property {() => TState} getState - Get the state
67
+ * @property {() => TMetadata} getMetadata - Get the metadata
68
+ * @property {ActionCollectionResult<TState, TMetadata>} actions - The actions collection if any
69
+ **/
70
+ export type StoreTools<TState = any, TMetadata = any, TActions = any> = {
71
+ /**
72
+ * Set the metadata
73
+ * @param {TMetadata} setter - The metadata or a function that will receive the metadata and return the new metadata
74
+ * @returns {void} result - void
75
+ * */
76
+ setMetadata: MetadataSetter<TMetadata>;
77
+ /**
78
+ * Set the state
79
+ * @param {TState} setter - The state or a function that will receive the state and return the new state
80
+ * @param {{ forceUpdate?: boolean }} options - Options
81
+ * @returns {void} result - void
82
+ * */
83
+ setState: StateSetter<TState>;
84
+ /**
85
+ * Get the state
86
+ * @returns {TState} result - The state
87
+ * */
88
+ getState: StateGetter<TState>;
89
+ /**
90
+ * Get the metadata
91
+ * @returns {TMetadata} result - The metadata
92
+ * */
93
+ getMetadata: () => TMetadata;
94
+ /**
95
+ * Actions of the hook
96
+ */
97
+ actions: TActions;
98
+ };
99
+ /**
100
+ * Basic contract for the storeActionsConfig configuration
101
+ * @template {TState} TState - The state type
102
+ * @template {TMetadata} TMetadata - The metadata type
103
+ * @property {string} key - The action name
104
+ * @property {(...parameters: unknown[]) => (storeTools: { setMetadata: MetadataSetter<TMetadata>; setState: StateSetter<TState>; getState: () => TState; getMetadata: () => TMetadata; }) => unknown | void} value - The action function
105
+ * @returns {ActionCollectionConfig<TState, TMetadata>} result - The action collection configuration
106
+ */
107
+ export interface ActionCollectionConfig<TState, TMetadata = null> {
108
+ [key: string]: (...parameters: any[]) => (storeTools: StoreTools<TState, TMetadata>) => unknown | void;
109
+ }
110
+ /**
111
+ * This is the actions object returned by the hook when you pass an storeActionsConfig configuration
112
+ * if you pass an storeActionsConfig configuration, the hook will return an object with the actions
113
+ * whatever data manipulation of the state should be executed through the custom actions with as access to the state and metadata
114
+ * @template {TState} TState - The state type
115
+ * @template {TMetadata} TMetadata - The metadata type
116
+ * @template {TStateSetter} TStateSetter - The storeActionsConfig type (optional) - if you pass an storeActionsConfig the hook will return an object with the actions
117
+ *
118
+ * @example
119
+ *
120
+ * const store = new GlobalStore(0, {
121
+ * increment: () => ({ setState }) => {
122
+ * setState((state) => state + 1);
123
+ * },
124
+ * decrement: () => ({ setState }) => {
125
+ * setState((state) => state - 1);
126
+ * },
127
+ * });
128
+ *
129
+ * const [state, actions] = store.getHook();
130
+ *
131
+ * actions.increment();
132
+ * actions.decrement();
133
+ *
134
+ * console.log(state); // 0
135
+ */
136
+ export type ActionCollectionResult<TState, TMetadata, TStateSetter extends ActionCollectionConfig<TState, TMetadata> | StateSetter<TState> = StateSetter<TState>> = TStateSetter extends ActionCollectionConfig<TState, TMetadata> ? {
137
+ [key in keyof TStateSetter]: (...params: Parameters<TStateSetter[key]>) => ReturnType<ReturnType<TStateSetter[key]>>;
138
+ } : null;
139
+ /**
140
+ * Common parameters of the store configuration callback functions
141
+ * @param {StateSetter<TState>} setState - add a new value to the state
142
+ * @param {() => TState} getState - get the current state
143
+ * @param {MetadataSetter<TMetadata>} setMetadata - add a new value to the metadata
144
+ * @param {() => TMetadata} getMetadata - get the current metadata
145
+ * @param {ActionCollectionResult<TState, ActionCollectionConfig<TState, TMetadata>> | null} actions - the actions object returned by the hook when you pass an storeActionsConfig configuration otherwise null
146
+ * @template {TState} TState - The state type
147
+ * @template {TMetadata} TMetadata - The metadata type
148
+ * @template {TStateSetter} TStateSetter - The storeActionsConfig type (optional) - if you pass an storeActionsConfig the hook will return an object with the actions
149
+ * @template {ActionCollectionResult<TState, TStateSetter>} TStateSetter - the result of the API (optional) - if you don't pass an API as a parameter, you can pass null
150
+ * */
151
+ export type StateConfigCallbackParam<TState, TMetadata, TStateSetter extends ActionCollectionConfig<TState, TMetadata> | StateSetter<TState> = StateSetter<TState>> = {
152
+ actions: ActionCollectionResult<TState, TMetadata, TStateSetter>;
153
+ } & StoreTools<TState, TMetadata>;
154
+ /**
155
+ * Parameters of the onStateChanged callback function
156
+ * @template {TState} TState - The state type
157
+ * @template {TMetadata} TMetadata - The metadata type
158
+ * @template {TStateSetter} TStateSetter - The storeActionsConfig type (optional) - if you pass an storeActionsConfig the hook will return an object with the actions
159
+ */
160
+ export type StateChangesParam<TState, TMetadata, TStateSetter extends ActionCollectionConfig<TState, TMetadata> | StateSetter<TState> = StateSetter<TState>> = StateConfigCallbackParam<TState, TMetadata, TStateSetter> & StateChanges<TState>;
161
+ /**
162
+ * Configuration of the store (optional) - if you don't need to use the store configuration you don't need to pass this parameter
163
+ * @param {StateConfigCallbackParam<TState, TMetadata> => void} onInit - callback function called when the store is initialized
164
+ * @param {StateConfigCallbackParam<TState, TMetadata> => void} onSubscribed - callback function called every time a component is subscribed to the store
165
+ * @param {StateChangesParam<TState, TMetadata> => boolean} computePreventStateChange - callback function called every time the state is changed and it allows you to prevent the state change
166
+ * @param {StateChangesParam<TState, TMetadata> => void} onStateChanged - callback function called every time the state is changed
167
+ * @template TState - the type of the state
168
+ * @template TMetadata - the type of the metadata (optional) - if you don't pass an metadata as a parameter, you can pass null
169
+ * @template {ActionCollectionConfig<TState,TMetadata> | null} TStateSetter - the configuration of the API (optional) - if you don't pass an API as a parameter, you can pass null
170
+ * */
171
+ export type GlobalStoreConfig<TState, TMetadata, TStateSetter extends ActionCollectionConfig<TState, TMetadata> | StateSetter<TState> = StateSetter<TState>> = {
172
+ /**
173
+ * @param {StateConfigCallbackParam<TState, TMetadata> => void} metadata - the initial value of the metadata
174
+ * */
175
+ metadata?: TMetadata;
176
+ /**
177
+ * @param {StateConfigCallbackParam<TState, TMetadata> => void} onInit - callback function called when the store is initialized
178
+ * @returns {void} result - void
179
+ * */
180
+ onInit?: (parameters: StateConfigCallbackParam<TState, TMetadata, TStateSetter>) => void;
181
+ /**
182
+ * @param {StateChangesParam<TState, TMetadata> => void} onStateChanged - callback function called every time the state is changed
183
+ * @returns {void} result - void
184
+ */
185
+ onStateChanged?: (parameters: StateChangesParam<TState, TMetadata, TStateSetter>) => void;
186
+ /**
187
+ * @param {StateConfigCallbackParam<TState, TMetadata> => void} onSubscribed - callback function called every time a component is subscribed to the store
188
+ * @returns {void} result - void
189
+ */
190
+ onSubscribed?: (parameters: StateConfigCallbackParam<TState, TMetadata, TStateSetter>) => void;
191
+ /**
192
+ * @param {StateChangesParam<TState, TMetadata> => boolean} computePreventStateChange - callback function called every time the state is about to change and it allows you to prevent the state change
193
+ * @returns {boolean} result - true if you want to prevent the state change, false otherwise
194
+ */
195
+ computePreventStateChange?: (parameters: StateChangesParam<TState, TMetadata, TStateSetter>) => boolean;
196
+ } | null;
197
+ export type UseHookConfig<TState> = {
198
+ /**
199
+ * The callback to execute when the state is changed to check if the same really changed
200
+ * If the function is not provided the derived state will perform a shallow comparison
201
+ */
202
+ isEqual?: (current: TState, next: TState) => boolean;
203
+ };
204
+ /**
205
+ * Callback function to unsubscribe from the store
206
+ */
207
+ export type UnsubscribeCallback = () => void;
208
+ /**
209
+ * Configuration of the subscribe callbacks
210
+ */
211
+ export type SubscribeCallbackConfig<TState> = UseHookConfig<TState> & {
212
+ /**
213
+ * By default the callback is executed immediately after the subscription
214
+ */
215
+ skipFirst?: boolean;
216
+ };
217
+ /**
218
+ * Callback function to subscribe to the store changes
219
+ */
220
+ export type SubscribeCallback<TState> = (state: TState) => void;
221
+ /**
222
+ * Callback function to subscribe to the store changes from a getter
223
+ */
224
+ export type SubscriberCallback<TState> = (subscribe: SubscribeToEmitter<TState>) => void;
225
+ /**
226
+ * Callback function to get the current state of the store or to subscribe to the store changes
227
+ * @template TState - the type of the state
228
+ * @param {SubscriberCallback<TState> | null} callback - the callback function to subscribe to the store changes (optional)
229
+ * use the methods subscribe and subscribeSelect to subscribe to the store changes
230
+ * if you don't pass a callback function the hook will return the current state of the store
231
+ * @returns {UnsubscribeCallback | TState} result - the state or the unsubscribe callback if you pass a callback function
232
+ */
233
+ export type StateGetter<TState> = <Subscription extends Subscribe | false = false>(
234
+ /**
235
+ * @param {SubscriberCallback<TState> | null} callback - the callback function to subscribe to the store changes (optional)
236
+ * use the methods subscribe and subscribeSelect to subscribe to the store changes
237
+ */
238
+ callback?: Subscription extends Subscribe ? SubscriberCallback<TState> : null) => Subscription extends Subscribe ? UnsubscribeCallback : TState;
239
+ export type MetadataGetter<TMetadata> = () => TMetadata;
240
+ /**
241
+ * Constant value type to indicate that the getter is a subscription
242
+ */
243
+ export type Subscribe = true;
244
+ /**
245
+ * Configuration of the state (optional) - if you don't need to use the state configuration you don't need to pass this parameter
246
+ */
247
+ export type createStateConfig<TState, TMetadata, TActions extends ActionCollectionConfig<TState, TMetadata> | null = null> = {
248
+ /**
249
+ * @description
250
+ * The type of the actionsConfig object (optional) (default: null) if a configuration is passed, the hook will return an object with the actions then all the store manipulation will be done through the actions
251
+ */
252
+ actions?: TActions;
253
+ } & GlobalStoreConfig<TState, TMetadata, TActions>;
254
+ export type CustomGlobalHookBuilderParams<TInheritMetadata = null, TCustomConfig = {}> = {
255
+ /**
256
+ * @description
257
+ * This function is called when the state is initialized.
258
+ */
259
+ onInitialize: ({ setState, setMetadata, getMetadata, getState, actions, }: StateConfigCallbackParam<any, TInheritMetadata>, config: TCustomConfig) => void;
260
+ /**
261
+ * @description
262
+ * This function is called when the state is changed.
263
+ */
264
+ onChange: ({ setState, setMetadata, getMetadata, getState, actions, }: StateChangesParam<any, TInheritMetadata>, config: TCustomConfig) => void;
265
+ };
266
+ /**
267
+ * @description
268
+ * Configuration of the custom global hook
269
+ */
270
+ export type CustomGlobalHookParams<TCustomConfig, TState, TMetadata, TActions extends ActionCollectionConfig<TState, TMetadata> | null> = {
271
+ /**
272
+ * @description
273
+ * Type of the configuration object that the custom hook will require or accept
274
+ */
275
+ config?: TCustomConfig;
276
+ /**
277
+ * @description
278
+ * The type of the actionsConfig object (optional) (default: null) if a configuration is passed, the hook will return an object with the actions then all the store manipulation will be done through the actions
279
+ */
280
+ actions?: TActions;
281
+ } & GlobalStoreConfig<TState, TMetadata, TActions>;
282
+ export type SelectorCallback<TState, TDerivate> = (state: TState) => TDerivate;
283
+ /**
284
+ * @description
285
+ * Function to subscribe to the store changes
286
+ * @returns {UnsubscribeCallback} result - Function to unsubscribe from the store
287
+ */
288
+ export type SubscribeToEmitter<TState> = <TParam1 extends SubscribeCallback<TState> | SelectorCallback<TState, unknown>, TResult = ReturnType<TParam1>, TConfig = TResult extends void | null | undefined | never ? SubscribeCallbackConfig<TState> : SubscribeCallbackConfig<TResult>, TParam2 extends SubscribeCallbackConfig<TState> | SubscribeCallback<TResult> = TResult extends void | null | undefined | never ? TConfig : SubscribeCallback<TResult>, TParam3 = TResult extends void | null | undefined | never ? never : TConfig>(
289
+ /**
290
+ * @description
291
+ * The callback function to subscribe to the store changes or a selector function to derive the state
292
+ */
293
+ param1: TParam1,
294
+ /**
295
+ * @description
296
+ * The configuration object or the callback function to subscribe to the store changes
297
+ */
298
+ param2?: TParam2,
299
+ /**
300
+ * @description
301
+ * The configuration object
302
+ */
303
+ param3?: TParam3) => UnsubscribeCallback;
304
+ export type SubscriberParameters = {
305
+ subscriptionId: string;
306
+ selector: SelectorCallback<any, any>;
307
+ config: UseHookConfig<any> | SubscribeCallbackConfig<any>;
308
+ currentState: unknown;
309
+ callback: SubscriptionCallback;
310
+ };
311
+ export type SubscriptionCallback = (params: {
312
+ state: unknown;
313
+ }) => void;
314
+ export type SetStateCallback = (parameters: {
315
+ state: unknown;
316
+ }) => void;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Shallow compare two values and return true if they are equal.
3
+ * This function just compare the first level of the values.
4
+ * @param value1
5
+ * @param value2
6
+ * @returns {boolean} true if the values are equal, false otherwise
7
+ */
8
+ export declare const shallowCompare: <T>(value1: T, value2: T) => boolean;
9
+ /**
10
+ * Debounce a function.
11
+ */
12
+ export declare const debounce: <T extends (...args: any[]) => any>(callback: T, delay?: number) => (...args: Parameters<T>) => ReturnType<T>;
13
+ export declare const uniqueId: () => string;
@@ -0,0 +1,15 @@
1
+ import { StateSetter, StateConfigCallbackParam, StateChangesParam, ActionCollectionConfig, GlobalStoreConfig } from "./GlobalStore.types";
2
+ import { GlobalStore } from "./GlobalStore";
3
+ /**
4
+ * @description
5
+ * Use this class to extends the capabilities of the GlobalStore.
6
+ * by implementing the abstract methods onInitialize and onChange.
7
+ * You can use this class to create a store with async storage.
8
+ */
9
+ export declare abstract class GlobalStoreAbstract<TState, TMetadata = null, TStateSetter extends ActionCollectionConfig<TState, TMetadata> | StateSetter<TState> = StateSetter<TState>> extends GlobalStore<TState, TMetadata, TStateSetter> {
10
+ constructor(state: TState, config?: GlobalStoreConfig<TState, TMetadata, TStateSetter>, actionsConfig?: TStateSetter | null);
11
+ protected onInit: (parameters: StateConfigCallbackParam<TState, TMetadata, TStateSetter>) => void;
12
+ protected onStateChanged: (parameters: StateChangesParam<TState, TMetadata, TStateSetter>) => void;
13
+ protected abstract onInitialize: ({ setState, setMetadata, getMetadata, getState, actions, }: StateConfigCallbackParam<TState, TMetadata, TStateSetter>) => void;
14
+ protected abstract onChange: ({ setState, setMetadata, getMetadata, getState, actions, }: StateChangesParam<TState, TMetadata, TStateSetter>) => void;
15
+ }
@@ -0,0 +1,7 @@
1
+ export * from "json-storage-formatter";
2
+ export * from "./GlobalStore.types";
3
+ export * from "./GlobalStore";
4
+ export * from "./GlobalStoreAbstract";
5
+ export * from "./GlobalStore.functionHooks";
6
+ export * from "./GlobalStore.utils";
7
+ export * from "./GlobalStore.combiners";
package/package.json ADDED
@@ -0,0 +1,86 @@
1
+ {
2
+ "name": "react-hooks-global-states",
3
+ "version": "1.0.0",
4
+ "description": "This is a package to easily handling global-state across your react-components No-redux",
5
+ "main": "lib/bundle.js",
6
+ "types": "lib/src/index.d.ts",
7
+ "files": [
8
+ "lib"
9
+ ],
10
+ "scripts": {
11
+ "test:debug": "node --inspect-brk node_modules/.bin/jest --watch --runInBand",
12
+ "test:quick": "jest --maxWorkers=4 -c --no-watchman -u",
13
+ "test:coverage": "jest --maxWorkers=4 -c --colors --no-watchman --verbose --coverage",
14
+ "build": "webpack --config webpack.config.js",
15
+ "prepare": "npm run build",
16
+ "version": "npm run format && git add -A src",
17
+ "postversion": "git push && git push --tags",
18
+ "lint": "eslint src --ext .js,.jsx,.ts,.tsx --max-warnings=0",
19
+ "lint:fix": "eslint --fix src --ext .js,.jsx,.ts,.tsx --max-warnings=0"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/johnny-quesada-developer/react-hooks-global-states.git"
24
+ },
25
+ "keywords": [
26
+ "react",
27
+ "redux",
28
+ "state",
29
+ "useState",
30
+ "useContext",
31
+ "global-state",
32
+ "context",
33
+ "typescript",
34
+ "react-native",
35
+ "async-storage"
36
+ ],
37
+ "author": "Johnny Quesada",
38
+ "license": "MIT",
39
+ "bugs": {
40
+ "url": "https://github.com/johnny-quesada-developer/react-hooks-global-states/issues"
41
+ },
42
+ "homepage": "https://github.com/johnny-quesada-developer/react-hooks-global-states#readme",
43
+ "devDependencies": {
44
+ "@babel/core": "^7.21.3",
45
+ "@babel/plugin-transform-modules-commonjs": "^7.21.2",
46
+ "@babel/preset-env": "^7.20.2",
47
+ "@babel/preset-react": "^7.18.6",
48
+ "@babel/preset-typescript": "^7.21.0",
49
+ "@types/jest": "^26.0.17",
50
+ "@types/lodash": "^4.14.165",
51
+ "@types/react": "^17.0.0",
52
+ "@types/react-dom": "^17.0.0",
53
+ "@types/react-test-renderer": "^17.0.0",
54
+ "@typescript-eslint/eslint-plugin": "^4.9.1",
55
+ "@typescript-eslint/parser": "^4.9.1",
56
+ "babel-loader": "^9.1.2",
57
+ "cancelable-promise-jq": "^1.0.4",
58
+ "clean-webpack-plugin": "^4.0.0",
59
+ "eslint": "^7.15.0",
60
+ "eslint-config-airbnb": "^18.2.1",
61
+ "eslint-plugin-import": "^2.22.1",
62
+ "eslint-plugin-jsx-a11y": "^6.4.1",
63
+ "eslint-plugin-react": "^7.21.5",
64
+ "eslint-plugin-react-hooks": "^4.2.0",
65
+ "jest": "^26.6.3",
66
+ "react": ">=17.0.0",
67
+ "react-test-renderer": "^17.0.1",
68
+ "ts-jest": "^26.4.4",
69
+ "ts-loader": "^9.4.2",
70
+ "tslib": "^2.5.0",
71
+ "typescript": "^4.9.5",
72
+ "webpack": "^5.76.3",
73
+ "webpack-cli": "^5.0.1"
74
+ },
75
+ "peerDependencies": {
76
+ "react": ">=17.0.0"
77
+ },
78
+ "peerDependenciesMeta": {
79
+ "react": {
80
+ "optional": false
81
+ }
82
+ },
83
+ "dependencies": {
84
+ "json-storage-formatter": "^1.0.9"
85
+ }
86
+ }