react-native-global-state-hooks 2.0.6 → 2.1.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/README.md +304 -58
- package/lib/GlobalStore.d.ts +162 -45
- package/lib/GlobalStore.d.ts.map +1 -1
- package/lib/GlobalStore.js +283 -150
- package/lib/GlobalStore.types.d.ts +108 -0
- package/lib/GlobalStore.types.d.ts.map +1 -0
- package/lib/{GlobalStoreTypes.js → GlobalStore.types.js} +0 -0
- package/lib/GlobalStore.utils.d.ts +10 -0
- package/lib/GlobalStore.utils.d.ts.map +1 -0
- package/lib/GlobalStore.utils.js +23 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +6 -0
- package/package.json +4 -4
- package/lib/GlobalStoreTypes.d.ts +0 -66
- package/lib/GlobalStoreTypes.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,29 +1,52 @@
|
|
|
1
1
|
# react-native-global-state-hooks
|
|
2
|
+
|
|
2
3
|
This is a package to easily handling global-state across your react-native-components **No-redux**, **No-context**
|
|
3
4
|
|
|
4
5
|
This utility follows the same style as the default **useState** hook, with a subscription pattern and **HOFs** to create a more intuitive, atomic and easy way of sharing state between components
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
...
|
|
8
|
+
|
|
9
|
+
...
|
|
7
10
|
|
|
8
|
-
|
|
11
|
+
# Creating a global store, an a simple hook
|
|
9
12
|
|
|
10
13
|
We are gonna create a global count example **useCountGlobal.ts**:
|
|
11
14
|
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
import GlobalStore from 'react-native-global-state-hooks';
|
|
15
|
+
```ts
|
|
16
|
+
import { GlobalStore } from 'react-native-global-state-hooks';
|
|
15
17
|
|
|
16
18
|
// initialize your store with the default value of the same.
|
|
17
19
|
const countStore = new GlobalStore(0);
|
|
18
20
|
|
|
19
|
-
//
|
|
21
|
+
// get the hook
|
|
20
22
|
export const useCountGlobal = countStore.getHook();
|
|
21
23
|
|
|
24
|
+
// inside your component just call...
|
|
25
|
+
const [count, setCount] = useCountGlobal(); // no paremeters are needed since this is a global store
|
|
26
|
+
|
|
22
27
|
// That's it, that's a global store... Strongly typed, with a global-hook that we could reuse cross all our react-components.
|
|
28
|
+
|
|
29
|
+
// #### Optionally you are able to use a decoupled hook,
|
|
30
|
+
// #### This function is linked to the store hooks but is not a hook himself.
|
|
31
|
+
|
|
32
|
+
export const [getCount, sendCount] = countStore.getHookDecoupled();
|
|
33
|
+
|
|
34
|
+
// @example
|
|
35
|
+
console.log(getCount()); // 0;
|
|
36
|
+
|
|
37
|
+
// components subscribed to the global hook if there are so
|
|
38
|
+
sendCount(5);
|
|
39
|
+
|
|
40
|
+
console.log(getCount()); // 5;
|
|
23
41
|
```
|
|
24
42
|
|
|
25
|
-
|
|
26
|
-
|
|
43
|
+
...
|
|
44
|
+
|
|
45
|
+
...
|
|
46
|
+
|
|
47
|
+
# Implementing your global hook into your components
|
|
48
|
+
|
|
49
|
+
Let's say we have two components **MyFirstComponent**, **MySecondComponent**, in order to use our global hook they will look just like:
|
|
27
50
|
|
|
28
51
|
```JSX
|
|
29
52
|
import { useCountGlobal } from './useCountGlobal'
|
|
@@ -37,59 +60,34 @@ const MyFirstComponent: React.FC = () => {
|
|
|
37
60
|
|
|
38
61
|
const MySecondComponent: React.FC = () => {
|
|
39
62
|
const [count, setter] = useCountGlobal();
|
|
40
|
-
|
|
41
|
-
|
|
63
|
+
|
|
64
|
+
// it can also be use as a normal setter into a callback or other hooks
|
|
65
|
+
const onClickAddTwo = useCallback(() => setter(state => state + 2), [])
|
|
66
|
+
|
|
42
67
|
return (<Button title={`count: ${count}`} onPress={onClickAddOne} />);
|
|
43
68
|
}
|
|
44
69
|
|
|
45
|
-
//
|
|
70
|
+
// It's so simple to share information between components
|
|
46
71
|
```
|
|
47
72
|
|
|
48
73
|
Note that the only difference between this and the default **useState** hook is that you are not adding the initial value, cause you already did that when you created the store:
|
|
49
74
|
|
|
50
|
-
```
|
|
75
|
+
```ts
|
|
51
76
|
const countStore = new GlobalStore(0);
|
|
52
77
|
```
|
|
53
78
|
|
|
54
|
-
|
|
79
|
+
...
|
|
55
80
|
|
|
56
|
-
|
|
81
|
+
...
|
|
57
82
|
|
|
58
|
-
|
|
59
|
-
// The FIRST parameter is the initial value of the state
|
|
60
|
-
// The Second parameter is an API to restrict access to the state, will talk about that later on [README]:./README.advance.md
|
|
61
|
-
// The Third parameter is the key that will be used on the async-storage
|
|
62
|
-
const countStore = new GlobalStore(0, null, 'GLOBAL_COUNT');
|
|
63
|
-
```
|
|
83
|
+
# Decoupled hook
|
|
64
84
|
|
|
65
|
-
|
|
85
|
+
If you want to access the global state outside a component or outside a hook, or without subscribing the component to the state changes...
|
|
66
86
|
|
|
67
|
-
|
|
68
|
-
const MyComponent: React.FC = () => {
|
|
69
|
-
// connect the component to the global persisted storage
|
|
70
|
-
const [count, setCount, isCountReady] = useCountGlobal();
|
|
71
|
-
const onClickAddOne = () => setCount(count + 1);
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* since the async storage is ASYNC, the first time the hook is called into a component we may get the default value, instead of the one from the storage.
|
|
75
|
-
*
|
|
76
|
-
* We are able to validate this with the third value returned in the hook array **isCountReady**, which is a boolean which let us now if the async storage already was reached out.
|
|
77
|
-
*/
|
|
78
|
-
const countLabel = isCountReady ? `count: ${count}` : 'Loading async storage...';
|
|
87
|
+
This is especially useful when you want to create components that have edition access to a certain store, but they actually don't need to be reactive to the state changes, like a search component that just need to get the current state every time that is going to search the data; but actually don't need to be subscribed to the changes over the collection he is going to be filtering.
|
|
79
88
|
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## Decoupled hook
|
|
85
|
-
|
|
86
|
-
If you want to access the global state outside a component or outside a hook, or without subscribing the component to the state changes...
|
|
87
|
-
|
|
88
|
-
This is especially useful when you want to create components that have edition access to a certain store, but they actually don't need to be reactive to the state changes, like a search component that just need to get the current state every time that is going to search the data; but actually don't need to be subscribed to the changes over the collection he is going to be filtering.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
```JSX
|
|
92
|
-
import GlobalStore from 'react-native-global-state-hooks';
|
|
89
|
+
```ts
|
|
90
|
+
import { GlobalStore } from 'react-native-global-state-hooks';
|
|
93
91
|
|
|
94
92
|
const countStore = new GlobalStore(0);
|
|
95
93
|
|
|
@@ -97,14 +95,15 @@ const countStore = new GlobalStore(0);
|
|
|
97
95
|
export const useCountGlobal = countStore.getHook();
|
|
98
96
|
|
|
99
97
|
// this functions are not hooks, and they can be used in whatever place into your code, ClassComponents, OtherHooks, Services etc.
|
|
100
|
-
export const [
|
|
101
|
-
|
|
98
|
+
export const [getCount, sendCount] = countStore.getHookDecoupled();
|
|
102
99
|
```
|
|
103
100
|
|
|
104
|
-
Let's see a trivial example:
|
|
101
|
+
Let's see a trivial example:
|
|
102
|
+
|
|
103
|
+
...
|
|
105
104
|
|
|
106
105
|
```JSX
|
|
107
|
-
import { useCountGlobal,
|
|
106
|
+
import { useCountGlobal, sendCount } from './useCountGlobal'
|
|
108
107
|
|
|
109
108
|
const CountDisplayerComponent: React.FC = () => {
|
|
110
109
|
const [count] = useCountGlobal();
|
|
@@ -112,10 +111,12 @@ const CountDisplayerComponent: React.FC = () => {
|
|
|
112
111
|
return (<Text>{count}<Text/>);
|
|
113
112
|
}
|
|
114
113
|
|
|
114
|
+
// here we have a separate component that is gonna handle the state of the previous component we created,
|
|
115
|
+
// this new component is not gonna be affected by the changes applied on <CountDisplayerComponent/>
|
|
115
116
|
// Stage2 does not need to be updated once the global count changes
|
|
116
117
|
const CountManagerComponent: React.FC = () => {
|
|
117
|
-
const increaseClick = () =>
|
|
118
|
-
const decreaseClick = () =>
|
|
118
|
+
const increaseClick = useCallback(() => sendCount(count => count + 1), []);
|
|
119
|
+
const decreaseClick = useCallback(() => sendCount(count => count - 1), []);
|
|
119
120
|
|
|
120
121
|
return (<>
|
|
121
122
|
<Button onPress={increaseClick} title={'increase'} />
|
|
@@ -124,18 +125,263 @@ const CountManagerComponent: React.FC = () => {
|
|
|
124
125
|
}
|
|
125
126
|
```
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
...
|
|
129
|
+
|
|
130
|
+
...
|
|
131
|
+
|
|
132
|
+
# Extending the global storage
|
|
133
|
+
|
|
134
|
+
Implementing extra functionality to extend the capabilities of the GlobalStorage couldn't be easier!!!
|
|
135
|
+
|
|
136
|
+
Here is an example of how you could create your custom store that for example stores the state into a async-storage persistente...
|
|
137
|
+
|
|
138
|
+
You could just use this code right as it is by just adding also into your project **@react-native-async-storage** or whatever another async storage library.
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
export class GlobalStoreAsync<
|
|
142
|
+
TState,
|
|
143
|
+
TMetadata extends { readonly isAsyncStorageReady: boolean },
|
|
144
|
+
TStateSetter extends
|
|
145
|
+
| ActionCollectionConfig<TState, TMetadata>
|
|
146
|
+
| StateSetter<TState>
|
|
147
|
+
| null = StateSetter<TState>
|
|
148
|
+
> extends GlobalStore<TState, TMetadata, TStateSetter> {
|
|
149
|
+
protected isAsyncStorageReady: boolean = false;
|
|
150
|
+
|
|
151
|
+
constructor(
|
|
152
|
+
state: TState,
|
|
153
|
+
metadata: TMetadata = { isAsyncStorageReady: false } as TMetadata,
|
|
154
|
+
setterConfig: TStateSetter | null = null,
|
|
155
|
+
config: GlobalStoreConfig<TState, TMetadata, NonNullable<TStateSetter>> & {
|
|
156
|
+
asyncStorageKey: string; // key of the async storage
|
|
157
|
+
}
|
|
158
|
+
) {
|
|
159
|
+
super(state, metadata, setterConfig, config);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* This method will be called once the store is created after the constructor,
|
|
164
|
+
* this method is different from the onInit of the confg property and it won't be overriden
|
|
165
|
+
*/
|
|
166
|
+
protected onInit = async ({
|
|
167
|
+
setState,
|
|
168
|
+
setMetadata,
|
|
169
|
+
getMetadata,
|
|
170
|
+
}: StateConfigCallbackParam<
|
|
171
|
+
TState,
|
|
172
|
+
TMetadata,
|
|
173
|
+
NonNullable<TStateSetter>
|
|
174
|
+
>) => {
|
|
175
|
+
const storedItem: string = await asyncStorage.getItem('items');
|
|
176
|
+
|
|
177
|
+
this.isAsyncStorageReady = true;
|
|
178
|
+
|
|
179
|
+
setMetadata({
|
|
180
|
+
...getMetadata(),
|
|
181
|
+
isAsyncStorageReady: true,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
if (!storedItem) return;
|
|
185
|
+
|
|
186
|
+
const jsonParsed = JSON.parse(storedItem);
|
|
187
|
+
const items = formatFromStore<TState>(jsonParsed);
|
|
188
|
+
|
|
189
|
+
setState(items);
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
protected onStateChanged = ({
|
|
193
|
+
getState,
|
|
194
|
+
}: StateChangesParam<TState, TMetadata, NonNullable<TStateSetter>>) => {
|
|
195
|
+
const state = getState();
|
|
196
|
+
const formattedObject: Object = formatToStore(state);
|
|
197
|
+
const jsonValue = JSON.stringify(formattedObject);
|
|
198
|
+
|
|
199
|
+
asyncStorage.setItem('items', jsonValue);
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The methods **formatToStore** and **formatFromStore** are part of another library of my [json-storage-formatter](https://www.npmjs.com/package/json-storage-formatter)...
|
|
205
|
+
|
|
206
|
+
this super small library will help you to transform objects into json string and get them back without losing any of the original data types... no more problems when **stringify** Dates, Maps, Sets, etc...
|
|
207
|
+
|
|
208
|
+
...
|
|
209
|
+
|
|
210
|
+
Originally the library was implementing persistent storage by using the package **@react-native-async-storage**, but not all people want to use it or need to use it... so it has been removed. Feel free to use the above example to get back that functionality if you were using the previous versions of the package.
|
|
211
|
+
|
|
212
|
+
You could find this example on the [**GitHub** of the project](https://github.com/johnny-quesada-developer/json-storage-formatter), between the unit test sources when the case scenario was tested [GlobalStoreAsyc.ts](https://github.com/johnny-quesada-developer/react-native-global-state-hooks/blob/master/%40tests/__test__/GlobalStoreAsyc.ts)
|
|
213
|
+
|
|
214
|
+
...
|
|
215
|
+
|
|
216
|
+
...
|
|
217
|
+
|
|
218
|
+
# Restricting the manipulation of the global **state**
|
|
219
|
+
|
|
220
|
+
## Who hate reducers?
|
|
221
|
+
|
|
222
|
+
It's super common to have the wish or the necessity of restricting the manipulation of the **state** through a specific set of actions or manipulations...**Dispatches**? **Actions**? Let's make it simple BY adding a custom **API** to the configuration of our **GlobalStore**
|
|
223
|
+
...
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
const initialValue = 0;
|
|
227
|
+
|
|
228
|
+
// this is not reactive information that you could also store in the async storage
|
|
229
|
+
// upating the metadata will not trigger the onStateChanged method or any update on the components
|
|
230
|
+
const metadata = null;
|
|
231
|
+
|
|
232
|
+
const countStore = new GlobalStore(
|
|
233
|
+
initialValue,
|
|
234
|
+
metadata,
|
|
235
|
+
{
|
|
236
|
+
log: (message: string) => (): void => {
|
|
237
|
+
console.log(message);
|
|
238
|
+
},
|
|
239
|
+
|
|
240
|
+
increase(message: string) {
|
|
241
|
+
return (storeTools: StoreTools<number>) => {
|
|
242
|
+
this.log(message);
|
|
243
|
+
|
|
244
|
+
return storeTools.getState();
|
|
245
|
+
};
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
decrease(message: string) {
|
|
249
|
+
return (storeTools: StoreTools<number>) => {
|
|
250
|
+
this.log(message);
|
|
251
|
+
|
|
252
|
+
return storeTools.getState();
|
|
253
|
+
};
|
|
254
|
+
},
|
|
255
|
+
} as const // the -as const- is necessary to avoid typescript errors
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
// the way to get the hook is the same as for simple setters
|
|
259
|
+
const useCountStore = countStore.getHook();
|
|
260
|
+
|
|
261
|
+
// now instead of a setState method, you'll get an actions object
|
|
262
|
+
// that contains all the actions that you defined in the setterConfig
|
|
263
|
+
const [count, countActions] = useCountStore();
|
|
264
|
+
|
|
265
|
+
// count is the current state - 0 (number)
|
|
266
|
+
// countActions is an object that contains all the actions that you defined in the setterConfig
|
|
267
|
+
// countActions.increase(); // this will increase the count by 1, returns the new count (number)
|
|
268
|
+
// countActions.decrease(); // this will decrease the count by 1, returns the new count (number)
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
...
|
|
272
|
+
|
|
273
|
+
# Configuration callbacks
|
|
274
|
+
|
|
275
|
+
## config.onInit
|
|
276
|
+
|
|
277
|
+
This method will be called once the store is created after the constructor,
|
|
278
|
+
|
|
279
|
+
@examples
|
|
280
|
+
|
|
281
|
+
```ts
|
|
282
|
+
import { GlobalStore } from 'react-native-global-state-hooks';
|
|
283
|
+
|
|
284
|
+
const initialValue = 0;
|
|
285
|
+
|
|
286
|
+
const store = new GlobalStore(0, null, null, {
|
|
287
|
+
onInit: async ({ setMetadata, setState }) => {
|
|
288
|
+
const data = await someApiCall();
|
|
289
|
+
|
|
290
|
+
setState(data);
|
|
291
|
+
setMetadata({ isDataUpdated: true });
|
|
292
|
+
},
|
|
293
|
+
});
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
...
|
|
297
|
+
|
|
298
|
+
## config.onStateChanged
|
|
299
|
+
|
|
300
|
+
This method will be called every time the state is changed
|
|
301
|
+
|
|
302
|
+
@examples
|
|
303
|
+
|
|
304
|
+
```ts
|
|
305
|
+
import { GlobalStore } from 'react-native-global-state-hooks';
|
|
306
|
+
|
|
307
|
+
const store = new GlobalStore(0, null, null, {
|
|
308
|
+
onStateChanged: ({ getState }) => {
|
|
309
|
+
const state = getState();
|
|
310
|
+
|
|
311
|
+
console.log(state);
|
|
312
|
+
},
|
|
313
|
+
});
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
...
|
|
317
|
+
|
|
318
|
+
## config.onSubscribed
|
|
319
|
+
|
|
320
|
+
This method will be called every time a component is subscribed to the store
|
|
321
|
+
|
|
322
|
+
@examples
|
|
323
|
+
|
|
324
|
+
```ts
|
|
325
|
+
import { GlobalStore } from 'react-native-global-state-hooks';
|
|
326
|
+
|
|
327
|
+
const store = new GlobalStore(0, null, null, {
|
|
328
|
+
onSubscribed: ({ getState }) => {
|
|
329
|
+
console.log('A component was subscribed to the store');
|
|
330
|
+
},
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
...
|
|
335
|
+
|
|
336
|
+
## config.computePreventStateChange
|
|
337
|
+
|
|
338
|
+
This method will be called every time the state is going to be changed, if it returns true the state won't be changed
|
|
339
|
+
|
|
340
|
+
@examples
|
|
341
|
+
|
|
342
|
+
```ts
|
|
343
|
+
import { GlobalStore } from 'react-native-global-state-hooks';
|
|
344
|
+
|
|
345
|
+
const store = new GlobalStore(0, null, null, {
|
|
346
|
+
computePreventStateChange: ({ getState }) => {
|
|
347
|
+
const state = getState();
|
|
348
|
+
const shouldPrevent = state < 0;
|
|
349
|
+
|
|
350
|
+
if (shouldPrevent) return true;
|
|
351
|
+
|
|
352
|
+
return false;
|
|
353
|
+
},
|
|
354
|
+
});
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
...
|
|
358
|
+
|
|
359
|
+
...
|
|
360
|
+
|
|
361
|
+
...
|
|
362
|
+
|
|
363
|
+
...
|
|
364
|
+
|
|
365
|
+
...
|
|
130
366
|
|
|
131
367
|
## Advantages:
|
|
368
|
+
|
|
132
369
|
1. Using REACT's simplest and default way to deal with the state.
|
|
133
370
|
2. Adding partial state designations (This is not on useState default functionality)
|
|
134
371
|
3. Added availability to create actions and decoupled access to the states, no more connects, and dispatches, just call your actions as a normal service of whatever other libraries.
|
|
135
372
|
4. This library is already taking care of avoiding re-renders if the new state does not have changes
|
|
136
|
-
5. This tool also take care for you to avoid **async-storage
|
|
373
|
+
5. This tool also take care for you to avoid **async-storage\*** data to lose the data types that you stored. For example when you are using datetimes
|
|
374
|
+
|
|
375
|
+
...
|
|
376
|
+
|
|
377
|
+
...
|
|
378
|
+
|
|
379
|
+
...
|
|
380
|
+
|
|
381
|
+
...
|
|
137
382
|
|
|
138
383
|
# Finallly notes:
|
|
139
|
-
Are concern about performance? this library is for you, instead of handling huge complex stores with options like redux, or by passing the setState to a context Provider (because of the limitations that the context has)... You should just use this library, we are using the more atomic and 'native' way that REACT gives to handle the state, and that is the hook **useState**...
|
|
140
384
|
|
|
141
|
-
|
|
385
|
+
Are concern about performance? this library is for you, instead of handling huge complex stores with options like redux, or by passing the setState to a context Provider (because of the limitations that the context has)... You should just use this library, we are using the more atomic and 'native' way that REACT gives to handle the state, and that is the hook **useState**...
|
|
386
|
+
|
|
387
|
+
This utility is just including the implementation of the use state into a subscriber pattern, to enable you to create hooks that will be subscribed to specific store changes, does how we'll be creating a global state hook.
|
package/lib/GlobalStore.d.ts
CHANGED
|
@@ -1,48 +1,165 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
*
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
1
|
+
import { Dispatch, SetStateAction } from 'react';
|
|
2
|
+
import { ActionCollectionConfig, StateSetter, GlobalStoreConfig, ActionCollectionResult, StateConfigCallbackParam } from './GlobalStore.types';
|
|
3
|
+
/**
|
|
4
|
+
* The GlobalStore class is the main class of the library and it is used to create a GlobalStore instances
|
|
5
|
+
* @template {TState} TState - The type of the state object
|
|
6
|
+
* @template {TMetadata} TMetadata - The type of the metadata object (optional) (default: null) no reactive information set to share with the subscribers
|
|
7
|
+
* @template {TStateSetter} TStateSetter - The type of the setterConfig 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
|
|
8
|
+
* */
|
|
9
|
+
export declare class GlobalStore<TState, TMetadata = null, TStateSetter extends ActionCollectionConfig<TState, TMetadata> | StateSetter<TState> | null = StateSetter<TState>> {
|
|
10
|
+
protected state: TState;
|
|
11
|
+
protected metadata: TMetadata;
|
|
12
|
+
protected setterConfig: TStateSetter | null;
|
|
13
|
+
private config;
|
|
14
|
+
/**
|
|
15
|
+
* list of all the subscribers setState functions
|
|
16
|
+
* @template {TState} TState - The type of the state object
|
|
17
|
+
* */
|
|
18
|
+
subscribers: Set<StateSetter<TState>>;
|
|
19
|
+
/**
|
|
20
|
+
* execute once the store is created
|
|
21
|
+
* @template {TState} TState - The type of the state object
|
|
22
|
+
* @template {TMetadata} TMetadata - The type of the metadata object (optional) (default: null) no reactive information set to share with the subscribers
|
|
23
|
+
* @template {TStateSetter} TStateSetter - The type of the setterConfig 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
|
|
24
|
+
* @param {StateConfigCallbackParam<TState, TMetadata, TStateSetter>} parameters - The parameters object brings the following properties: setState, getState, setMetadata, getMetadata
|
|
25
|
+
* @param {Dispatch<SetStateAction<TState>>} parameters.setState - The setState function to update the state
|
|
26
|
+
* @param {() => TState} parameters.getState - The getState function to get the state
|
|
27
|
+
* @param {Dispatch<SetStateAction<TMetadata>>} parameters.setMetadata - The setMetadata function to update the metadata
|
|
28
|
+
* @param {() => TMetadata} parameters.getMetadata - The getMetadata function to get the metadata
|
|
29
|
+
* */
|
|
30
|
+
protected onInit?: GlobalStoreConfig<TState, TMetadata, TStateSetter>['onInit'];
|
|
31
|
+
/**
|
|
32
|
+
* execute every time the state is changed
|
|
33
|
+
* @template {TState} TState - The type of the state object
|
|
34
|
+
* @template {TMetadata} TMetadata - The type of the metadata object (optional) (default: null) no reactive information set to share with the subscribers
|
|
35
|
+
* @template {TStateSetter} TStateSetter - The type of the setterConfig 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
|
|
36
|
+
* @param {StateConfigCallbackParam<TState, TMetadata, TStateSetter>} parameters - The parameters object brings the following properties: setState, getState, setMetadata, getMetadata
|
|
37
|
+
* @param {Dispatch<SetStateAction<TState>>} parameters.setState - The setState function to update the state
|
|
38
|
+
* @param {() => TState} parameters.getState - The getState function to get the state
|
|
39
|
+
* @param {Dispatch<SetStateAction<TMetadata>>} parameters.setMetadata - The setMetadata function to update the metadata
|
|
40
|
+
* @param {() => TMetadata} parameters.getMetadata - The getMetadata function to get the metadata
|
|
41
|
+
* */
|
|
42
|
+
protected onStateChanged?: GlobalStoreConfig<TState, TMetadata, TStateSetter>['onStateChanged'];
|
|
43
|
+
/**
|
|
44
|
+
* Execute each time a new component gets subscribed to the store
|
|
45
|
+
* @template {TState} TState - The type of the state object
|
|
46
|
+
* @template {TMetadata} TMetadata - The type of the metadata object (optional) (default: null) no reactive information set to share with the subscribers
|
|
47
|
+
* @template {TStateSetter} TStateSetter - The type of the setterConfig 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
|
|
48
|
+
* @param {StateConfigCallbackParam<TState, TMetadata, TStateSetter>} parameters - The parameters object brings the following properties: setState, getState, setMetadata, getMetadata
|
|
49
|
+
* @param {Dispatch<SetStateAction<TState>>} parameters.setState - The setState function to update the state
|
|
50
|
+
* @param {() => TState} parameters.getState - The getState function to get the state
|
|
51
|
+
* @param {Dispatch<SetStateAction<TMetadata>>} parameters.setMetadata - The setMetadata function to update the metadata
|
|
52
|
+
* @param {() => TMetadata} parameters.getMetadata - The getMetadata function to get the metadata
|
|
53
|
+
* */
|
|
54
|
+
protected onSubscribed?: GlobalStoreConfig<TState, TMetadata, TStateSetter>['onSubscribed'];
|
|
55
|
+
/**
|
|
56
|
+
* Execute everytime a state change is triggered and before the state is updated, it allows to prevent the state change by returning true
|
|
57
|
+
* @template {TState} TState - The type of the state object
|
|
58
|
+
* @template {TMetadata} TMetadata - The type of the metadata object (optional) (default: null) no reactive information set to share with the subscribers
|
|
59
|
+
* @template {TStateSetter} TStateSetter - The type of the setterConfig 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
|
|
60
|
+
* @param {StateConfigCallbackParam<TState, TMetadata, TStateSetter>} parameters - The parameters object brings the following properties: setState, getState, setMetadata, getMetadata
|
|
61
|
+
* @param {Dispatch<SetStateAction<TState>>} parameters.setState - The setState function to update the state
|
|
62
|
+
* @param {() => TState} parameters.getState - The getState function to get the state
|
|
63
|
+
* @param {Dispatch<SetStateAction<TMetadata>>} parameters.setMetadata - The setMetadata function to update the metadata
|
|
64
|
+
* @param {() => TMetadata} parameters.getMetadata - The getMetadata function to get the metadata
|
|
65
|
+
* @returns {boolean} - true to prevent the state change, false to allow the state change
|
|
66
|
+
* */
|
|
67
|
+
protected computePreventStateChange?: GlobalStoreConfig<TState, TMetadata, TStateSetter>['computePreventStateChange'];
|
|
68
|
+
/**
|
|
69
|
+
* Create a new instance of the GlobalStore
|
|
70
|
+
* @param {TState} state - The initial state
|
|
71
|
+
* @param {TMetadata} metadata - The metadata object (optional) (default: null) no reactive information set to share with the subscribers
|
|
72
|
+
* @param {TStateSetter} setterConfig - The actions configuration object (optional) (default: null) if not null the store manipulation will be done through the actions
|
|
73
|
+
* @param {GlobalStoreConfig<TState, TMetadata>} config - The configuration object (optional) (default: { metadata: null })
|
|
74
|
+
* @param {StateConfigCallbackParam<TState, TMetadata>} config.onInit - The callback to execute when the store is initialized (optional) (default: null)
|
|
75
|
+
* @param {StateConfigCallbackParam<TState, TMetadata>} config.onStateChanged - The callback to execute when the state is changed (optional) (default: null)
|
|
76
|
+
* @param {StateConfigCallbackParam<TState, TMetadata>} config.onSubscribed - The callback to execute when a subscriber is added (optional) (default: null)
|
|
77
|
+
* @param {StateConfigCallbackParam<TState, TMetadata>} config.computePreventStateChange - The callback to execute when the state is changed to compute if the state change should be prevented (optional) (default: null)
|
|
78
|
+
* */
|
|
79
|
+
constructor(state: TState, metadata?: TMetadata, setterConfig?: TStateSetter | null, config?: GlobalStoreConfig<TState, TMetadata, TStateSetter>);
|
|
80
|
+
protected onInitializeStore: () => void;
|
|
81
|
+
/**
|
|
82
|
+
* gets a clone of the state
|
|
83
|
+
* @returns {TState} - The state clone
|
|
84
|
+
* */
|
|
85
|
+
protected getStateClone: () => TState;
|
|
86
|
+
/**
|
|
87
|
+
* gets a clone of the metadata
|
|
88
|
+
* @returns {TMetadata} - The metadata clone
|
|
89
|
+
* */
|
|
90
|
+
protected getMetadataClone: () => TMetadata;
|
|
91
|
+
/**
|
|
92
|
+
* set the state and update all the subscribers
|
|
93
|
+
* @param {StateSetter<TState>} setter - The setter function or the value to set
|
|
94
|
+
* @param {React.Dispatch<React.SetStateAction<TState>>} invokerSetState - The setState function of the component that invoked the state change (optional) (default: null) this is used to updated first the component that invoked the state change
|
|
95
|
+
* */
|
|
96
|
+
protected setState: ({ invokerSetState, state, }: {
|
|
97
|
+
state: TState;
|
|
98
|
+
invokerSetState?: React.Dispatch<React.SetStateAction<TState>>;
|
|
99
|
+
}) => void;
|
|
100
|
+
/**
|
|
101
|
+
* Set the value of the metadata property, this is no reactive and will not trigger a re-render
|
|
102
|
+
* @param {StateSetter<TMetadata>} setter - The setter function or the value to set
|
|
103
|
+
* */
|
|
104
|
+
protected setMetadata: StateSetter<TMetadata>;
|
|
105
|
+
/**
|
|
106
|
+
* get the parameters object to pass to the callback functions (onInit, onStateChanged, onSubscribed, computePreventStateChange)
|
|
107
|
+
* this parameters object brings the following properties: setState, getState, setMetadata, getMetadata
|
|
108
|
+
* this parameter object allows to update the state, get the state, update the metadata, get the metadata
|
|
109
|
+
* @param {{ invokerSetState?: React.Dispatch<React.SetStateAction<TState>> }} parameters - The setState function of the component that invoked the state change (optional) (default: null) this is used to updated first the component that invoked the state change
|
|
110
|
+
* @returns {StateConfigCallbackParam<TState, TMetadata>} - The parameters object
|
|
111
|
+
* */
|
|
112
|
+
protected getConfigCallbackParam: ({ invokerSetState, }: {
|
|
113
|
+
invokerSetState?: React.Dispatch<React.SetStateAction<TState>>;
|
|
114
|
+
}) => StateConfigCallbackParam<TState, TMetadata, TStateSetter>;
|
|
115
|
+
/**
|
|
116
|
+
* Returns a custom hook that allows to handle a global state
|
|
117
|
+
* @returns {[TState, TStateSetter, TMetadata]} - The state, the state setter or the actions map, the metadata
|
|
118
|
+
* */
|
|
119
|
+
getHook: () => () => [TState, TStateSetter extends StateSetter<TState> ? StateSetter<TState> : ActionCollectionResult<TState, TMetadata, TStateSetter>, TMetadata];
|
|
120
|
+
/**
|
|
121
|
+
* Returns an array with the a function to get the state, the state setter or the actions map, and a function to get the metadata
|
|
122
|
+
* @returns {[() => TState, TStateSetter, () => TMetadata]} - The state getter, the state setter or the actions map, the metadata getter
|
|
123
|
+
* */
|
|
124
|
+
getHookDecoupled: () => [() => TState, TStateSetter extends StateSetter<TState> ? StateSetter<TState> : ActionCollectionResult<TState, TMetadata, TStateSetter>, () => TMetadata];
|
|
125
|
+
/**
|
|
126
|
+
* returns a wrapper for the setState function that will update the state and all the subscribers
|
|
127
|
+
* @param {{ invokerSetState?: React.Dispatch<React.SetStateAction<TState>> }} parameters - The setState function of the component that invoked the state change (optional) (default: null) this is used to updated first the component that invoked the state change
|
|
128
|
+
* @returns {StateSetter<TState>} - The state setter
|
|
129
|
+
* */
|
|
130
|
+
protected getSetStateWrapper: ({ invokerSetState, }?: {
|
|
131
|
+
invokerSetState?: React.Dispatch<React.SetStateAction<TState>>;
|
|
132
|
+
}) => StateSetter<TState>;
|
|
133
|
+
/**
|
|
134
|
+
* Returns the state setter or the actions map
|
|
135
|
+
* @param {{ invokerSetState?: React.Dispatch<React.SetStateAction<TState>> }} parameters - The setState function of the component that invoked the state change (optional) (default: null) this is used to updated first the component that invoked the state change
|
|
136
|
+
* @returns {TStateSetter} - The state setter or the actions map
|
|
137
|
+
* */
|
|
138
|
+
protected getStateOrchestrator(invokerSetState?: React.Dispatch<React.SetStateAction<TState>>): StateSetter<TState> | ActionCollectionResult<TState, TMetadata, TStateSetter>;
|
|
139
|
+
/**
|
|
140
|
+
* Calculate whenever or not we should compute the callback parameters on the state change
|
|
141
|
+
* @returns {boolean} - True if we should compute the callback parameters on the state change
|
|
142
|
+
* */
|
|
143
|
+
protected hasStateCallbacks: () => boolean;
|
|
144
|
+
/**
|
|
145
|
+
* This is responsible for defining whenever or not the state change should be allowed or prevented
|
|
146
|
+
* the function also execute the functions:
|
|
147
|
+
* - onStateChanged (if defined) - this function is executed after the state change
|
|
148
|
+
* - computePreventStateChange (if defined) - this function is executed before the state change and it should return a boolean value that will be used to determine if the state change should be prevented or not
|
|
149
|
+
* @param {{ setter: StateSetter<TState>; invokerSetState?: React.Dispatch<React.SetStateAction<TState>> }} parameters - The state setter and the setState function of the component that invoked the state change (optional) (default: null) this is used to updated first the component that invoked the state change
|
|
150
|
+
*/
|
|
151
|
+
protected computeSetState: ({ setter, invokerSetState, }: {
|
|
152
|
+
setter: StateSetter<TState>;
|
|
153
|
+
invokerSetState?: React.Dispatch<React.SetStateAction<TState>>;
|
|
154
|
+
}) => void;
|
|
155
|
+
/**
|
|
156
|
+
* This creates a map of actions that can be used to modify or interact with the state
|
|
157
|
+
* @param {{ invokerSetState?: React.Dispatch<React.SetStateAction<TState>> }} parameters - The setState function of the component that invoked the state change (optional) (default: null) this is used to updated first the component that invoked the state change
|
|
158
|
+
* @returns {ActionCollectionResult<TState, TMetadata, TStateSetter>} - The actions map result of the configuration object passed to the constructor
|
|
159
|
+
* */
|
|
160
|
+
protected getStoreActionsMap: ({ invokerSetState, }: {
|
|
161
|
+
invokerSetState?: React.Dispatch<React.SetStateAction<TState>>;
|
|
162
|
+
}) => ActionCollectionResult<TState, TMetadata, TStateSetter>;
|
|
46
163
|
}
|
|
47
164
|
export default GlobalStore;
|
|
48
165
|
//# sourceMappingURL=GlobalStore.d.ts.map
|