1
1
import type { ThunkDispatch , TypedStartListening , UnknownAction } from '@reduxjs/toolkit' ;
2
- import { addListener , combineReducers , configureStore , createAction , createListenerMiddleware } from '@reduxjs/toolkit' ;
2
+ import { addListener , combineReducers , configureStore , createListenerMiddleware } from '@reduxjs/toolkit' ;
3
3
import { logger } from 'app/logging/logger' ;
4
4
import { serverBackedDriver } from 'app/store/enhancers/reduxRemember/driver' ;
5
5
import { errorHandler } from 'app/store/enhancers/reduxRemember/errors' ;
@@ -43,14 +43,13 @@ import { diff } from 'jsondiffpatch';
43
43
import { atom } from 'nanostores' ;
44
44
import dynamicMiddlewares from 'redux-dynamic-middlewares' ;
45
45
import type { SerializeFunction , UnserializeFunction } from 'redux-remember' ;
46
- import { REMEMBER_PERSISTED , rememberEnhancer , rememberReducer } from 'redux-remember' ;
47
- import { newHistory } from 'redux-undo' ;
46
+ import { rememberEnhancer , rememberReducer } from 'redux-remember' ;
47
+ import undoable , { newHistory } from 'redux-undo' ;
48
48
import { serializeError } from 'serialize-error' ;
49
49
import { api } from 'services/api' ;
50
50
import { authToastMiddleware } from 'services/api/authToastMiddleware' ;
51
51
import type { JsonObject } from 'type-fest' ;
52
52
53
- import { getDebugLoggerMiddleware } from './middleware/debugLoggerMiddleware' ;
54
53
import { actionSanitizer } from './middleware/devtools/actionSanitizer' ;
55
54
import { actionsDenylist } from './middleware/devtools/actionsDenylist' ;
56
55
import { stateSanitizer } from './middleware/devtools/stateSanitizer' ;
@@ -61,49 +60,60 @@ export const listenerMiddleware = createListenerMiddleware();
61
60
62
61
const log = logger ( 'system' ) ;
63
62
63
+ // When adding a slice, add the config to the SLICE_CONFIGS object below, then add the reducer to ALL_REDUCERS.
64
+ // Remember to wrap undoable slices in `undoable()`.
65
+
64
66
const SLICE_CONFIGS = {
65
- [ canvasSessionSliceConfig . slice . name ] : canvasSessionSliceConfig ,
66
- [ canvasSettingsSliceConfig . slice . name ] : canvasSettingsSliceConfig ,
67
- [ canvasSliceConfig . slice . name ] : canvasSliceConfig ,
68
- [ changeBoardModalSliceConfig . slice . name ] : changeBoardModalSliceConfig ,
69
- [ configSliceConfig . slice . name ] : configSliceConfig ,
70
- [ dynamicPromptsSliceConfig . slice . name ] : dynamicPromptsSliceConfig ,
71
- [ gallerySliceConfig . slice . name ] : gallerySliceConfig ,
72
- [ lorasSliceConfig . slice . name ] : lorasSliceConfig ,
73
- [ modelManagerSliceConfig . slice . name ] : modelManagerSliceConfig ,
74
- [ nodesSliceConfig . slice . name ] : nodesSliceConfig ,
75
- [ paramsSliceConfig . slice . name ] : paramsSliceConfig ,
76
- [ queueSliceConfig . slice . name ] : queueSliceConfig ,
77
- [ refImagesSliceConfig . slice . name ] : refImagesSliceConfig ,
78
- [ stylePresetSliceConfig . slice . name ] : stylePresetSliceConfig ,
79
- [ systemSliceConfig . slice . name ] : systemSliceConfig ,
80
- [ uiSliceConfig . slice . name ] : uiSliceConfig ,
81
- [ upscaleSliceConfig . slice . name ] : upscaleSliceConfig ,
82
- [ workflowLibrarySliceConfig . slice . name ] : workflowLibrarySliceConfig ,
83
- [ workflowSettingsSliceConfig . slice . name ] : workflowSettingsSliceConfig ,
67
+ [ canvasSessionSliceConfig . slice . reducerPath ] : canvasSessionSliceConfig ,
68
+ [ canvasSettingsSliceConfig . slice . reducerPath ] : canvasSettingsSliceConfig ,
69
+ [ canvasSliceConfig . slice . reducerPath ] : canvasSliceConfig ,
70
+ [ changeBoardModalSliceConfig . slice . reducerPath ] : changeBoardModalSliceConfig ,
71
+ [ configSliceConfig . slice . reducerPath ] : configSliceConfig ,
72
+ [ dynamicPromptsSliceConfig . slice . reducerPath ] : dynamicPromptsSliceConfig ,
73
+ [ gallerySliceConfig . slice . reducerPath ] : gallerySliceConfig ,
74
+ [ lorasSliceConfig . slice . reducerPath ] : lorasSliceConfig ,
75
+ [ modelManagerSliceConfig . slice . reducerPath ] : modelManagerSliceConfig ,
76
+ [ nodesSliceConfig . slice . reducerPath ] : nodesSliceConfig ,
77
+ [ paramsSliceConfig . slice . reducerPath ] : paramsSliceConfig ,
78
+ [ queueSliceConfig . slice . reducerPath ] : queueSliceConfig ,
79
+ [ refImagesSliceConfig . slice . reducerPath ] : refImagesSliceConfig ,
80
+ [ stylePresetSliceConfig . slice . reducerPath ] : stylePresetSliceConfig ,
81
+ [ systemSliceConfig . slice . reducerPath ] : systemSliceConfig ,
82
+ [ uiSliceConfig . slice . reducerPath ] : uiSliceConfig ,
83
+ [ upscaleSliceConfig . slice . reducerPath ] : upscaleSliceConfig ,
84
+ [ workflowLibrarySliceConfig . slice . reducerPath ] : workflowLibrarySliceConfig ,
85
+ [ workflowSettingsSliceConfig . slice . reducerPath ] : workflowSettingsSliceConfig ,
84
86
} ;
85
87
86
88
const ALL_REDUCERS = {
87
89
[ api . reducerPath ] : api . reducer ,
88
- [ canvasSessionSliceConfig . slice . name ] : canvasSessionSliceConfig . slice . reducer ,
89
- [ canvasSettingsSliceConfig . slice . name ] : canvasSettingsSliceConfig . slice . reducer ,
90
- [ canvasSliceConfig . slice . name ] : canvasSliceConfig . slice . reducer ,
91
- [ changeBoardModalSliceConfig . slice . name ] : changeBoardModalSliceConfig . slice . reducer ,
92
- [ configSliceConfig . slice . name ] : configSliceConfig . slice . reducer ,
93
- [ dynamicPromptsSliceConfig . slice . name ] : dynamicPromptsSliceConfig . slice . reducer ,
94
- [ gallerySliceConfig . slice . name ] : gallerySliceConfig . slice . reducer ,
95
- [ lorasSliceConfig . slice . name ] : lorasSliceConfig . slice . reducer ,
96
- [ modelManagerSliceConfig . slice . name ] : modelManagerSliceConfig . slice . reducer ,
97
- [ nodesSliceConfig . slice . name ] : nodesSliceConfig . slice . reducer ,
98
- [ paramsSliceConfig . slice . name ] : paramsSliceConfig . slice . reducer ,
99
- [ queueSliceConfig . slice . name ] : queueSliceConfig . slice . reducer ,
100
- [ refImagesSliceConfig . slice . name ] : refImagesSliceConfig . slice . reducer ,
101
- [ stylePresetSliceConfig . slice . name ] : stylePresetSliceConfig . slice . reducer ,
102
- [ systemSliceConfig . slice . name ] : systemSliceConfig . slice . reducer ,
103
- [ uiSliceConfig . slice . name ] : uiSliceConfig . slice . reducer ,
104
- [ upscaleSliceConfig . slice . name ] : upscaleSliceConfig . slice . reducer ,
105
- [ workflowLibrarySliceConfig . slice . name ] : workflowLibrarySliceConfig . slice . reducer ,
106
- [ workflowSettingsSliceConfig . slice . name ] : workflowSettingsSliceConfig . slice . reducer ,
90
+ [ canvasSessionSliceConfig . slice . reducerPath ] : canvasSessionSliceConfig . slice . reducer ,
91
+ [ canvasSettingsSliceConfig . slice . reducerPath ] : canvasSettingsSliceConfig . slice . reducer ,
92
+ // Undoable!
93
+ [ canvasSliceConfig . slice . reducerPath ] : undoable (
94
+ canvasSliceConfig . slice . reducer ,
95
+ canvasSliceConfig . undoableConfig ?. reduxUndoOptions
96
+ ) ,
97
+ [ changeBoardModalSliceConfig . slice . reducerPath ] : changeBoardModalSliceConfig . slice . reducer ,
98
+ [ configSliceConfig . slice . reducerPath ] : configSliceConfig . slice . reducer ,
99
+ [ dynamicPromptsSliceConfig . slice . reducerPath ] : dynamicPromptsSliceConfig . slice . reducer ,
100
+ [ gallerySliceConfig . slice . reducerPath ] : gallerySliceConfig . slice . reducer ,
101
+ [ lorasSliceConfig . slice . reducerPath ] : lorasSliceConfig . slice . reducer ,
102
+ [ modelManagerSliceConfig . slice . reducerPath ] : modelManagerSliceConfig . slice . reducer ,
103
+ // Undoable!
104
+ [ nodesSliceConfig . slice . reducerPath ] : undoable (
105
+ nodesSliceConfig . slice . reducer ,
106
+ nodesSliceConfig . undoableConfig ?. reduxUndoOptions
107
+ ) ,
108
+ [ paramsSliceConfig . slice . reducerPath ] : paramsSliceConfig . slice . reducer ,
109
+ [ queueSliceConfig . slice . reducerPath ] : queueSliceConfig . slice . reducer ,
110
+ [ refImagesSliceConfig . slice . reducerPath ] : refImagesSliceConfig . slice . reducer ,
111
+ [ stylePresetSliceConfig . slice . reducerPath ] : stylePresetSliceConfig . slice . reducer ,
112
+ [ systemSliceConfig . slice . reducerPath ] : systemSliceConfig . slice . reducer ,
113
+ [ uiSliceConfig . slice . reducerPath ] : uiSliceConfig . slice . reducer ,
114
+ [ upscaleSliceConfig . slice . reducerPath ] : upscaleSliceConfig . slice . reducer ,
115
+ [ workflowLibrarySliceConfig . slice . reducerPath ] : workflowLibrarySliceConfig . slice . reducer ,
116
+ [ workflowSettingsSliceConfig . slice . reducerPath ] : workflowSettingsSliceConfig . slice . reducer ,
107
117
} ;
108
118
109
119
const rootReducer = combineReducers ( ALL_REDUCERS ) ;
@@ -112,6 +122,10 @@ const rememberedRootReducer = rememberReducer(rootReducer);
112
122
113
123
export const $isPendingPersist = atom ( false ) ;
114
124
125
+ $isPendingPersist . listen ( ( isPendingPersist ) => {
126
+ console . log ( { isPendingPersist } ) ;
127
+ } ) ;
128
+
115
129
const unserialize : UnserializeFunction = ( data , key ) => {
116
130
const sliceConfig = SLICE_CONFIGS [ key as keyof typeof SLICE_CONFIGS ] ;
117
131
if ( ! sliceConfig ?. persistConfig ) {
@@ -164,10 +178,11 @@ const serialize: SerializeFunction = (data, key) => {
164
178
if ( ! sliceConfig ?. persistConfig ) {
165
179
throw new Error ( `No persist config for slice "${ key } "` ) ;
166
180
}
167
- // Heuristic to determine if the slice is undoable - could just hardcode it in the persistConfig
168
- const isUndoable = 'present' in data && 'past' in data && 'future' in data && '_latestUnfiltered' in data ;
169
181
170
- const result = omit ( isUndoable ? data . present : data , sliceConfig . persistConfig . persistDenylist ?? [ ] ) ;
182
+ const result = omit (
183
+ sliceConfig . undoableConfig ? data . present : data ,
184
+ sliceConfig . persistConfig . persistDenylist ?? [ ]
185
+ ) ;
171
186
return JSON . stringify ( result ) ;
172
187
} ;
173
188
@@ -187,7 +202,7 @@ export const createStore = (uniqueStoreKey?: string, persist = true) =>
187
202
. concat ( api . middleware )
188
203
. concat ( dynamicMiddlewares )
189
204
. concat ( authToastMiddleware )
190
- . concat ( getDebugLoggerMiddleware ( ) )
205
+ // .concat(getDebugLoggerMiddleware())
191
206
. prepend ( listenerMiddleware . middleware ) ,
192
207
enhancers : ( getDefaultEnhancers ) => {
193
208
const enhancers = getDefaultEnhancers ( ) ;
@@ -266,40 +281,3 @@ addAppConfigReceivedListener(startAppListening);
266
281
addAdHocPostProcessingRequestedListener ( startAppListening ) ;
267
282
268
283
addSetDefaultSettingsListener ( startAppListening ) ;
269
-
270
- const addPersistenceListener = ( startAppListening : AppStartListening ) => {
271
- startAppListening ( {
272
- predicate : ( action , currentRootState , originalRootState ) => {
273
- for ( const { slice, persistConfig } of Object . values ( PERSISTED_SLICE_CONFIGS ) ) {
274
- if ( ! persistConfig ) {
275
- // shouldn't get here, we filtered out slices without persistConfig
276
- return false ;
277
- }
278
- const persistDenylist : string [ ] = persistConfig . persistDenylist ?? [ ] ;
279
- const originalState = originalRootState [ slice . name ] ;
280
- const currentState = currentRootState [ slice . name ] ;
281
- for ( const [ k , v ] of Object . entries ( currentState ) ) {
282
- if ( persistDenylist . includes ( k ) ) {
283
- continue ;
284
- }
285
-
286
- if ( v !== originalState [ k as keyof typeof originalState ] ) {
287
- return true ;
288
- }
289
- }
290
- }
291
- return false ;
292
- } ,
293
- effect : ( ) => {
294
- $isPendingPersist . set ( true ) ;
295
- } ,
296
- } ) ;
297
-
298
- startAppListening ( {
299
- matcher : createAction ( REMEMBER_PERSISTED ) . match ,
300
- effect : ( ) => {
301
- $isPendingPersist . set ( false ) ;
302
- } ,
303
- } ) ;
304
- } ;
305
- addPersistenceListener ( startAppListening ) ;
0 commit comments