From e6fe2540b81cf5be4d403d6adc53d0c75b3922d1 Mon Sep 17 00:00:00 2001 From: Mary Hipp Date: Thu, 30 Nov 2023 11:47:27 -0500 Subject: [PATCH] dynamically create indexedDB store using unique store key if available --- .../web/src/app/components/InvokeAIUI.tsx | 12 ++- invokeai/frontend/web/src/app/store/store.ts | 100 +++++++++--------- 2 files changed, 61 insertions(+), 51 deletions(-) diff --git a/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx b/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx index 64d0d8d3ab..b190a36f06 100644 --- a/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx +++ b/invokeai/frontend/web/src/app/components/InvokeAIUI.tsx @@ -7,7 +7,8 @@ import { $headerComponent } from 'app/store/nanostores/headerComponent'; import { $isDebugging } from 'app/store/nanostores/isDebugging'; import { $projectId } from 'app/store/nanostores/projectId'; import { $queueId, DEFAULT_QUEUE_ID } from 'app/store/nanostores/queueId'; -import { store } from 'app/store/store'; +import { $store } from 'app/store/nanostores/store'; +import { createStore } from 'app/store/store'; import { PartialAppConfig } from 'app/types/invokeai'; import Loading from 'common/components/Loading/Loading'; import AppDndContext from 'features/dnd/components/AppDndContext'; @@ -18,6 +19,7 @@ import React, { lazy, memo, useEffect, + useMemo, } from 'react'; import { Provider } from 'react-redux'; import { addMiddleware, resetMiddlewares } from 'redux-dynamic-middlewares'; @@ -137,6 +139,14 @@ const InvokeAIUI = ({ }; }, [isDebugging]); + const store = useMemo(() => { + return createStore(projectId); + }, [projectId]); + + useEffect(() => { + $store.set(store); + }, [store]); + return ( diff --git a/invokeai/frontend/web/src/app/store/store.ts b/invokeai/frontend/web/src/app/store/store.ts index a0230c2807..87edba56e0 100644 --- a/invokeai/frontend/web/src/app/store/store.ts +++ b/invokeai/frontend/web/src/app/store/store.ts @@ -32,7 +32,6 @@ import { actionSanitizer } from './middleware/devtools/actionSanitizer'; import { actionsDenylist } from './middleware/devtools/actionsDenylist'; import { stateSanitizer } from './middleware/devtools/stateSanitizer'; import { listenerMiddleware } from './middleware/listenerMiddleware'; -import { $store } from './nanostores/store'; import { createStore as createIDBKeyValStore, get, set } from 'idb-keyval'; const allReducers = { @@ -84,57 +83,58 @@ const idbKeyValDriver: Driver = { setItem: (key, value) => set(key, value, idbKeyValStore), }; -export const store = configureStore({ - reducer: rememberedRootReducer, - enhancers: (existingEnhancers) => { - return existingEnhancers - .concat( - rememberEnhancer(idbKeyValDriver, rememberedKeys, { - persistDebounce: 300, - serialize, - unserialize, - prefix: STORAGE_PREFIX, - }) - ) - .concat(autoBatchEnhancer()); - }, - middleware: (getDefaultMiddleware) => - getDefaultMiddleware({ - serializableCheck: false, - immutableCheck: false, - }) - .concat(api.middleware) - .concat(dynamicMiddlewares) - .prepend(listenerMiddleware.middleware), - devTools: { - actionSanitizer, - stateSanitizer, - trace: true, - predicate: (state, action) => { - // TODO: hook up to the log level param in system slice - // manually type state, cannot type the arg - // const typedState = state as ReturnType; - - // TODO: doing this breaks the rtk query devtools, commenting out for now - // if (action.type.startsWith('api/')) { - // // don't log api actions, with manual cache updates they are extremely noisy - // return false; - // } - - if (actionsDenylist.includes(action.type)) { - // don't log other noisy actions - return false; - } - - return true; +export const createStore = (uniqueStoreKey?: string) => + configureStore({ + reducer: rememberedRootReducer, + enhancers: (existingEnhancers) => { + return existingEnhancers + .concat( + rememberEnhancer(idbKeyValDriver, rememberedKeys, { + persistDebounce: 300, + serialize, + unserialize, + prefix: uniqueStoreKey + ? `${STORAGE_PREFIX}-${uniqueStoreKey}-` + : STORAGE_PREFIX, + }) + ) + .concat(autoBatchEnhancer()); }, - }, -}); + middleware: (getDefaultMiddleware) => + getDefaultMiddleware({ + serializableCheck: false, + immutableCheck: false, + }) + .concat(api.middleware) + .concat(dynamicMiddlewares) + .prepend(listenerMiddleware.middleware), + devTools: { + actionSanitizer, + stateSanitizer, + trace: true, + predicate: (state, action) => { + // TODO: hook up to the log level param in system slice + // manually type state, cannot type the arg + // const typedState = state as ReturnType; -export type AppGetState = typeof store.getState; -export type RootState = ReturnType; + // TODO: doing this breaks the rtk query devtools, commenting out for now + // if (action.type.startsWith('api/')) { + // // don't log api actions, with manual cache updates they are extremely noisy + // return false; + // } + + if (actionsDenylist.includes(action.type)) { + // don't log other noisy actions + return false; + } + + return true; + }, + }, + }); + +export type RootState = ReturnType; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type AppThunkDispatch = ThunkDispatch; -export type AppDispatch = typeof store.dispatch; +export type AppDispatch = ReturnType['dispatch']; export const stateSelector = (state: RootState) => state; -$store.set(store);