diff --git a/src/store/loadingState.ts b/src/store/loadingState.ts index 3c42c962..cf71e3f9 100644 --- a/src/store/loadingState.ts +++ b/src/store/loadingState.ts @@ -1,17 +1,13 @@ -import { create } from 'zustand'; -import { devtools } from 'zustand/middleware'; -import { IS_PROD_MODE } from '@common/constants/bundle.constants'; +import { StateCreator } from 'zustand'; import { createBaseSlice, SliceState } from './utils/slice'; +import { generateStore } from './utils/storeCreator'; export type LoadingState = SliceState<'isLoading', boolean>; const STORE_NAME = 'LoadingState'; -export const useLoadingStateStore = create()( - devtools( - (...args) => ({ - ...createBaseSlice({ basic: 'isLoading' }, false)(...args), - }), - { name: 'Linked Data Editor', store: STORE_NAME, enabled: !IS_PROD_MODE }, - ), -); +const loadingStateStore: StateCreator = (...args) => ({ + ...createBaseSlice({ basic: 'isLoading' }, false)(...args), +}); + +export const useLoadingStateStore = generateStore(loadingStateStore, STORE_NAME); diff --git a/src/store/marcPreview.ts b/src/store/marcPreview.ts index 29065873..ff3a1131 100644 --- a/src/store/marcPreview.ts +++ b/src/store/marcPreview.ts @@ -1,7 +1,6 @@ -import { create } from 'zustand'; -import { devtools } from 'zustand/middleware'; -import { IS_PROD_MODE } from '@common/constants/bundle.constants'; +import { StateCreator } from 'zustand'; import { createBaseSlice, SliceState } from './utils/slice'; +import { generateStore } from './utils/storeCreator'; type MarcPreviewData = MarcDTO | null; type MarcPreviewMetaData = MarcPreviewMetadata | null; @@ -12,13 +11,10 @@ export type MarcPreviewState = SliceState<'basicValue', any> & const STORE_NAME = 'MarcPreview'; -export const useMarcPreviewStore = create()( - devtools( - (...args) => ({ - ...createBaseSlice({ basic: 'basicValue' }, null)(...args), - ...createBaseSlice({ basic: 'complexValue' }, null as MarcPreviewData)(...args), - ...createBaseSlice({ basic: 'metaData' }, null as MarcPreviewMetaData)(...args), - }), - { name: 'Linked Data Editor', store: STORE_NAME, enabled: !IS_PROD_MODE }, - ), -); +const marcPreviewStore: StateCreator = (...args) => ({ + ...createBaseSlice({ basic: 'basicValue' }, null)(...args), + ...createBaseSlice({ basic: 'complexValue' }, null as MarcPreviewData)(...args), + ...createBaseSlice({ basic: 'metaData' }, null as MarcPreviewMetaData)(...args), +}); + +export const useMarcPreviewStore = generateStore(marcPreviewStore, STORE_NAME); diff --git a/src/store/status.ts b/src/store/status.ts index 00219aa3..efb4bbaf 100644 --- a/src/store/status.ts +++ b/src/store/status.ts @@ -1,7 +1,6 @@ -import { create } from 'zustand'; -import { devtools } from 'zustand/middleware'; -import { IS_PROD_MODE } from '@common/constants/bundle.constants'; +import { StateCreator } from 'zustand'; import { createBaseSlice, SliceState } from './utils/slice'; +import { generateStore } from './utils/storeCreator'; type LastSavedRecordId = string | null; @@ -12,18 +11,15 @@ export type StatusState = SliceState<'lastSavedRecordId', LastSavedRecordId> & const STORE_NAME = 'Status'; -export const useStatusStore = create()( - devtools( - (...args) => ({ - ...createBaseSlice({ basic: 'lastSavedRecordId' }, null as LastSavedRecordId)(...args), - ...createBaseSlice({ basic: 'isEditedRecord' }, false)(...args), - ...createBaseSlice({ basic: 'recordStatus' }, { type: undefined } as RecordStatus)(...args), - ...createBaseSlice<'statusMessages', StatusEntry[], 'statusMessage', StatusEntry>( - { basic: 'statusMessages', singleItem: 'statusMessage' }, - [] as StatusEntry[], - true, - )(...args), - }), - { name: 'Linked Data Editor', store: STORE_NAME, enabled: !IS_PROD_MODE }, - ), -); +const statusStore: StateCreator = (...args) => ({ + ...createBaseSlice({ basic: 'lastSavedRecordId' }, null as LastSavedRecordId)(...args), + ...createBaseSlice({ basic: 'isEditedRecord' }, false)(...args), + ...createBaseSlice({ basic: 'recordStatus' }, { type: undefined } as RecordStatus)(...args), + ...createBaseSlice<'statusMessages', StatusEntry[], 'statusMessage', StatusEntry>( + { basic: 'statusMessages', singleItem: 'statusMessage' }, + [] as StatusEntry[], + true, + )(...args), +}); + +export const useStatusStore = generateStore(statusStore, STORE_NAME); diff --git a/src/store/utils/storeCreator.ts b/src/store/utils/storeCreator.ts new file mode 100644 index 00000000..42fa737d --- /dev/null +++ b/src/store/utils/storeCreator.ts @@ -0,0 +1,8 @@ +import { IS_PROD_MODE } from '@common/constants/bundle.constants'; +import { create, StateCreator } from 'zustand'; +import { devtools } from 'zustand/middleware'; + +const STORE_NAME = 'Linked Data Editor'; + +export const generateStore = (store: StateCreator, name: string) => + create()(devtools(store, { name: STORE_NAME, store: name, enabled: !IS_PROD_MODE })); diff --git a/src/test/__tests__/store/utils/slice.test.ts b/src/test/__tests__/store/utils/slice.test.ts index 430bcb4c..d4fac5d0 100644 --- a/src/test/__tests__/store/utils/slice.test.ts +++ b/src/test/__tests__/store/utils/slice.test.ts @@ -3,6 +3,9 @@ import { createBaseSlice } from '@src/store/utils/slice'; describe('createBaseSlice', () => { type KeyBasic = 'testKey'; type KeySingleItem = 'item'; + + const keys = { basic: 'testKey' }; + const initialValue = 'initialValue'; const set = jest.fn(); const get = jest.fn(); let store: any; @@ -12,23 +15,17 @@ describe('createBaseSlice', () => { }); test('"set" method updates the state', () => { - const keys = { basic: 'testKey' }; - const initialValue = 'initialValue'; - const sliceTitle = 'testSlice'; - const baseSlice = createBaseSlice(keys, initialValue, sliceTitle)(set, get, store); + const baseSlice = createBaseSlice(keys, initialValue)(set, get, store); baseSlice.setTestKey('newValue'); - expect(set).toHaveBeenCalledWith({ testKey: 'newValue' }, false, 'testSlice/setTestKey'); + expect(set).toHaveBeenCalledWith({ testKey: 'newValue' }, false, 'setTestKey'); }); test('"reset" method resets the state to initial value', () => { - const keys = { basic: 'testKey' }; - const initialValue = 'initialValue'; - const sliceTitle = 'testSlice'; - const baseSlice = createBaseSlice(keys, initialValue, sliceTitle)(set, get, store); + const baseSlice = createBaseSlice(keys, initialValue)(set, get, store); baseSlice.resetTestKey(); - expect(set).toHaveBeenCalledWith({ testKey: initialValue }, false, 'testSlice/resetTestKey'); + expect(set).toHaveBeenCalledWith({ testKey: initialValue }, false, 'resetTestKey'); }); describe('"add" method', () => { @@ -36,16 +33,10 @@ describe('createBaseSlice', () => { test('updates the state when canAddSingleItem is true', () => { const initialValue = ['initialValue']; - const sliceTitle = 'testSlice'; - const baseSlice = createBaseSlice<'testKey', string[], 'item', string>( - keys, - initialValue, - sliceTitle, - true, - )(set, get, store); + const baseSlice = createBaseSlice<'testKey', string[], 'item', string>(keys, initialValue, true)(set, get, store); baseSlice.addItem?.('newItem'); - expect(set).toHaveBeenCalledWith(expect.any(Function), false, 'testSlice/addTestKey'); + expect(set).toHaveBeenCalledWith(expect.any(Function), false, 'addTestKey'); const state = { testKey: ['initialValue'] }; const updater = set.mock.calls[0][0]; @@ -55,16 +46,14 @@ describe('createBaseSlice', () => { test('updates the state when value is an object', () => { type StateEntry = Record; const initialValue = { key1: 'value_1' } as StateEntry; - const sliceTitle = 'testSlice'; - const baseSlice = createBaseSlice( - keys, - initialValue, - sliceTitle, - true, - )(set, get, store); + const baseSlice = createBaseSlice(keys, initialValue, true)( + set, + get, + store, + ); baseSlice.addItem?.({ key2: 'value_2' }); - expect(set).toHaveBeenCalledWith(expect.any(Function), false, 'testSlice/addTestKey'); + expect(set).toHaveBeenCalledWith(expect.any(Function), false, 'addTestKey'); const state = { testKey: { key1: 'value_1' } }; const updater = set.mock.calls[0][0]; @@ -75,16 +64,14 @@ describe('createBaseSlice', () => { test('updates the state when value is a Set', () => { const initialValue = new Set(['value_1']); - const sliceTitle = 'testSlice'; - const baseSlice = createBaseSlice, KeySingleItem, string>( - keys, - initialValue, - sliceTitle, - true, - )(set, get, store); + const baseSlice = createBaseSlice, KeySingleItem, string>(keys, initialValue, true)( + set, + get, + store, + ); baseSlice.addItem?.('value_2'); - expect(set).toHaveBeenCalledWith(expect.any(Function), false, 'testSlice/addTestKey'); + expect(set).toHaveBeenCalledWith(expect.any(Function), false, 'addTestKey'); const state = { testKey: new Set(['value_1']) }; const updater = set.mock.calls[0][0];