Skip to content

Commit 10f2427

Browse files
author
Attila Cseh
committed
deserialization fixed
1 parent 28ac192 commit 10f2427

File tree

6 files changed

+33
-26
lines changed

6 files changed

+33
-26
lines changed

invokeai/frontend/web/src/app/store/store.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,13 @@ const unserialize: UnserializeFunction = (data, key) => {
106106
throw new Error(`No persist config for slice "${key}"`);
107107
}
108108
const { getInitialState, persistConfig } = sliceConfig;
109-
let state;
109+
110110
try {
111111
const parsedState = JSON.parse(data);
112+
const stateToMigrate = persistConfig.deserialize ? persistConfig.deserialize(parsedState) : parsedState;
112113

113114
// Run migrations to bring old state up to date with the current version.
114-
const migrated = persistConfig.migrate(parsedState);
115+
const migrated = persistConfig.migrate(stateToMigrate);
115116

116117
log.debug(
117118
{
@@ -121,16 +122,17 @@ const unserialize: UnserializeFunction = (data, key) => {
121122
},
122123
`Rehydrated slice "${key}"`
123124
);
124-
state = migrated;
125+
126+
return migrated;
125127
} catch (err) {
126128
log.warn(
127129
{ error: serializeError(err as Error) },
128130
`Error rehydrating slice "${key}", falling back to default initial state`
129131
);
130-
state = getInitialState();
131-
}
132+
const initialState = getInitialState();
132133

133-
return persistConfig.deserialize ? persistConfig.deserialize(state) : state;
134+
return persistConfig.deserialize ? persistConfig.deserialize(initialState) : initialState;
135+
}
134136
};
135137

136138
const serialize: SerializeFunction = (data, key) => {

invokeai/frontend/web/src/app/store/types.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Slice } from '@reduxjs/toolkit';
22
import type { ZodType } from 'zod';
3+
import { z } from 'zod';
34

