Skip to content

Commit ffb63c2

Browse files
committed
[FIX] createPubSubStore logic
1 parent 8b16ae5 commit ffb63c2

1 file changed

Lines changed: 10 additions & 12 deletions

File tree

packages/react-tools-lib/src/hooks/state/createPubSubStore.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ function updateReference<T extends object, C>(currStore: T, storeSlice: object,
4343
* **`createPubSubStore`**: A state management hook implemented on Publish-Subscribe pattern. It allows components to subscribe to state changes and receive updates whenever the state is modified, providing a scalable and decoupled state management solution.__N.B.: to work properly, objects like Set, Map, Date or more generally objects without _Symbol.iterator_ must be treated as immutable__. [See demo](https://react-tools.ndria.dev/#/hooks/state/createPubSubStore)
4444
* @param {T extends object} obj - Object that rapresent the initialState of the store.
4545
* @param {E extends Record<string, (store: T, ...args: any) => void>} [mutatorsFn] - Object that contains specified void function to mutate the store value, not the store itself, that receives the store as first parameter and other optional parameters.
46-
* @param {boolean} [persist=false] - boolean that indicates if the store value will be persisted on the local Storage.
46+
* @param {"localStorage" | "sessionStorge"|undefined} [persist=undefined] - value that indicates where persist the store, on the local or session Storage. If it isn't provided then store will not persist.
4747
* @returns {{getStore:()=>T, mutateStore:(cb:(globStore:T)=>void), usePubSubStore:<C>(subscribe?: (store: T) => C)=>[T|C, (store: T|C|((currStore: T) => T)|((currStore: C) => C)) => void, () => T]}} result
4848
* An object with:
4949
* - __getStore__: __IMMUTABLE__ function that returns the store object.
@@ -55,32 +55,30 @@ function updateReference<T extends object, C>(currStore: T, storeSlice: object,
5555
* - _third element_: the __getState__. An _immutable_ function that returns the current subscribed value.
5656
* - _fourth element_: the __mutators__. Like above.
5757
*/
58-
export const createPubSubStore = <T extends object, E extends Record<string, (store: T, ...args: any) => void>>(obj: T, mutatorsFn?: E, persist?: boolean): { getStore: () => T; mutateStore: (cb: (globStore: T) => void) => void; mutators: Record<keyof E, (...args: ExtractTail<Parameters<E[keyof E]>>) => void>, usePubSubStore: { (subscribe?: undefined): [T, (store: T | ((currStore: T) => T)) => void, () => T, Record<keyof E, (...args: ExtractTail<Parameters<E[keyof E]>>) => void>]; <C>(subscribe?: (store: T) => C): [C, (store: C | ((currStore: C) => C)) => void, () => C, Record<keyof E, (...args: ExtractTail<Parameters<E[keyof E]>>) => void>]; <C>(subscribe?: (store: T) => C): [T | C, (store: T | C | ((currStore: T) => T) | ((currStore: C) => C)) => void, () => T, Record<keyof E, (...args: ExtractTail<Parameters<E[keyof E]>>) => void>] }} => {
58+
export const createPubSubStore = <T extends object, E extends Record<string, (store: T, ...args: any) => void>>(obj: T, mutatorsFn?: E, persist?: "localStorage" | "sessionStorge"): { getStore: () => T; mutateStore: (cb: (globStore: T) => void) => void; mutators: Record<keyof E, (...args: ExtractTail<Parameters<E[keyof E]>>) => void>, usePubSubStore: { (subscribe?: undefined): [T, (store: T | ((currStore: T) => T)) => void, () => T, Record<keyof E, (...args: ExtractTail<Parameters<E[keyof E]>>) => void>]; <C>(subscribe?: (store: T) => C): [C, (store: C | ((currStore: C) => C)) => void, () => C, Record<keyof E, (...args: ExtractTail<Parameters<E[keyof E]>>) => void>]; <C>(subscribe?: (store: T) => C): [T | C, (store: T | C | ((currStore: T) => T) | ((currStore: C) => C)) => void, () => T, Record<keyof E, (...args: ExtractTail<Parameters<E[keyof E]>>) => void>] }} => {
5959
const pubSub = new PublishSubscribePattern();
6060
const topicName = "pub_Sub_str-" + id;
6161
id++;
6262
let store:T;
6363
const mutators: Record<keyof E, (...args: ExtractTail<Parameters<E[keyof E]>>) => void> = {} as Record<keyof E, (...args: ExtractTail<Parameters<E[keyof E]>>) => void>;
64+
const storage = persist === "localStorage" ? localStorage : sessionStorage;
6465

6566
if (persist) {
66-
const serializedStore = localStorage.getItem(topicName);
67+
const serializedStore = storage.getItem(topicName);
6768
if (serializedStore) {
6869
store = JSON.parse(serializedStore);
6970
} else {
7071
store = { ...obj };
71-
localStorage.setItem(topicName, JSON.stringify(store));
72+
storage.setItem(topicName, JSON.stringify(store));
7273
}
73-
} else {
74-
store = { ...obj };
75-
localStorage.setItem(topicName, JSON.stringify(store));
7674
}
7775

7876
if (mutatorsFn) {
7977
for (const key in mutatorsFn) {
8078
mutators[key] = (...args) => {
8179
const str = getStore();
8280
mutatorsFn[key](str, ...args);
83-
persist && localStorage.setItem(topicName, JSON.stringify(str));
81+
persist && storage.setItem(topicName, JSON.stringify(str));
8482
pubSub.publish(topicName, str);
8583
}
8684
}
@@ -96,7 +94,7 @@ export const createPubSubStore = <T extends object, E extends Record<string, (st
9694
function mutateStore(cb: (globStore: T) => void) {
9795
const globStore = getStore();
9896
cb(globStore);
99-
persist && localStorage.setItem(topicName, JSON.stringify(globStore));
97+
persist && storage.setItem(topicName, JSON.stringify(globStore));
10098
pubSub.publish(topicName, globStore);
10199
}
102100

@@ -138,7 +136,7 @@ export const createPubSubStore = <T extends object, E extends Record<string, (st
138136
if (!subscribe) {
139137
//INFO if subscribe is undefined, i am updating the whole store.
140138
const updatedValue = store instanceof Function ? (store as ((currStore: T) => T))(currentStore.current as T) : store as T;
141-
persist && localStorage.setItem(topicName, JSON.stringify(updatedValue));
139+
persist && storage.setItem(topicName, JSON.stringify(updatedValue));
142140
pubSub.publish(topicName, updatedValue);
143141
} else {
144142
/**
@@ -155,13 +153,13 @@ export const createPubSubStore = <T extends object, E extends Record<string, (st
155153
}
156154
if (Array.isArray(updatedValue) || typeof updatedValue === "object") {
157155
storeSlice[path.current[path.current.length - 1]] = updatedValue;
158-
persist && localStorage.setItem(topicName, JSON.stringify(getStore()));
156+
persist && storage.setItem(topicName, JSON.stringify(getStore()));
159157
pubSub.publish(topicName, getStore());
160158
} else {
161159
const currStore = getStore();
162160
updateReference(currStore, storeSlice, path.current[path.current.length - 1], updatedValue);
163161
storeSlice = currStore as Record<string, unknown>;
164-
persist && localStorage.setItem(topicName, JSON.stringify(storeSlice));
162+
persist && storage.setItem(topicName, JSON.stringify(storeSlice));
165163
pubSub.publish(topicName, storeSlice);
166164
}
167165
}

0 commit comments

Comments
 (0)