From ca0684700e79c4112df6671b8e00bf102b47c03a Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Tue, 22 Jul 2025 15:45:35 +1000 Subject: [PATCH] refactor(ui): alternate approach to slice configs --- .../store/enhancers/reduxRemember/driver.ts | 70 +++------ invokeai/frontend/web/src/app/store/store.ts | 144 ++++++++---------- invokeai/frontend/web/src/app/store/types.ts | 16 +- .../features/changeBoardModal/store/slice.ts | 3 +- .../store/canvasSettingsSlice.ts | 2 +- .../controlLayers/store/canvasSlice.ts | 2 +- .../store/canvasStagingAreaSlice.ts | 2 +- .../controlLayers/store/lorasSlice.ts | 2 +- .../controlLayers/store/paramsSlice.ts | 2 +- .../controlLayers/store/refImagesSlice.ts | 4 +- .../store/dynamicPromptsSlice.ts | 2 +- .../features/gallery/store/gallerySlice.ts | 2 +- .../store/modelManagerV2Slice.ts | 2 +- .../src/features/nodes/store/nodesSlice.ts | 2 +- .../nodes/store/workflowLibrarySlice.ts | 2 +- .../nodes/store/workflowSettingsSlice.ts | 2 +- .../features/parameters/store/upscaleSlice.ts | 2 +- .../src/features/queue/store/queueSlice.ts | 2 +- .../stylePresets/store/stylePresetSlice.ts | 2 +- .../src/features/system/store/configSlice.ts | 2 +- .../src/features/system/store/systemSlice.ts | 2 +- .../web/src/features/ui/store/uiSlice.ts | 2 +- 22 files changed, 115 insertions(+), 156 deletions(-) diff --git a/invokeai/frontend/web/src/app/store/enhancers/reduxRemember/driver.ts b/invokeai/frontend/web/src/app/store/enhancers/reduxRemember/driver.ts index 4bdf47a142..b209a58785 100644 --- a/invokeai/frontend/web/src/app/store/enhancers/reduxRemember/driver.ts +++ b/invokeai/frontend/web/src/app/store/enhancers/reduxRemember/driver.ts @@ -1,45 +1,25 @@ import { StorageError } from 'app/store/enhancers/reduxRemember/errors'; import { $authToken } from 'app/store/nanostores/authToken'; import { $projectId } from 'app/store/nanostores/projectId'; -import type { UseStore } from 'idb-keyval'; -import { clear, createStore as createIDBKeyValStore, get, set } from 'idb-keyval'; -import { atom } from 'nanostores'; +import { $queueId } from 'app/store/nanostores/queueId'; +import { $isPendingPersist } from 'app/store/store'; import type { Driver } from 'redux-remember'; import { getBaseUrl } from 'services/api'; import { buildAppInfoUrl } from 'services/api/endpoints/appInfo'; -// Create a custom idb-keyval store (just needed to customize the name) -const $idbKeyValStore = atom(createIDBKeyValStore('invoke', 'invoke-store')); - -export const clearIdbKeyValStore = () => { - clear($idbKeyValStore.get()); -}; - -// Create redux-remember driver, wrapping idb-keyval -export const idbKeyValDriver: Driver = { - getItem: (key) => { - try { - return get(key, $idbKeyValStore.get()); - } catch (originalError) { - throw new StorageError({ - key, - projectId: $projectId.get(), - originalError, - }); - } - }, - setItem: (key, value) => { - try { - return set(key, value, $idbKeyValStore.get()); - } catch (originalError) { - throw new StorageError({ - key, - value, - projectId: $projectId.get(), - originalError, - }); - } - }, +const getUrl = (key?: string) => { + const baseUrl = getBaseUrl(); + const query: Record = {}; + if (key) { + query['key'] = key; + } + const queueId = $queueId.get(); + if (queueId) { + query['queueId'] = queueId; + } + const path = buildAppInfoUrl('client_state', query); + const url = `${baseUrl}/${path}`; + return url; }; const getHeaders = (extra?: Record) => { @@ -61,9 +41,7 @@ const getHeaders = (extra?: Record) => { export const serverBackedDriver: Driver = { getItem: async (key) => { try { - const baseUrl = getBaseUrl(); - const path = buildAppInfoUrl('client_state', { key }); - const url = `${baseUrl}/${path}`; + const url = getUrl(key); const headers = getHeaders(); const res = await fetch(url, { headers, method: 'GET' }); if (!res.ok) { @@ -81,11 +59,9 @@ export const serverBackedDriver: Driver = { }, setItem: async (key, value) => { try { - const baseUrl = getBaseUrl(); - const path = buildAppInfoUrl('client_state'); - const url = `${baseUrl}/${path}`; + const url = getUrl(key); const headers = getHeaders({ 'content-type': 'application/json' }); - const res = await fetch(url, { headers, method: 'POST', body: JSON.stringify({ key, value }) }); + const res = await fetch(url, { headers, method: 'POST', body: JSON.stringify(value) }); if (!res.ok) { throw new Error(`Response status: ${res.status}`); } @@ -102,12 +78,16 @@ export const serverBackedDriver: Driver = { }; export const resetClientState = async () => { - const baseUrl = getBaseUrl(); - const path = buildAppInfoUrl('client_state'); - const url = `${baseUrl}/${path}`; + const url = getUrl(); const headers = getHeaders(); const res = await fetch(url, { headers, method: 'DELETE' }); if (!res.ok) { throw new Error(`Response status: ${res.status}`); } }; + +window.addEventListener('beforeunload', (e) => { + if ($isPendingPersist.get()) { + e.preventDefault(); + } +}); diff --git a/invokeai/frontend/web/src/app/store/store.ts b/invokeai/frontend/web/src/app/store/store.ts index bdfbe7da9e..fe3c390897 100644 --- a/invokeai/frontend/web/src/app/store/store.ts +++ b/invokeai/frontend/web/src/app/store/store.ts @@ -1,5 +1,5 @@ import type { ThunkDispatch, TypedStartListening, UnknownAction } from '@reduxjs/toolkit'; -import { addListener, combineReducers, configureStore, createAction, createListenerMiddleware } from '@reduxjs/toolkit'; +import { addListener, combineReducers, configureStore, createListenerMiddleware } from '@reduxjs/toolkit'; import { logger } from 'app/logging/logger'; import { serverBackedDriver } from 'app/store/enhancers/reduxRemember/driver'; import { errorHandler } from 'app/store/enhancers/reduxRemember/errors'; @@ -43,14 +43,13 @@ import { diff } from 'jsondiffpatch'; import { atom } from 'nanostores'; import dynamicMiddlewares from 'redux-dynamic-middlewares'; import type { SerializeFunction, UnserializeFunction } from 'redux-remember'; -import { REMEMBER_PERSISTED, rememberEnhancer, rememberReducer } from 'redux-remember'; -import { newHistory } from 'redux-undo'; +import { rememberEnhancer, rememberReducer } from 'redux-remember'; +import undoable, { newHistory } from 'redux-undo'; import { serializeError } from 'serialize-error'; import { api } from 'services/api'; import { authToastMiddleware } from 'services/api/authToastMiddleware'; import type { JsonObject } from 'type-fest'; -import { getDebugLoggerMiddleware } from './middleware/debugLoggerMiddleware'; import { actionSanitizer } from './middleware/devtools/actionSanitizer'; import { actionsDenylist } from './middleware/devtools/actionsDenylist'; import { stateSanitizer } from './middleware/devtools/stateSanitizer'; @@ -61,49 +60,60 @@ export const listenerMiddleware = createListenerMiddleware(); const log = logger('system'); +// When adding a slice, add the config to the SLICE_CONFIGS object below, then add the reducer to ALL_REDUCERS. +// Remember to wrap undoable slices in `undoable()`. + const SLICE_CONFIGS = { - [canvasSessionSliceConfig.slice.name]: canvasSessionSliceConfig, - [canvasSettingsSliceConfig.slice.name]: canvasSettingsSliceConfig, - [canvasSliceConfig.slice.name]: canvasSliceConfig, - [changeBoardModalSliceConfig.slice.name]: changeBoardModalSliceConfig, - [configSliceConfig.slice.name]: configSliceConfig, - [dynamicPromptsSliceConfig.slice.name]: dynamicPromptsSliceConfig, - [gallerySliceConfig.slice.name]: gallerySliceConfig, - [lorasSliceConfig.slice.name]: lorasSliceConfig, - [modelManagerSliceConfig.slice.name]: modelManagerSliceConfig, - [nodesSliceConfig.slice.name]: nodesSliceConfig, - [paramsSliceConfig.slice.name]: paramsSliceConfig, - [queueSliceConfig.slice.name]: queueSliceConfig, - [refImagesSliceConfig.slice.name]: refImagesSliceConfig, - [stylePresetSliceConfig.slice.name]: stylePresetSliceConfig, - [systemSliceConfig.slice.name]: systemSliceConfig, - [uiSliceConfig.slice.name]: uiSliceConfig, - [upscaleSliceConfig.slice.name]: upscaleSliceConfig, - [workflowLibrarySliceConfig.slice.name]: workflowLibrarySliceConfig, - [workflowSettingsSliceConfig.slice.name]: workflowSettingsSliceConfig, + [canvasSessionSliceConfig.slice.reducerPath]: canvasSessionSliceConfig, + [canvasSettingsSliceConfig.slice.reducerPath]: canvasSettingsSliceConfig, + [canvasSliceConfig.slice.reducerPath]: canvasSliceConfig, + [changeBoardModalSliceConfig.slice.reducerPath]: changeBoardModalSliceConfig, + [configSliceConfig.slice.reducerPath]: configSliceConfig, + [dynamicPromptsSliceConfig.slice.reducerPath]: dynamicPromptsSliceConfig, + [gallerySliceConfig.slice.reducerPath]: gallerySliceConfig, + [lorasSliceConfig.slice.reducerPath]: lorasSliceConfig, + [modelManagerSliceConfig.slice.reducerPath]: modelManagerSliceConfig, + [nodesSliceConfig.slice.reducerPath]: nodesSliceConfig, + [paramsSliceConfig.slice.reducerPath]: paramsSliceConfig, + [queueSliceConfig.slice.reducerPath]: queueSliceConfig, + [refImagesSliceConfig.slice.reducerPath]: refImagesSliceConfig, + [stylePresetSliceConfig.slice.reducerPath]: stylePresetSliceConfig, + [systemSliceConfig.slice.reducerPath]: systemSliceConfig, + [uiSliceConfig.slice.reducerPath]: uiSliceConfig, + [upscaleSliceConfig.slice.reducerPath]: upscaleSliceConfig, + [workflowLibrarySliceConfig.slice.reducerPath]: workflowLibrarySliceConfig, + [workflowSettingsSliceConfig.slice.reducerPath]: workflowSettingsSliceConfig, }; const ALL_REDUCERS = { [api.reducerPath]: api.reducer, - [canvasSessionSliceConfig.slice.name]: canvasSessionSliceConfig.slice.reducer, - [canvasSettingsSliceConfig.slice.name]: canvasSettingsSliceConfig.slice.reducer, - [canvasSliceConfig.slice.name]: canvasSliceConfig.slice.reducer, - [changeBoardModalSliceConfig.slice.name]: changeBoardModalSliceConfig.slice.reducer, - [configSliceConfig.slice.name]: configSliceConfig.slice.reducer, - [dynamicPromptsSliceConfig.slice.name]: dynamicPromptsSliceConfig.slice.reducer, - [gallerySliceConfig.slice.name]: gallerySliceConfig.slice.reducer, - [lorasSliceConfig.slice.name]: lorasSliceConfig.slice.reducer, - [modelManagerSliceConfig.slice.name]: modelManagerSliceConfig.slice.reducer, - [nodesSliceConfig.slice.name]: nodesSliceConfig.slice.reducer, - [paramsSliceConfig.slice.name]: paramsSliceConfig.slice.reducer, - [queueSliceConfig.slice.name]: queueSliceConfig.slice.reducer, - [refImagesSliceConfig.slice.name]: refImagesSliceConfig.slice.reducer, - [stylePresetSliceConfig.slice.name]: stylePresetSliceConfig.slice.reducer, - [systemSliceConfig.slice.name]: systemSliceConfig.slice.reducer, - [uiSliceConfig.slice.name]: uiSliceConfig.slice.reducer, - [upscaleSliceConfig.slice.name]: upscaleSliceConfig.slice.reducer, - [workflowLibrarySliceConfig.slice.name]: workflowLibrarySliceConfig.slice.reducer, - [workflowSettingsSliceConfig.slice.name]: workflowSettingsSliceConfig.slice.reducer, + [canvasSessionSliceConfig.slice.reducerPath]: canvasSessionSliceConfig.slice.reducer, + [canvasSettingsSliceConfig.slice.reducerPath]: canvasSettingsSliceConfig.slice.reducer, + // Undoable! + [canvasSliceConfig.slice.reducerPath]: undoable( + canvasSliceConfig.slice.reducer, + canvasSliceConfig.undoableConfig?.reduxUndoOptions + ), + [changeBoardModalSliceConfig.slice.reducerPath]: changeBoardModalSliceConfig.slice.reducer, + [configSliceConfig.slice.reducerPath]: configSliceConfig.slice.reducer, + [dynamicPromptsSliceConfig.slice.reducerPath]: dynamicPromptsSliceConfig.slice.reducer, + [gallerySliceConfig.slice.reducerPath]: gallerySliceConfig.slice.reducer, + [lorasSliceConfig.slice.reducerPath]: lorasSliceConfig.slice.reducer, + [modelManagerSliceConfig.slice.reducerPath]: modelManagerSliceConfig.slice.reducer, + // Undoable! + [nodesSliceConfig.slice.reducerPath]: undoable( + nodesSliceConfig.slice.reducer, + nodesSliceConfig.undoableConfig?.reduxUndoOptions + ), + [paramsSliceConfig.slice.reducerPath]: paramsSliceConfig.slice.reducer, + [queueSliceConfig.slice.reducerPath]: queueSliceConfig.slice.reducer, + [refImagesSliceConfig.slice.reducerPath]: refImagesSliceConfig.slice.reducer, + [stylePresetSliceConfig.slice.reducerPath]: stylePresetSliceConfig.slice.reducer, + [systemSliceConfig.slice.reducerPath]: systemSliceConfig.slice.reducer, + [uiSliceConfig.slice.reducerPath]: uiSliceConfig.slice.reducer, + [upscaleSliceConfig.slice.reducerPath]: upscaleSliceConfig.slice.reducer, + [workflowLibrarySliceConfig.slice.reducerPath]: workflowLibrarySliceConfig.slice.reducer, + [workflowSettingsSliceConfig.slice.reducerPath]: workflowSettingsSliceConfig.slice.reducer, }; const rootReducer = combineReducers(ALL_REDUCERS); @@ -112,6 +122,10 @@ const rememberedRootReducer = rememberReducer(rootReducer); export const $isPendingPersist = atom(false); +$isPendingPersist.listen((isPendingPersist) => { + console.log({ isPendingPersist }); +}); + const unserialize: UnserializeFunction = (data, key) => { const sliceConfig = SLICE_CONFIGS[key as keyof typeof SLICE_CONFIGS]; if (!sliceConfig?.persistConfig) { @@ -164,10 +178,11 @@ const serialize: SerializeFunction = (data, key) => { if (!sliceConfig?.persistConfig) { throw new Error(`No persist config for slice "${key}"`); } - // Heuristic to determine if the slice is undoable - could just hardcode it in the persistConfig - const isUndoable = 'present' in data && 'past' in data && 'future' in data && '_latestUnfiltered' in data; - const result = omit(isUndoable ? data.present : data, sliceConfig.persistConfig.persistDenylist ?? []); + const result = omit( + sliceConfig.undoableConfig ? data.present : data, + sliceConfig.persistConfig.persistDenylist ?? [] + ); return JSON.stringify(result); }; @@ -187,7 +202,7 @@ export const createStore = (uniqueStoreKey?: string, persist = true) => .concat(api.middleware) .concat(dynamicMiddlewares) .concat(authToastMiddleware) - .concat(getDebugLoggerMiddleware()) + // .concat(getDebugLoggerMiddleware()) .prepend(listenerMiddleware.middleware), enhancers: (getDefaultEnhancers) => { const enhancers = getDefaultEnhancers(); @@ -266,40 +281,3 @@ addAppConfigReceivedListener(startAppListening); addAdHocPostProcessingRequestedListener(startAppListening); addSetDefaultSettingsListener(startAppListening); - -const addPersistenceListener = (startAppListening: AppStartListening) => { - startAppListening({ - predicate: (action, currentRootState, originalRootState) => { - for (const { slice, persistConfig } of Object.values(PERSISTED_SLICE_CONFIGS)) { - if (!persistConfig) { - // shouldn't get here, we filtered out slices without persistConfig - return false; - } - const persistDenylist: string[] = persistConfig.persistDenylist ?? []; - const originalState = originalRootState[slice.name]; - const currentState = currentRootState[slice.name]; - for (const [k, v] of Object.entries(currentState)) { - if (persistDenylist.includes(k)) { - continue; - } - - if (v !== originalState[k as keyof typeof originalState]) { - return true; - } - } - } - return false; - }, - effect: () => { - $isPendingPersist.set(true); - }, - }); - - startAppListening({ - matcher: createAction(REMEMBER_PERSISTED).match, - effect: () => { - $isPendingPersist.set(false); - }, - }); -}; -addPersistenceListener(startAppListening); diff --git a/invokeai/frontend/web/src/app/store/types.ts b/invokeai/frontend/web/src/app/store/types.ts index f5cc7211d4..8ba22916b1 100644 --- a/invokeai/frontend/web/src/app/store/types.ts +++ b/invokeai/frontend/web/src/app/store/types.ts @@ -1,12 +1,14 @@ -import type { Slice, UnknownAction } from '@reduxjs/toolkit'; +import type { Slice } from '@reduxjs/toolkit'; import type { UndoableOptions } from 'redux-undo'; -export type SliceConfig = { - slice: Slice; +type StateFromSlice = T extends Slice ? U : never; + +export type SliceConfig = { + slice: T; /** * A function that returns the initial state of the slice. */ - getInitialState: () => T; + getInitialState: () => StateFromSlice; /** * The optional persist configuration for this slice. If omitted, the slice will not be persisted. */ @@ -16,11 +18,11 @@ export type SliceConfig = { * @param state The rehydrated state. * @returns A correctly-shaped state. */ - migrate: (state: unknown) => T; + migrate: (state: unknown) => StateFromSlice; /** * Keys to omit from the persisted state. */ - persistDenylist?: (keyof T)[]; + persistDenylist?: (keyof StateFromSlice)[]; }; /** * The optional undoable configuration for this slice. If omitted, the slice will not be undoable. @@ -29,6 +31,6 @@ export type SliceConfig = { /** * The options to be passed into redux-undo. */ - reduxUndoOptions: UndoableOptions; + reduxUndoOptions: UndoableOptions>; }; }; diff --git a/invokeai/frontend/web/src/features/changeBoardModal/store/slice.ts b/invokeai/frontend/web/src/features/changeBoardModal/store/slice.ts index f7d6bffc2b..c52cc546e8 100644 --- a/invokeai/frontend/web/src/features/changeBoardModal/store/slice.ts +++ b/invokeai/frontend/web/src/features/changeBoardModal/store/slice.ts @@ -5,7 +5,6 @@ import type { SliceConfig } from 'app/store/types'; import { deepClone } from 'common/util/deepClone'; import { initialState } from './initialState'; -import type { ChangeBoardModalState } from './types'; const getInitialState = () => deepClone(initialState); @@ -30,7 +29,7 @@ export const { isModalOpenChanged, imagesToChangeSelected, changeBoardReset } = export const selectChangeBoardModalSlice = (state: RootState) => state.changeBoardModal; -export const changeBoardModalSliceConfig: SliceConfig = { +export const changeBoardModalSliceConfig: SliceConfig = { slice, getInitialState, }; diff --git a/invokeai/frontend/web/src/features/controlLayers/store/canvasSettingsSlice.ts b/invokeai/frontend/web/src/features/controlLayers/store/canvasSettingsSlice.ts index 130ff0d4bb..8af5852513 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/canvasSettingsSlice.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/canvasSettingsSlice.ts @@ -192,7 +192,7 @@ const migrate = (state: any): any => { return state; }; -export const canvasSettingsSliceConfig: SliceConfig = { +export const canvasSettingsSliceConfig: SliceConfig = { slice, getInitialState, persistConfig: { diff --git a/invokeai/frontend/web/src/features/controlLayers/store/canvasSlice.ts b/invokeai/frontend/web/src/features/controlLayers/store/canvasSlice.ts index 5877b813b8..131142d0ed 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/canvasSlice.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/canvasSlice.ts @@ -1721,7 +1721,7 @@ export const canvasUndoableConfig: UndoableOptions = // debug: import.meta.env.MODE === 'development', }; -export const canvasSliceConfig: SliceConfig = { +export const canvasSliceConfig: SliceConfig = { slice, getInitialState: getInitialCanvasState, persistConfig: { diff --git a/invokeai/frontend/web/src/features/controlLayers/store/canvasStagingAreaSlice.ts b/invokeai/frontend/web/src/features/controlLayers/store/canvasStagingAreaSlice.ts index c2e7593606..e1356d2fef 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/canvasStagingAreaSlice.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/canvasStagingAreaSlice.ts @@ -61,7 +61,7 @@ const migrate = (state: any): any => { return state; }; -export const canvasSessionSliceConfig: SliceConfig = { +export const canvasSessionSliceConfig: SliceConfig = { slice, getInitialState, persistConfig: { migrate }, diff --git a/invokeai/frontend/web/src/features/controlLayers/store/lorasSlice.ts b/invokeai/frontend/web/src/features/controlLayers/store/lorasSlice.ts index b2baa9c72b..5c85199c77 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/lorasSlice.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/lorasSlice.ts @@ -79,7 +79,7 @@ const migrate = (state: any): any => { return state; }; -export const lorasSliceConfig: SliceConfig = { +export const lorasSliceConfig: SliceConfig = { slice, getInitialState, persistConfig: { diff --git a/invokeai/frontend/web/src/features/controlLayers/store/paramsSlice.ts b/invokeai/frontend/web/src/features/controlLayers/store/paramsSlice.ts index a267ec057d..4d60a28387 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/paramsSlice.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/paramsSlice.ts @@ -405,7 +405,7 @@ const migrate = (state: any): any => { return state; }; -export const paramsSliceConfig: SliceConfig = { +export const paramsSliceConfig: SliceConfig = { slice, getInitialState: getInitialParamsState, persistConfig: { migrate }, diff --git a/invokeai/frontend/web/src/features/controlLayers/store/refImagesSlice.ts b/invokeai/frontend/web/src/features/controlLayers/store/refImagesSlice.ts index 3ebb0059c4..e772392daf 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/refImagesSlice.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/refImagesSlice.ts @@ -271,14 +271,14 @@ const migrate = (state: any): any => { return state; }; -export const refImagesSliceConfig: SliceConfig = { +export const refImagesSliceConfig: SliceConfig = { slice, getInitialState: getInitialRefImagesState, persistConfig: { migrate, persistDenylist: ['selectedEntityId', 'isPanelOpen'], }, -} as const; +}; export const selectRefImagesSlice = (state: RootState) => state.refImages; diff --git a/invokeai/frontend/web/src/features/dynamicPrompts/store/dynamicPromptsSlice.ts b/invokeai/frontend/web/src/features/dynamicPrompts/store/dynamicPromptsSlice.ts index 8999143ec6..6788feaf6b 100644 --- a/invokeai/frontend/web/src/features/dynamicPrompts/store/dynamicPromptsSlice.ts +++ b/invokeai/frontend/web/src/features/dynamicPrompts/store/dynamicPromptsSlice.ts @@ -74,7 +74,7 @@ const migrate = (state: any): any => { return state; }; -export const dynamicPromptsSliceConfig: SliceConfig = { +export const dynamicPromptsSliceConfig: SliceConfig = { slice, getInitialState, persistConfig: { diff --git a/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts b/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts index 9a8e4ee6df..c788280bb2 100644 --- a/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts +++ b/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts @@ -200,7 +200,7 @@ const migrate = (state: any): any => { return state; }; -export const gallerySliceConfig: SliceConfig = { +export const gallerySliceConfig: SliceConfig = { slice, getInitialState, persistConfig: { diff --git a/invokeai/frontend/web/src/features/modelManagerV2/store/modelManagerV2Slice.ts b/invokeai/frontend/web/src/features/modelManagerV2/store/modelManagerV2Slice.ts index 0d2e5239c7..15d1ea5bf8 100644 --- a/invokeai/frontend/web/src/features/modelManagerV2/store/modelManagerV2Slice.ts +++ b/invokeai/frontend/web/src/features/modelManagerV2/store/modelManagerV2Slice.ts @@ -69,7 +69,7 @@ const migrate = (state: any): any => { return state; }; -export const modelManagerSliceConfig: SliceConfig = { +export const modelManagerSliceConfig: SliceConfig = { slice, getInitialState, persistConfig: { diff --git a/invokeai/frontend/web/src/features/nodes/store/nodesSlice.ts b/invokeai/frontend/web/src/features/nodes/store/nodesSlice.ts index f273437251..4d06d1c205 100644 --- a/invokeai/frontend/web/src/features/nodes/store/nodesSlice.ts +++ b/invokeai/frontend/web/src/features/nodes/store/nodesSlice.ts @@ -936,7 +936,7 @@ const reduxUndoOptions: UndoableOptions = { }, }; -export const nodesSliceConfig: SliceConfig = { +export const nodesSliceConfig: SliceConfig = { slice, getInitialState, persistConfig: { diff --git a/invokeai/frontend/web/src/features/nodes/store/workflowLibrarySlice.ts b/invokeai/frontend/web/src/features/nodes/store/workflowLibrarySlice.ts index 2020de7448..c17e5f14d3 100644 --- a/invokeai/frontend/web/src/features/nodes/store/workflowLibrarySlice.ts +++ b/invokeai/frontend/web/src/features/nodes/store/workflowLibrarySlice.ts @@ -79,7 +79,7 @@ export const { /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ const migrate = (state: any): any => state; -export const workflowLibrarySliceConfig: SliceConfig = { +export const workflowLibrarySliceConfig: SliceConfig = { slice, getInitialState, persistConfig: { diff --git a/invokeai/frontend/web/src/features/nodes/store/workflowSettingsSlice.ts b/invokeai/frontend/web/src/features/nodes/store/workflowSettingsSlice.ts index f5cafd39f0..8d9cd4d837 100644 --- a/invokeai/frontend/web/src/features/nodes/store/workflowSettingsSlice.ts +++ b/invokeai/frontend/web/src/features/nodes/store/workflowSettingsSlice.ts @@ -117,7 +117,7 @@ const migrate = (state: any): any => { return state; }; -export const workflowSettingsSliceConfig: SliceConfig = { +export const workflowSettingsSliceConfig: SliceConfig = { slice, getInitialState, persistConfig: { diff --git a/invokeai/frontend/web/src/features/parameters/store/upscaleSlice.ts b/invokeai/frontend/web/src/features/parameters/store/upscaleSlice.ts index 33d5ddc328..6dd363becb 100644 --- a/invokeai/frontend/web/src/features/parameters/store/upscaleSlice.ts +++ b/invokeai/frontend/web/src/features/parameters/store/upscaleSlice.ts @@ -85,7 +85,7 @@ const migrate = (state: any): any => { return state; }; -export const upscaleSliceConfig: SliceConfig = { +export const upscaleSliceConfig: SliceConfig = { slice, getInitialState, persistConfig: { diff --git a/invokeai/frontend/web/src/features/queue/store/queueSlice.ts b/invokeai/frontend/web/src/features/queue/store/queueSlice.ts index 29812b32cc..a80ee7da1b 100644 --- a/invokeai/frontend/web/src/features/queue/store/queueSlice.ts +++ b/invokeai/frontend/web/src/features/queue/store/queueSlice.ts @@ -36,7 +36,7 @@ const slice = createSlice({ export const { listCursorChanged, listPriorityChanged, listParamsReset } = slice.actions; -export const queueSliceConfig: SliceConfig = { +export const queueSliceConfig: SliceConfig = { slice, getInitialState, }; diff --git a/invokeai/frontend/web/src/features/stylePresets/store/stylePresetSlice.ts b/invokeai/frontend/web/src/features/stylePresets/store/stylePresetSlice.ts index 2753dee2f5..4451abd0e4 100644 --- a/invokeai/frontend/web/src/features/stylePresets/store/stylePresetSlice.ts +++ b/invokeai/frontend/web/src/features/stylePresets/store/stylePresetSlice.ts @@ -68,7 +68,7 @@ const migrate = (state: any): any => { return state; }; -export const stylePresetSliceConfig: SliceConfig = { +export const stylePresetSliceConfig: SliceConfig = { slice, getInitialState, persistConfig: { diff --git a/invokeai/frontend/web/src/features/system/store/configSlice.ts b/invokeai/frontend/web/src/features/system/store/configSlice.ts index d8c365d56e..0685e0bd24 100644 --- a/invokeai/frontend/web/src/features/system/store/configSlice.ts +++ b/invokeai/frontend/web/src/features/system/store/configSlice.ts @@ -201,7 +201,7 @@ const slice = createSlice({ export const { configChanged } = slice.actions; -export const configSliceConfig: SliceConfig = { +export const configSliceConfig: SliceConfig = { slice, getInitialState, }; diff --git a/invokeai/frontend/web/src/features/system/store/systemSlice.ts b/invokeai/frontend/web/src/features/system/store/systemSlice.ts index 5839d5f2f2..36c8d1b53f 100644 --- a/invokeai/frontend/web/src/features/system/store/systemSlice.ts +++ b/invokeai/frontend/web/src/features/system/store/systemSlice.ts @@ -104,7 +104,7 @@ const migrate = (state: any): any => { return state; }; -export const systemSliceConfig: SliceConfig = { +export const systemSliceConfig: SliceConfig = { slice, getInitialState, persistConfig: { diff --git a/invokeai/frontend/web/src/features/ui/store/uiSlice.ts b/invokeai/frontend/web/src/features/ui/store/uiSlice.ts index 7a932f4901..6efdccd445 100644 --- a/invokeai/frontend/web/src/features/ui/store/uiSlice.ts +++ b/invokeai/frontend/web/src/features/ui/store/uiSlice.ts @@ -104,7 +104,7 @@ const migrate = (state: any): any => { return state; }; -export const uiSliceConfig: SliceConfig = { +export const uiSliceConfig: SliceConfig = { slice, getInitialState, persistConfig: {