react-native-global-state-hooks 2.0.2 → 2.0.4

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.advance.md CHANGED
@@ -1,61 +1,105 @@
1
-
2
- ## Customize persist storage
3
-
4
- Let suppose you don't like **async-storage** or you also want to implement some kind of encrypt-process. You could easily extend the **GlobalStore** Class, and customize your persist store implementation.
5
-
6
1
  ## Creating hooks with reusable actions
7
2
 
8
- Let's say you want to have a STATE with a specific set of actions that you could be reused. With this library is pretty easy to accomplish. Let's create **increase** and **decrease** actions to our COUNT-store. **useCountGlobal.ts**:
3
+ Let's say you want to have a STATE with a specific set of actions that you could be reused. With this library is pretty easy to accomplish. Let's create **increase** and **decrease** actions to our count-store. **useCountGlobal.ts**:
9
4
 
10
5
  ```JSX
11
- import * as IGlobalState from 'react-native-global-state-hooks/lib/GlobalStoreTypes';
12
- import GlobalStore from 'react-native-global-state-hooks';
6
+ import {
7
+ IActionCollectionConfig,
8
+ IActionCollectionResult,
9
+ StateSetter,
10
+ } from 'react-native-global-state-hooks/lib/GlobalStoreTypes';
11
+
12
+ /**
13
+ * When using a custom api, the getHook and getHookDecoupled will not longer return directly the setter,
14
+ * intead they will return and api with the specific actions and mutations defined for the store
15
+ * Creating a configuration object for our api
16
+ */
17
+ const countActionsApi: IActionCollectionConfig<number> = {
18
+ /* Decrease the value of the count */
19
+ decrease(decrease: number) {
20
+ /**
21
+ * We need to return the async function that is gonna take care of the state mutation or actions
22
+ */
23
+ return async (setter: StateSetter<number>, state: number) => {
24
+ /**
25
+ * Next, we perfom whatever modification we want on top of the store
26
+ */
27
+ return setter(state - decrease);
28
+ };
29
+ },
13
30
 
14
- export interface ICountActionsConfig extends IGlobalState.IActionCollectionConfig<number> {
15
- decrease: (decrease: number) => (setter: IGlobalState.StateSetter<number>, state: number) => Promise<void>,
16
- increase: (increase: number) => (setter: IGlobalState.StateSetter<number>, state: number) => Promise<void>,
17
- }
31
+ //* Lets add a new action to increase the value of the count */
32
+ increase(increase: number) {
18
33
 
19
- export interface ICountActions extends IGlobalState.IActionCollectionResult {
20
- decrease: (decrease: number) => Promise<void>,
21
- increase: (increase: number) => Promise<void>,
22
- }
34
+ return async (setter: StateSetter<number>, state: number) => {
35
+ return setter(state + increase);
36
+ };
37
+ },
38
+ };
39
+
40
+ /**
41
+ * Now our getHook and getHookDecoupled are gonna return our custom api instead of the StateSetter,
42
+ * This will allow us to have more control over our store since the mutations of the same are gonna be limitated
43
+ */
44
+ const countStore = new GlobalStore(0, countActionsApi);
45
+ ```
23
46
 