45
type StateFromSlice<T extends Slice> = T extends Slice<infer U> ? U : never;
56
export type SerializedStateFromDenyList<S, T extends readonly (keyof S)[]> = Omit<S, T[number]>;
@@ -28,7 +29,7 @@ export type SliceConfig<T extends Slice, TInternalState = StateFromSlice<T>, TSe
2829
* @param state The rehydrated state.
2930
* @returns A correctly-shaped state.
3031
*/
31-
migrate: (state: unknown) => TSerializedState;
32+
migrate: (state: unknown) => TInternalState;
3233
/**
3334
* Serializes the state
3435
*
@@ -45,3 +46,14 @@ export type SliceConfig<T extends Slice, TInternalState = StateFromSlice<T>, TSe
4546
deserialize?: (state: unknown) => TInternalState;
4647
};
4748
};
49+
50+
export const zStateWithHistory = <T extends z.ZodTypeAny>(stateSchema: T) =>
51+
z.object({
52+
past: z.array(stateSchema),
53+
present: stateSchema,
54+
future: z.array(stateSchema),
55+
_latestUnfiltered: stateSchema.optional(),
56+
group: z.unknown().optional(),
57+
index: z.number().optional(),
58+
limit: z.number().optional(),
59+
});

invokeai/frontend/web/src/features/controlLayers/store/canvasSlice.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ import {
101101
isRegionalGuidanceFLUXReduxConfig,
102102
isRegionalGuidanceIPAdapterConfig,
103103
zCanvasStateWithHistory,
104-
zCanvasStateWithoutHistory,
105104
} from './types';
106105
import {
107106
converters,
@@ -2102,7 +2101,7 @@ export const canvasSliceConfig: SliceConfig<typeof canvasSlice, CanvasStateWithH
21022101
},
21032102
};
21042103
}
2105-
return zCanvasStateWithoutHistory.parse(state);
2104+
return zCanvasStateWithHistory.parse(state);
21062105
},
21072106
serialize: (state) => {
21082107
return {

invokeai/frontend/web/src/features/controlLayers/store/types.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { zStateWithHistory } from 'app/store/types';
12
import { deepClone } from 'common/util/deepClone';
23
import type { CanvasEntityAdapter } from 'features/controlLayers/konva/CanvasEntity/types';
34
import { zMainModelBase, zModelIdentifierField } from 'features/nodes/types/common';
@@ -874,16 +875,6 @@ const zCanvasStagingAreaState = z.object({
874875
});
875876
export type CanvasStagingAreaState = z.infer<typeof zCanvasStagingAreaState>;
876877

877-
const zStateWithHistory = <T extends z.ZodTypeAny>(stateSchema: T) =>
878-
z.object({
879-
past: z.array(stateSchema),
880-
present: stateSchema,
881-
future: z.array(stateSchema),
882-
_latestUnfiltered: stateSchema.optional(),
883-
group: z.string().optional(),
884-
index: z.number().optional(),
885-
limit: z.number().optional(),
886-
});
887878
const zCanvasEntity = z.object({
888879
selectedEntityIdentifier: zCanvasEntityIdentifer.nullable(),
889880
bookmarkedEntityIdentifier: zCanvasEntityIdentifer.nullable(),
@@ -916,9 +907,9 @@ const zCanvasState = <T extends z.ZodTypeAny>(canvasInstanceSchema: T) =>
916907
activeCanvasId: zId,
917908
canvases: z.record(zId, canvasInstanceSchema),
918909
});
919-
export const zCanvasStateWithoutHistory = zCanvasState(zCanvasInstanceStateWithoutHistory);
910+
const _zCanvasStateWithoutHistory = zCanvasState(zCanvasInstanceStateWithoutHistory);
920911
export const zCanvasStateWithHistory = zCanvasState(zCanvasInstanceStateWithHistory);
921-
export type CanvasState = z.infer<typeof zCanvasStateWithoutHistory>;
912+
export type CanvasState = z.infer<typeof _zCanvasStateWithoutHistory>;
922913
export type CanvasStateWithHistory = z.infer<typeof zCanvasStateWithHistory>;
923914

924915
export const zCanvasReferenceImageState_OLD = zCanvasEntityBase.extend({

invokeai/frontend/web/src/features/nodes/store/nodesSlice.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
removeElement,
2020
reparentElement,
2121
} from 'features/nodes/components/sidePanel/builder/form-manipulation';
22-
import { type NodesState, zNodesState } from 'features/nodes/store/types';
22+
import { type NodesState, zNodesState, zNodesStateWithHistory } from 'features/nodes/store/types';
2323
import { SHARED_NODE_PROPERTIES } from 'features/nodes/types/constants';
2424
import type {
2525
BoardFieldValue,
@@ -85,12 +85,12 @@ import {
8585
} from 'features/nodes/types/workflow';
8686
import { atom, computed } from 'nanostores';
8787
import type { MouseEvent } from 'react';
88-
import type { StateWithHistory, UndoableOptions } from 'redux-undo';
88+
import type { UndoableOptions } from 'redux-undo';
8989
import undoable, { newHistory } from 'redux-undo';
9090
import { assert } from 'tsafe';
9191
import type { z } from 'zod';
9292

93-
import type { PendingConnection, Templates } from './types';
93+
import type { NodesStateWithHistory, PendingConnection, Templates } from './types';
9494

9595
export const getInitialWorkflow = (): Omit<NodesState, 'mode' | 'formFieldInitialValues' | '_version'> => {
9696
return {
@@ -807,7 +807,7 @@ const reduxUndoOptions: UndoableOptions<NodesState, UnknownAction> = {
807807

808808
export const undoableNodesSliceReducer = undoable(slice.reducer, reduxUndoOptions);
809809

810-
export const nodesSliceConfig: SliceConfig<typeof slice, StateWithHistory<NodesState>, NodesState> = {
810+
export const nodesSliceConfig: SliceConfig<typeof slice, NodesStateWithHistory, NodesState> = {
811811
slice,
812812
schema: zNodesState,
813813
getInitialState,
@@ -817,7 +817,7 @@ export const nodesSliceConfig: SliceConfig<typeof slice, StateWithHistory<NodesS
817817
if (!('_version' in state)) {
818818
state._version = 1;
819819
}
820-
return zNodesState.parse(state);
820+
return zNodesStateWithHistory.parse(state);
821821
},
822822
serialize: (state) => state.present,
823823
deserialize: (state) => {

invokeai/frontend/web/src/features/nodes/store/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { HandleType } from '@xyflow/react';
2+
import { zStateWithHistory } from 'app/store/types';
23
import { type FieldInputTemplate, type FieldOutputTemplate, zStatefulFieldValue } from 'features/nodes/types/field';
34
import { type InvocationTemplate, type NodeExecutionState, zAnyEdge, zAnyNode } from 'features/nodes/types/invocation';
45
import { zWorkflowV3 } from 'features/nodes/types/workflow';
@@ -23,4 +24,6 @@ export const zNodesState = z.object({
2324
formFieldInitialValues: z.record(z.string(), zStatefulFieldValue),
2425
...zWorkflowV3.omit({ nodes: true, edges: true, is_published: true }).shape,
2526
});
27+
export const zNodesStateWithHistory = zStateWithHistory(zNodesState);
2628
export type NodesState = z.infer<typeof zNodesState>;
29+
export type NodesStateWithHistory = z.infer<typeof zNodesStateWithHistory>;

0 commit comments

Comments
 (0)