From 4b8c1cc3db22d2ebcbeeea151223492b8e198b3a Mon Sep 17 00:00:00 2001 From: Siarhei Karol Date: Fri, 29 Nov 2024 12:35:25 +0300 Subject: [PATCH] update slices creator --- src/store/status.ts | 1 + src/store/utils/slice.ts | 79 +++++++++++++++++++++++++--------------- 2 files changed, 50 insertions(+), 30 deletions(-) diff --git a/src/store/status.ts b/src/store/status.ts index 45b9332d..462fbc3f 100644 --- a/src/store/status.ts +++ b/src/store/status.ts @@ -20,6 +20,7 @@ export const useStatusStoreBase = create()( 'statusMessages', [] as StatusEntry[], STORE_NAME, + true )(...args), })), ); diff --git a/src/store/utils/slice.ts b/src/store/utils/slice.ts index acb662ef..cc3e8522 100644 --- a/src/store/utils/slice.ts +++ b/src/store/utils/slice.ts @@ -8,52 +8,71 @@ export type SliceState = { [P in `set${Capitalize}`]: (value: V) => void; } & { [P in `reset${Capitalize}`]: () => void; -} & { - [P in `add${Capitalize}`]: (value: T) => void; +} & Partial<{ + [P in `add${Capitalize}`]: (value: T) => void; + }>; + +const capitalize = (value: string) => { + return value.charAt(0).toUpperCase() + value.slice(1); +}; + +const updateValue = (value: V, updatedValue: T): V => { + if (Array.isArray(value)) { + return [...value, updatedValue] as any; + } else if (value instanceof Map) { + const newMap = new Map(value); + + if (updatedValue instanceof Map) { + updatedValue.forEach((value, key) => newMap.set(key, value)); + } else if (typeof updatedValue === 'object' && updatedValue !== null) { + Object.entries(updatedValue).forEach(([k, v]) => newMap.set(k, v)); + } + + return newMap as any; + } else if (typeof value === 'object' && value !== null) { + if (typeof updatedValue === 'object' && updatedValue !== null) { + return { ...value, ...updatedValue } as any; + } + + return updatedValue as any; + } else if (value instanceof Set) { + return new Set([...value, updatedValue]) as any; + } else if (typeof value === 'string') { + return `${value}${updatedValue}` as any; + } + + return updatedValue as any; }; export const createBaseSlice = ( valueTitle: K, initialValue: V, sliceTitle: string, + canAddSingleItem = false, ): StateCreator, [['zustand/devtools', never]], [], SliceState> => { return set => { const capitalizedTitle = capitalize(valueTitle); - return { + const baseSlice = { [valueTitle]: initialValue, [`set${capitalizedTitle}`]: (updatedValue: V) => - set({ [valueTitle]: updatedValue } as any, undefined, `${sliceTitle}/set${capitalizedTitle}`), + set({ [valueTitle]: updatedValue } as any, false, `${sliceTitle}/set${capitalizedTitle}`), [`reset${capitalizedTitle}`]: () => - set({ [valueTitle]: initialValue } as any, undefined, `${sliceTitle}/set${capitalizedTitle}`), - [`add${capitalizedTitle}`]: (updatedValue: T) => + set({ [valueTitle]: initialValue } as any, false, `${sliceTitle}/reset${capitalizedTitle}`), + } as SliceState; + + if (canAddSingleItem) { + (baseSlice as any)[`add${capitalizedTitle}`] = (updatedValue: T) => set( state => { const value = state[valueTitle] as any; - - if (Array.isArray(value)) { - return { [valueTitle]: [...value, updatedValue] } as any; - } else if (typeof value === 'object' && value !== null) { - if (typeof updatedValue === 'object' && updatedValue !== null) { - return { [valueTitle]: { ...value, ...updatedValue } } as any; - } - - return { [valueTitle]: updatedValue } as any; - } else if (value instanceof Set) { - return { [valueTitle]: new Set([...value, updatedValue]) } as any; - } else if (typeof value === 'string') { - return { [valueTitle]: `${value}${updatedValue}` } as any; - } - - return { [valueTitle]: updatedValue } as any; + return { [valueTitle]: updateValue(value, updatedValue) } as any; }, - undefined, - `${sliceTitle}/set${capitalizedTitle}`, - ), - } as SliceState; - }; -}; + false, + `${sliceTitle}/add${capitalizedTitle}`, + ); + } -const capitalize = (value: string) => { - return value.charAt(0).toUpperCase() + value.slice(1); + return baseSlice; + }; };