24
- const countActions: IActionCollectionConfig<number> = {
25
- decrease: (decrease: number) => async (setter: IGlobalState.StateSetter<number>, state: number) => {
26
- setter(state - decrease);
47
+ If we remove all the explanatory comments the code will look like this:
48
+
49
+ ```TS
50
+ const countStore = new GlobalStore(0, {
51
+ decrease(decrease: number) {
52
+ return (setter: StateSetter<number>, state: number) =>
53
+ setter(state - decrease);
27
54
  },
28
- increase: (increase: number) => async (setter: IGlobalState.StateSetter<number>, state: number) => {
29
- setter(state + increase);
55
+
56
+ increase(increase: number) {
57
+ return (setter: StateSetter<number>, state: number) =>
58
+ setter(state + increase);
30
59
  },
31
- };
60
+ } as IActionCollectionConfig<number>);
61
+ ```
32
62
 
33
- const countStore = new GlobalStore(0, countActions);
63
+ Now lets get our new global hook with specific API
34
64
 
35
- export const useCountGlobal = countStore.getHook<ICountActions>();
65
+ ```TS
66
+ export interface ICountActions
67
+ extends IActionCollectionResult<number, IActionCollectionConfig<number>> {
68
+ decrease: (decrease: number) => Promise<number>;
69
+ increase: (increase: number) => Promise<number>;
70
+ }
36
71
 
72
+ /**
73
+ * The ICountActions interface is optional but it allow you yo get more accurate results for the typescript autocompletes and validations, ignore this if you are not using TS
74
+ */
75
+ export const useCountGlobal = countStore.getHook<ICountActions>();
37
76
  ```
38
77
 
39
- Now the result of our useCountGlobal will return our actions instead of a simple setter... Let's see:
78
+ And that's it! the result of our useCountGlobal will return our actions instead of a simple setter... Let's see how that will look:
40
79
 
41
80
  ```JSX
42
81
  import { useCountGlobal } from './useCountGlobal'
43
82
 
44
- function Stage1() {
45
- const [count, actions] = useCountGlobal();
83
+ const MyComponent: Reac.FC = () => {
84
+ const [count, countActions] = useCountGlobal();
46
85
 
47
- const increaseClick = () => actions.increase(1);
48
- const decreaseClick = () => actions.decrease(1);
86
+ // this functions are strongly typed
87
+ const increaseClick = () => countActions.increase(1);
88
+ const decreaseClick = () => countActions.decrease(1);
49
89
 
50
90
  return (<>
51
- <label>{count}<label/><br/>
52
- <button onPress={increaseClick}>increase<button/>
53
- <button onPress={decreaseClick}>decrease<button/>
91
+ <Text>{count}<Text/>
92
+ <Button onPress={increaseClick} title={'increase'} />
93
+ <Button onPress={decreaseClick} title={'decrease'} />
54
94
  </>);
55
95
  }
56
96
 
57
97
  ```
58
98
 
99
+ ## Customize persist storage
100
+
101
+ Let suppose you don't like **async-storage** or you also want to implement some kind of encrypt-process. You could easily extend the **GlobalStore** Class, and customize your persist store implementation.
102
+
59
103
  ```JSX
60
104
  import GlobalState from 'react-native-global-state-hooks';
61
105
  import secureStorage from 'react-native-secure-storage';
@@ -70,6 +114,7 @@ export class SecureGlobalState<
70
114
 
71
115
  protected asyncStorageGetItem = () => secureStorage.getItem(this.persistStoreAs as string, config);
72
116
 
117
+ /** value is a json string*/
73
118
  protected asyncStorageSetItem = (value: string) => secureStorage.setItem(this.persistStoreAs as string, value, config);
74
119
 
75
120
  }
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # react-native-global-state-hooks
2
- This is a package to easily handling global-state across your react-native-components **No-redux**.
2
+ This is a package to easily handling global-state across your react-native-components **No-redux**, **No-context**
3
3
 
4
- 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
4
+ 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
5
 
6
6
  **after version 1.0.4, we migrated to @react-native-async-storage/async-storage, because @react-native-async-storage/async-storage has been deprecated!!**
7
7
 
@@ -16,14 +16,14 @@ import GlobalStore from 'react-native-global-state-hooks';
16
16
  // initialize your store with the default value of the same.
17
17
  const countStore = new GlobalStore(0);
18
18
 
19
- // youll use this function the same way you'll use the **useState**
19
+ // you'll use this function the same way you'll use the **useState**
20
20
  export const useCountGlobal = countStore.getHook();
21
21
 
22
22
  // That's it, that's a global store... Strongly typed, with a global-hook that we could reuse cross all our react-components.
23
23
  ```
24
24
 
25
25
  ## Implementing your global hook into your components
26
- Let's say we have two components **Stage1**, **Stage2**, in order to use our global hook they will look just like:
26
+ Let's say we have two components **MyFirstComponent**, **MySecondComponent**, in order to use our global hook they will look just like:
27
27
 
28
28
  ```JSX
29
29
  import { useCountGlobal } from './useCountGlobal'
@@ -32,14 +32,14 @@ const MyFirstComponent: React.FC = () => {
32
32
  const [count, setter] = useCountGlobal();
33
33
  const onClickAddOne = () => setter(count + 1);
34
34
 
35
- return (<button onPress={onClickAddOne}>count: {count}<button/>);
35
+ return (<Button title={`count: ${count}`} onPress={onClickAddOne} />);
36
36
  }
37
37
 
38
38
  const MySecondComponent: React.FC = () => {
39
39
  const [count, setter] = useCountGlobal();
40
40
  const onClickAddTwo = () => setter(count + 2);
41
41
 
42
- return (<button onPress={onClickAddTwo}>count: {count}<button/>);
42
+ return (<Button title={`count: ${count}`} onPress={onClickAddOne} />);
43
43
  }
44
44
 
45
45
  // Just like that! You are now using a global state!!
@@ -53,11 +53,11 @@ const countStore = new GlobalStore(0);
53
53
 
54
54
  ## Persisted store
55
55
 
56
- You could persist the state with **@react-native-async-storage** by just adding the **key-name** to the constructor of your global-store, for example:
56
+ You could persist the state with **@react-native-async-storage** by just adding the **storage-key** to the constructor of your global-store, for example:
57
57
 
58
58
  ```JSX
59
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.
60
+ // The Second parameter is an API to restrict access to the state, will talk about that later on [README]:./README.advance.md
61
61
  // The Third parameter is the key that will be used on the async-storage
62
62
  const countStore = new GlobalStore(0, null, 'GLOBAL_COUNT');
63
63
  ```
@@ -77,7 +77,7 @@ const MyComponent: React.FC = () => {
77
77
  */
78
78
  const countLabel = isCountReady ? `count: ${count}` : 'Loading async storage...';
79
79
 
80
- return (<button onPress={onClickAddOne}>{countLabel}<button/>);
80
+ return (<Button title={countLabel} onPress={onClickAddOne} />);
81
81
  }
82
82
  ```
83
83
 
@@ -109,7 +109,7 @@ import { useCountGlobal, setCountGlobalValue } from './useCountGlobal'
109
109
  const CountDisplayerComponent: React.FC = () => {
110
110
  const [count] = useCountGlobal();
111
111
 
112
- return (<label>{count}<label/><br/>);
112
+ return (<Text>{count}<Text/>);
113
113
  }
114
114
 
115
115
  // Stage2 does not need to be updated once the global count changes
@@ -118,17 +118,24 @@ const CountManagerComponent: React.FC = () => {
118
118
  const decreaseClick = () => setCountGlobalValue(count => count - 1);
119
119
 
120
120
  return (<>
121
- <button onPress={increaseClick}>increase<button/>
122
- <button onPress={decreaseClick}>decrease<button/>
121
+ <Button onPress={increaseClick} title={'increase'} />
122
+ <Button onPress={decreaseClick} title={'decrease'}/>
123
123
  </>);
124
124
  }
125
125
  ```
126
126
 
127
+ ## Advance Config
128
+ Here you can see more information how to create more complex services for your global stores.
129
+ [README]:./README.advance.md
130
+
127
131
  ## Advantages:
128
132
  1. Using REACT's simplest and default way to deal with the state.
129
- 3. 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
133
+ 2. Adding partial state designations (This is not on useState default functionality)
134
+ 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
+ 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*** data to lose the data types that you stored. For example when you are using datetimes
130
137
 
131
- ## Advance Config
138
+ # 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**...
132
140
 
133
- Here you can see more information how to create more complex services for your global stores.
134
- [README]:./README.advance.md
141
+ 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.
@@ -1,16 +1,28 @@
1
1
  /// <reference types="lodash" />
2
2
  import * as IGlobalStore from './GlobalStoreTypes';
3
3
  export declare const isPrimitive: <T>(value: T) => boolean;
4
- export declare class GlobalStore<IState, IPersist extends string | null = null, IsPersist extends boolean = IPersist extends null ? false : true, IActions extends IGlobalStore.IActionCollectionConfig<IState> | null = null> implements IGlobalStore.IGlobalState<IState, IPersist, IsPersist, IActions> {
4
+ export declare type IValueWithMedaData = {
5
+ _type_?: 'map' | 'set' | 'date';
6
+ value?: unknown;
7
+ };
8
+ export declare class GlobalStore<IState, IPersist extends string | null, IActions extends IGlobalStore.IActionCollectionConfig<IState> | null = null> implements IGlobalStore.IGlobalState<IState, IPersist, IActions> {
5
9
  protected state: IState;
6
10
  protected actions: IActions;
7
11
  persistStoreAs: IPersist;
12
+ /**
13
+ * This function can be used to format the data after it is loaded from the asyncStorage
14
+ */
15
+ onPersistStorageLoad: (obj: unknown) => (IState | null);
8
16
  subscribers: IGlobalStore.StateSetter<IState>[];
9
17
  get isPersistStore(): boolean;
10
- constructor(state: IState, actions?: IActions, persistStoreAs?: IPersist);
18
+ constructor(state: IState, actions?: IActions, persistStoreAs?: IPersist,
19
+ /**
20
+ * This function can be used to format the data after it is loaded from the asyncStorage
21
+ */
22
+ onPersistStorageLoad?: (obj: unknown) => (IState | null));
11
23
  private get isStoredStateItemUpdated();
12
24
  private storedStateItem;
13
- protected formatItemFromStore<T>(obj: T): unknown;
25
+ protected formatItemFromStore<T>(_obj: T): unknown;
14
26
  protected formatToStore<T>(obj: T): unknown;
15
27
  protected getAsyncStoreItemPromise: Promise<IState> | null;
16
28
  protected asyncStorageGetItem(): Promise<string | null>;
@@ -18,10 +30,10 @@ export declare class GlobalStore<IState, IPersist extends string | null = null,
18
30
  protected asyncStorageSetItem(valueToStore: string): Promise<void>;
19
31
  protected setAsyncStoreItem(): Promise<void>;
20
32
  protected getStateCopy: () => IState;
21
- getHook: <IApi extends IGlobalStore.ActionCollectionResult<IState, IActions> | null = IActions extends null ? null : IGlobalStore.ActionCollectionResult<IState, IActions>>() => () => [IState, IGlobalStore.IHookResult<IState, IActions, IApi>, IsPersist extends true ? boolean : null];
22
- getHookDecoupled: <IApi extends IGlobalStore.ActionCollectionResult<IState, IActions> | null = IActions extends null ? null : IGlobalStore.ActionCollectionResult<IState, IActions>>() => [() => IPersist extends string ? Promise<IState> : IState, IGlobalStore.IHookResult<IState, IActions, IApi>];
33
+ getHook: <IApi extends IGlobalStore.IActionCollectionResult<IState, IActions> | null = IActions extends null ? null : IGlobalStore.IActionCollectionResult<IState, IActions>>() => () => [IState, IGlobalStore.IHookResult<IState, IActions, IApi>, IPersist extends null ? false : boolean];
34
+ getHookDecoupled: <IApi extends IGlobalStore.IActionCollectionResult<IState, IActions> | null = IActions extends null ? null : IGlobalStore.IActionCollectionResult<IState, IActions>>() => [() => IPersist extends string ? Promise<IState> : IState, IGlobalStore.IHookResult<IState, IActions, IApi>];
23
35
  private _stateOrchestrator;
24
- protected get stateOrchestrator(): IGlobalStore.StateSetter<IState> | IGlobalStore.ActionCollectionResult<IState, IActions>;
36
+ protected get stateOrchestrator(): IGlobalStore.StateSetter<IState> | IGlobalStore.IActionCollectionResult<IState, IActions>;
25
37
  /**
26
38
  ** [subscriber-update-callback, hook]
27
39
  */
@@ -34,7 +46,8 @@ export declare class GlobalStore<IState, IPersist extends string | null = null,
34
46
  * React native cannot use unstable_batchedUpdates, it does not have any effect
35
47
  */
36
48
  static ExecutePendingBatches: import("lodash").DebouncedFunc<() => void>;
37
- protected getActions: <IApi extends IGlobalStore.ActionCollectionResult<IState, IGlobalStore.IActionCollectionConfig<IState>>>() => IApi;
49
+ protected getActions: <IApi extends IGlobalStore.IActionCollectionResult<IState, IGlobalStore.IActionCollectionConfig<IState>>>() => IApi;
50
+ deleteAsyncStoreItem: () => Promise<void>;
38
51
  }
39
52
  export default GlobalStore;
40
53
  //# sourceMappingURL=GlobalStore.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GlobalStore.d.ts","sourceRoot":"","sources":["../src/GlobalStore.ts"],"names":[],"mappings":";AAKA,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AAEnD,eAAO,MAAM,WAAW,0BAAuH,CAAC;AAEhJ,qBAAa,WAAW,CACtB,MAAM,EACN,QAAQ,SAAS,MAAM,GAAG,IAAI,GAAG,IAAI,EACrC,SAAS,SAAS,OAAO,GAAG,QAAQ,SAAS,IAAI,GAAG,KAAK,GAAG,IAAI,EAChE,QAAQ,SAAS,YAAY,CAAC,uBAAuB,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,IAAI,CAC3E,YAAW,YAAY,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;IAQ/D,SAAS,CAAC,KAAK,EAAE,MAAM;IAAE,SAAS,CAAC,OAAO,EAAE,QAAQ;IAA4B,cAAc,EAAE,QAAQ;IAN7G,WAAW,EAAE,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAM;IAE5D,IAAW,cAAc,IAAI,OAAO,CAEnC;gBAEqB,KAAK,EAAE,MAAM,EAAY,OAAO,GAAE,QAA2B,EAAS,cAAc,GAAE,QAA2B;IAEvI,OAAO,KAAK,wBAAwB,GAEnC;IAED,OAAO,CAAC,eAAe,CAAiC;IAExD,SAAS,CAAC,mBAAmB,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO;IA0BjD,SAAS,CAAC,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO;IAmB3C,SAAS,CAAC,wBAAwB,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAQ;IAElE,SAAS,CAAC,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;cAIvC,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;cAwBpC,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;cAIxD,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAUlD,SAAS,CAAC,YAAY,QAAO,MAAM,CAAyC;IAErE,OAAO,oRA2BZ;IAEK,gBAAgB,iLAGV,QAAQ,SAAS,MAAM,GAAG,QAAQ,MAAM,CAAC,GAAG,MAAM,oDAO7D;IAEF,OAAO,CAAC,kBAAkB,CAAyG;IAEnI,SAAS,KAAK,iBAAiB,IAAI,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,sBAAsB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAY1H;IAED;;MAEE;IACF,SAAS,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,MAAM,IAAI,EAAE,MAAM,CAAC,EAAE,CAAM;IAE7D,SAAS,CAAC,YAAY,6BAA8B,MAAM,KAAK,MAAM,aAAa,MAAM,IAAI,UAqB1F;IAEF,SAAS,CAAC,iBAAiB,6BAAoC,MAAM,KAAK,MAAM,MAC9E,QAAQ,MAAM,CAAC,CAAmF;IAEpG,SAAS,CAAC,+BAA+B,6BAAoC,MAAM,KAAK,MAAM,MAAI,QAAQ,MAAM,CAAC,CAK/G;IAEF,MAAM,CAAC,8BAA8B,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,CAAM;IAE3D;;MAEE;IACF,MAAM,CAAC,qBAAqB,6CAQtB;IAEN,SAAS,CAAC,UAAU,qHA0BlB;CAEH;AAED,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"GlobalStore.d.ts","sourceRoot":"","sources":["../src/GlobalStore.ts"],"names":[],"mappings":";AAKA,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AAEnD,eAAO,MAAM,WAAW,0BAAuH,CAAC;AAEhJ,oBAAY,kBAAkB,GAAG;IAC/B,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAChC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAA;AAED,qBAAa,WAAW,CACtB,MAAM,EACN,QAAQ,SAAS,MAAM,GAAG,IAAI,EAC9B,QAAQ,SAAS,YAAY,CAAC,uBAAuB,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,IAAI,CAC3E,YAAW,YAAY,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC;IAS9D,SAAS,CAAC,KAAK,EAAE,MAAM;IACvB,SAAS,CAAC,OAAO,EAAE,QAAQ;IACpB,cAAc,EAAE,QAAQ;IAE/B;;MAEE;IACK,oBAAoB,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;IAdzD,WAAW,EAAE,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAM;IAE5D,IAAW,cAAc,IAAI,OAAO,CAEnC;gBAGW,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,QAA2B,EACvC,cAAc,GAAE,QAA2B;IAElD;;MAEE;IACK,oBAAoB,GAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,MAAM,GAAG,IAAI,CAAc;IAG7E,OAAO,KAAK,wBAAwB,GAEnC;IAED,OAAO,CAAC,eAAe,CAAiC;IAExD,SAAS,CAAC,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO;IAkDlD,SAAS,CAAC,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO;IAoD3C,SAAS,CAAC,wBAAwB,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAQ;IAElE,SAAS,CAAC,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;cAIvC,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;cA2BpC,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;cAIxD,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAUlD,SAAS,CAAC,YAAY,QAAO,MAAM,CAAyC;IAErE,OAAO,sRA2BZ;IAEK,gBAAgB,mLAGV,QAAQ,SAAS,MAAM,GAAG,QAAQ,MAAM,CAAC,GAAG,MAAM,oDAO7D;IAEF,OAAO,CAAC,kBAAkB,CAA0G;IAEpI,SAAS,KAAK,iBAAiB,IAAI,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAY3H;IAED;;MAEE;IACF,SAAS,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,MAAM,IAAI,EAAE,MAAM,CAAC,EAAE,CAAM;IAE7D,SAAS,CAAC,YAAY,6BAA8B,MAAM,KAAK,MAAM,aAAa,MAAM,IAAI,UAqB1F;IAEF,SAAS,CAAC,iBAAiB,6BAAoC,MAAM,KAAK,MAAM,MAC9E,QAAQ,MAAM,CAAC,CAAmF;IAEpG,SAAS,CAAC,+BAA+B,6BAAoC,MAAM,KAAK,MAAM,MAAI,QAAQ,MAAM,CAAC,CAK/G;IAEF,MAAM,CAAC,8BAA8B,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,CAAM;IAE3D;;MAEE;IACF,MAAM,CAAC,qBAAqB,6CAQtB;IAEN,SAAS,CAAC,UAAU,sHA0BlB;IAEK,oBAAoB,QAAa,QAAQ,IAAI,CAAC,CAIpD;CAEF;AAED,eAAe,WAAW,CAAC"}
@@ -8,10 +8,15 @@ const async_storage_1 = (0, tslib_1.__importDefault)(require("@react-native-asyn
8
8
  const isPrimitive = (value) => (0, lodash_1.isNil)(value) || (0, lodash_1.isNumber)(value) || (0, lodash_1.isBoolean)(value) || (0, lodash_1.isString)(value) || typeof value === 'symbol';
9
9
  exports.isPrimitive = isPrimitive;
10
10
  class GlobalStore {
11
- constructor(state, actions = null, persistStoreAs = null) {
11
+ constructor(state, actions = null, persistStoreAs = null,
12
+ /**
13
+ * This function can be used to format the data after it is loaded from the asyncStorage
14
+ */
15
+ onPersistStorageLoad = () => null) {
12
16
  this.state = state;
13
17
  this.actions = actions;
14
18
  this.persistStoreAs = persistStoreAs;
19
+ this.onPersistStorageLoad = onPersistStorageLoad;
15
20
  this.subscribers = [];
16
21
  this.storedStateItem = undefined;
17
22
  this.getAsyncStoreItemPromise = null;
@@ -81,6 +86,11 @@ class GlobalStore {
81
86
  return result;
82
87
  }) })), {});
83
88
  };
89
+ this.deleteAsyncStoreItem = () => (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
90
+ if (!this.isPersistStore)
91
+ return;
92
+ yield async_storage_1.default.removeItem(this.persistStoreAs);
93
+ });
84
94
  }
85
95
  get isPersistStore() {
86
96
  return !!this.persistStoreAs;
@@ -88,30 +98,73 @@ class GlobalStore {
88
98
  get isStoredStateItemUpdated() {
89
99
  return this.storedStateItem !== undefined;
90
100
  }
91
- formatItemFromStore(obj) {
101
+ formatItemFromStore(_obj) {
102
+ var _a, _b;
103
+ const obj = _obj;
104
+ if ((0, exports.isPrimitive)(obj)) {
105
+ return obj;
106
+ }
107
+ const isMetaDate = (obj === null || obj === void 0 ? void 0 : obj._type_) === 'date';
108
+ if (isMetaDate) {
109
+ return new Date(obj.value);
110
+ }
111
+ const isMetaMap = (obj === null || obj === void 0 ? void 0 : obj._type_) === 'map';
112
+ if (isMetaMap) {
113
+ const mapData = ((_a = obj.value) !== null && _a !== void 0 ? _a : []).map(([key, item]) => [
114
+ key,
115
+ this.formatItemFromStore(item),
116
+ ]);
117
+ return new Map(mapData);
118
+ }
119
+ const isMetaSet = (obj === null || obj === void 0 ? void 0 : obj._type_) === 'set';
120
+ if (isMetaSet) {
121
+ const setData = (_b = obj.value) !== null && _b !== void 0 ? _b : [].map((item) => this.formatItemFromStore(item));
122
+ return new Set(setData);
123
+ }
92
124
  const isArray = Array.isArray(obj);
93
125
  if (isArray) {
94
126
  return obj.map((item) => this.formatItemFromStore(item));
95
127
  }
96
- return Object.keys(obj).filter((key) => !key.includes('_type')).reduce((acumulator, key) => {
97
- const type = obj[`${key}_type`];
128
+ const keys = Object.keys(obj);
129
+ return keys.reduce((acumulator, key) => {
98
130
  const unformatedValue = obj[key];
99
- const isDateType = type === 'date';
100
- if (isDateType) {
101
- return Object.assign(Object.assign({}, acumulator), { [key]: new Date(unformatedValue) });
102
- }
103
- return Object.assign(Object.assign({}, acumulator), { [key]: (0, exports.isPrimitive)(unformatedValue) ? unformatedValue : this.formatItemFromStore(unformatedValue) });
131
+ return Object.assign(Object.assign({}, acumulator), { [key]: this.formatItemFromStore(unformatedValue) });
104
132
  }, {});
105
133
  }
106
134
  formatToStore(obj) {
135
+ if ((0, exports.isPrimitive)(obj)) {
136
+ return obj;
137
+ }
107
138
  const isArray = Array.isArray(obj);
108
139
  if (isArray) {
109
140
  return obj.map((item) => this.formatToStore(item));
110
141
  }
111
- return Object.keys(obj).reduce((acumulator, key) => {
142
+ const isMap = obj instanceof Map;
143
+ if (isMap) {
144
+ const pairs = Array.from(obj.entries());
145
+ return {
146
+ _type_: 'map',
147
+ value: pairs.map((pair) => this.formatToStore(pair)),
148
+ };
149
+ }
150
+ const isSet = obj instanceof Set;
151
+ if (isSet) {
152
+ const values = Array.from(obj.values());
153
+ return {
154
+ _type_: 'set',
155
+ value: values.map((value) => this.formatToStore(value)),
156
+ };
157
+ }
158
+ if ((0, lodash_1.isDate)(obj)) {
159
+ return {
160
+ _type_: 'date',
161
+ value: obj.toISOString(),
162
+ };
163
+ }
164
+ const keys = Object.keys(obj);
165
+ return keys.reduce((acumulator, key) => {
112
166
  const value = obj[key];
113
- const isDatetime = value instanceof Date;
114
- return (Object.assign(Object.assign({}, acumulator), { [key]: (0, exports.isPrimitive)(value) || isDatetime ? value : this.formatToStore(value), [`${key}_type`]: isDatetime ? 'date' : typeof value }));
167
+ return (Object.assign(Object.assign({}, acumulator), { [key]: this.formatToStore(value) }));
115
168
  }, {});
116
169
  }
117
170
  asyncStorageGetItem() {
@@ -125,11 +178,13 @@ class GlobalStore {
125
178
  return this.getAsyncStoreItemPromise;
126
179
  this.getAsyncStoreItemPromise = new Promise((resolve) => {
127
180
  (() => (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
181
+ var _a;
128
182
  const item = yield this.asyncStorageGetItem();
129
183
  if (item) {
130
- const value = JSON.parse(item);
131
- const primitive = (0, exports.isPrimitive)(value);
132
- const newState = primitive || Array.isArray(value) ? value : this.formatItemFromStore(value);
184
+ let value = JSON.parse(item);
185
+ /** This allow users to review what is been stored */
186
+ value = (_a = this.onPersistStorageLoad(value)) !== null && _a !== void 0 ? _a : value;
187
+ const newState = this.formatItemFromStore(value);
133
188
  yield this.globalSetterAsync(newState);
134
189
  }
135
190
  resolve(this.state);
@@ -148,7 +203,7 @@ class GlobalStore {
148
203
  if (this.storedStateItem === this.state)
149
204
  return;
150
205
  this.storedStateItem = this.state;
151
- const valueToStore = (0, exports.isPrimitive)(this.state) ? this.state : this.formatToStore((0, lodash_1.cloneDeep)(this.state));
206
+ const valueToStore = this.formatToStore((0, lodash_1.cloneDeep)(this.state));
152
207
  yield this.asyncStorageSetItem(JSON.stringify(valueToStore));
153
208
  });
154
209
  }
@@ -14,21 +14,15 @@ export interface IActionCollectionConfig<IState> {
14
14
  [key: string]: IActionConfig<IState>;
15
15
  }
16
16
  /**
17
- * This should be the API format of the hook (if you passed an API as a parameter)
18
- */
19
- export interface IActionCollectionResult {
20
- [key: string]: (...params: any[]) => Promise<unknown>;
21
- }
22
- /**
23
17
  * This is the API result of the hook (if you passed an API as a parameter)
24
18
  */
25
- export declare type ActionCollectionResult<IState, IActions extends IActionCollectionConfig<IState> | null> = {
19
+ export declare type IActionCollectionResult<IState, IActions extends IActionCollectionConfig<IState> | null> = {
26
20
  [key in keyof IActions]: (...params: any[]) => unknown;
27
21
  };
28
22
  /**
29
23
  * Hook result, if you passed an API as a parameter it will be returned in the second position of the hook invoke.
30
24
  */
31
- export declare type IHookResult<IState, IActions extends IActionCollectionConfig<IState> | null = null, IApi extends ActionCollectionResult<IState, IActions> | null = IActions extends null ? null : ActionCollectionResult<IState, IActions>> = IApi extends null ? StateSetter<IState> : IActions extends IActionCollectionConfig<IState> ? IApi extends ActionCollectionResult<IState, IActions> ? IApi : StateSetter<IState> : StateSetter<IState>;
25
+ export declare type IHookResult<IState, IActions extends IActionCollectionConfig<IState> | null = null, IApi extends IActionCollectionResult<IState, IActions> | null = IActions extends null ? null : IActionCollectionResult<IState, IActions>> = IApi extends null ? StateSetter<IState> : IActions extends IActionCollectionConfig<IState> ? IApi extends IActionCollectionResult<IState, IActions> ? IApi : StateSetter<IState> : StateSetter<IState>;
32
26
  /**
33
27
  * This is a class to create global-store objects
34
28
  * @template IState
@@ -42,31 +36,31 @@ export declare type IHookResult<IState, IActions extends IActionCollectionConfig
42
36
  * this will disable the default return of the state-setter of the hook, and instead will return the API
43
37
  * @param {string} persistStoreAs - A name if you want to persist the state of the store in localstorage
44
38
  * */
45
- export interface IGlobalState<IState, IPersist extends string | null = null, IsPersist extends boolean = IPersist extends null ? false : true, IActions extends IActionCollectionConfig<IState> | null = null> {
39
+ export interface IGlobalState<IState, IPersist extends string | null = null, IActions extends IActionCollectionConfig<IState> | null = null> {
46
40
  persistStoreAs: IPersist;
47
41
  isPersistStore: boolean;
48
42
  /**
43
+ * This function can be used to format the data after it is loaded from the asyncStorage
44
+ */
45
+ onPersistStorageLoad: (obj: unknown) => (IState | null);
46
+ /**
49
47
  * Returns a global hook that will share information across components by subscribing them to a specific store.
50
48
  * @return [currentState, GlobalState.IHookResult<IState, IActions, IApi>, initialStatePersistStorage | null, isUpdatedPersistStorage | null]
51
49
  */
52
- getHook: <IApi extends IActions extends ActionCollectionResult<IState, IActions> ? ActionCollectionResult<IState, IActions> : null>() => () => [
50
+ getHook: <IApi extends IActions extends IActionCollectionResult<IState, IActions> ? IActionCollectionResult<IState, IActions> : null>() => () => [
53
51
  IState,
54
52
  IHookResult<IState, IActions, IApi>,
55
- IsPersist extends true ? boolean : null
53
+ IPersist extends null ? false : true extends true ? boolean : null
56
54
  ];
57
55
  /**
58
56
  * This is an access to the subscribers queue and to the current state of a specific store...
59
57
  * THIS IS NOT A REACT-HOOK, so you could use it everywhere example other hooks, and services.
60
58
  * @return [currentState, GlobalState.IHookResult<IState, IActions, IApi>]
61
59
  */
62
- getHookDecoupled: <IApi extends IActions extends ActionCollectionResult<IState, IActions> ? ActionCollectionResult<IState, IActions> : null>() => [
60
+ getHookDecoupled: <IApi extends IActions extends IActionCollectionResult<IState, IActions> ? IActionCollectionResult<IState, IActions> : null>() => [
63
61
  () => IPersist extends string ? Promise<IState> : IState,
64
62
  IHookResult<IState, IActions, IApi>
65
63
  ];
66
- }
67
- /**
68
- * @deprecated This interface name is deprecated, use instead IGlobalState
69
- */
70
- export interface IGlobalStateFactory<IState, IPersist extends string | null = null, IsPersist extends boolean = IPersist extends null ? false : true, IActions extends IActionCollectionConfig<IState> | null = null> extends IGlobalState<IState, IPersist, IsPersist, IActions> {
64
+ deleteAsyncStoreItem: () => Promise<void>;
71
65
  }
72
66
  //# sourceMappingURL=GlobalStoreTypes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GlobalStoreTypes.d.ts","sourceRoot":"","sources":["../src/GlobalStoreTypes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GlobalStoreTypes.d.ts","sourceRoot":"","sources":["../src/GlobalStoreTypes.ts"],"names":[],"mappings":"AAAA;;;EAGE;AACF,oBAAY,WAAW,CAAC,MAAM,IAAI,CAChC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,KACzC,OAAO,CAAC,MAAM,CAAC,CAAC;AAErB;;EAEE;AACF,oBAAY,aAAa,CAAC,MAAM,IAAI,CAElC,GAAG,MAAM,EAAE,GAAG,EAAE,KACb,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE7E;;EAEE;AACF,MAAM,WAAW,uBAAuB,CAAC,MAAM;IAC7C,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;CACtC;AAED;;EAEE;AACF,oBAAY,uBAAuB,CAAC,MAAM,EAAE,QAAQ,SAAS,uBAAuB,CAAC,MAAM,CAAC,GAAG,IAAI,IAAI;KAEpG,GAAG,IAAI,MAAM,QAAQ,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,KAAK,OAAO;CACvD,CAAC;AAEF;;EAEE;AACF,oBAAY,WAAW,CACrB,MAAM,EACN,QAAQ,SAAS,uBAAuB,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,IAAI,EAC9D,IAAI,SAAS,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,GAAG,QAAQ,SAAS,IAAI,GAAG,IAAI,GAAG,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,IACtI,IAAI,SAAS,IAAI,GACjB,WAAW,CAAC,MAAM,CAAC,GACnB,QAAQ,SAAS,uBAAuB,CAAC,MAAM,CAAC,GAChD,IAAI,SAAS,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,GACpD,IAAI,GACJ,WAAW,CAAC,MAAM,CAAC,GACrB,WAAW,CAAC,MAAM,CAAC,CAAC;AAExB;;;;;;;;;;;;IAYI;AACJ,MAAM,WAAW,YAAY,CAC3B,MAAM,EACN,QAAQ,SAAS,MAAM,GAAG,IAAI,GAAG,IAAI,EACrC,QAAQ,SAAS,uBAAuB,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,IAAI;IAG9D,cAAc,EAAE,QAAQ,CAAC;IAEzB,cAAc,EAAE,OAAO,CAAC;IAExB;;MAEE;IACF,oBAAoB,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAExD;;;MAGE;IACF,OAAO,EAAE,CAAC,IAAI,SAAS,QAAQ,SAAS,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,OAAO,MAAM;QAC/I,MAAM;QACN,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC;QACnC,QAAQ,SAAS,IAAI,GAAG,KAAK,GAAG,IAAI,SAAS,IAAI,GAAG,OAAO,GAAG,IAAI;KACnE,CAAC;IAEF;;;;MAIE;IACF,gBAAgB,EAAE,CAAC,IAAI,SAAS,QAAQ,SAAS,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,OAAO;QAClJ,MAAM,QAAQ,SAAS,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM;QACxD,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC;KACpC,CAAC;IAEF,oBAAoB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-global-state-hooks",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "This is a package to easily handling global-state across your react-native-components No-redux",
5
5
  "main": "lib/GlobalStore.js",
6
6
  "files": [