From 5df3c00e28947f5190f030da9733a53904e12392 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:24:26 +1000 Subject: [PATCH] feat(ui): remove SerializableObject, use type-fest's JsonObject --- .../addAdHocPostProcessingRequestedListener.ts | 6 +++--- .../listenerMiddleware/listeners/batchEnqueued.ts | 8 ++++---- .../listeners/enqueueRequestedLinear.ts | 4 ++-- .../listenerMiddleware/listeners/getOpenAPISchema.ts | 6 +++--- .../listenerMiddleware/listeners/modelsLoaded.ts | 4 ++-- invokeai/frontend/web/src/app/store/store.ts | 4 ++-- invokeai/frontend/web/src/common/types.ts | 12 ------------ .../features/controlLayers/hooks/saveCanvasHooks.ts | 4 ++-- .../controlLayers/konva/CanvasCompositorModule.ts | 8 ++++---- .../konva/CanvasEntity/CanvasEntityAdapterBase.ts | 10 +++++----- .../CanvasEntity/CanvasEntityAdapterControlLayer.ts | 4 ++-- .../CanvasEntity/CanvasEntityAdapterInpaintMask.ts | 4 ++-- .../CanvasEntity/CanvasEntityAdapterRasterLayer.ts | 4 ++-- .../CanvasEntityAdapterRegionalGuidance.ts | 4 ++-- .../CanvasEntity/CanvasEntityBufferObjectRenderer.ts | 2 +- .../features/controlLayers/konva/CanvasManager.ts | 4 ++-- .../features/controlLayers/konva/CanvasModuleBase.ts | 6 +++--- .../konva/CanvasSegmentAnythingModule.ts | 2 +- .../controlLayers/konva/CanvasStateApiModule.ts | 8 ++++---- .../web/src/features/controlLayers/store/types.ts | 4 ++-- .../src/features/nodes/util/schema/parseSchema.ts | 4 ++-- .../features/nodes/util/workflow/validateWorkflow.ts | 4 ++-- .../web/src/services/api/endpoints/images.ts | 7 +++---- .../web/src/services/events/onInvocationComplete.tsx | 4 ++-- .../web/src/services/events/setEventListeners.tsx | 8 ++++---- 25 files changed, 61 insertions(+), 74 deletions(-) delete mode 100644 invokeai/frontend/web/src/common/types.ts diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addAdHocPostProcessingRequestedListener.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addAdHocPostProcessingRequestedListener.ts index 3c7a8b9ea7..cc1d2cbbaa 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addAdHocPostProcessingRequestedListener.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addAdHocPostProcessingRequestedListener.ts @@ -1,12 +1,12 @@ import { createAction } from '@reduxjs/toolkit'; import { logger } from 'app/logging/logger'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; -import type { SerializableObject } from 'common/types'; import { buildAdHocPostProcessingGraph } from 'features/nodes/util/graph/buildAdHocPostProcessingGraph'; import { toast } from 'features/toast/toast'; import { t } from 'i18next'; import { queueApi } from 'services/api/endpoints/queue'; import type { BatchConfig, ImageDTO } from 'services/api/types'; +import type { JsonObject } from 'type-fest'; const log = logger('queue'); @@ -39,9 +39,9 @@ export const addAdHocPostProcessingRequestedListener = (startAppListening: AppSt const enqueueResult = await req.unwrap(); req.reset(); - log.debug({ enqueueResult } as SerializableObject, t('queue.graphQueued')); + log.debug({ enqueueResult } as JsonObject, t('queue.graphQueued')); } catch (error) { - log.error({ enqueueBatchArg } as SerializableObject, t('queue.graphFailedToQueue')); + log.error({ enqueueBatchArg } as JsonObject, t('queue.graphFailedToQueue')); if (error instanceof Object && 'status' in error && error.status === 403) { return; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/batchEnqueued.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/batchEnqueued.ts index bfc0a014f7..e2fd33ecf3 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/batchEnqueued.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/batchEnqueued.ts @@ -1,12 +1,12 @@ import { logger } from 'app/logging/logger'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; -import type { SerializableObject } from 'common/types'; import { zPydanticValidationError } from 'features/system/store/zodSchemas'; import { toast } from 'features/toast/toast'; import { t } from 'i18next'; import { truncate, upperFirst } from 'lodash-es'; import { serializeError } from 'serialize-error'; import { queueApi } from 'services/api/endpoints/queue'; +import type { JsonObject } from 'type-fest'; const log = logger('queue'); @@ -17,7 +17,7 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) = effect: (action) => { const enqueueResult = action.payload; const arg = action.meta.arg.originalArgs; - log.debug({ enqueueResult } as SerializableObject, 'Batch enqueued'); + log.debug({ enqueueResult } as JsonObject, 'Batch enqueued'); toast({ id: 'QUEUE_BATCH_SUCCEEDED', @@ -45,7 +45,7 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) = status: 'error', description: t('common.unknownError'), }); - log.error({ batchConfig } as SerializableObject, t('queue.batchFailedToQueue')); + log.error({ batchConfig } as JsonObject, t('queue.batchFailedToQueue')); return; } @@ -71,7 +71,7 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) = description: t('common.unknownError'), }); } - log.error({ batchConfig, error: serializeError(response) } as SerializableObject, t('queue.batchFailedToQueue')); + log.error({ batchConfig, error: serializeError(response) } as JsonObject, t('queue.batchFailedToQueue')); }, }); }; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedLinear.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedLinear.ts index 60a8ea814f..8cc52045b0 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedLinear.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/enqueueRequestedLinear.ts @@ -1,7 +1,6 @@ import { logger } from 'app/logging/logger'; import { enqueueRequested } from 'app/store/actions'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; -import type { SerializableObject } from 'common/types'; import type { Result } from 'common/util/result'; import { withResult, withResultAsync } from 'common/util/result'; import { $canvasManager } from 'features/controlLayers/store/ephemeral'; @@ -14,6 +13,7 @@ import { serializeError } from 'serialize-error'; import { queueApi } from 'services/api/endpoints/queue'; import type { Invocation } from 'services/api/types'; import { assert } from 'tsafe'; +import type { JsonObject } from 'type-fest'; const log = logger('generation'); @@ -88,7 +88,7 @@ export const addEnqueueRequestedLinear = (startAppListening: AppStartListening) return; } - log.debug({ batchConfig: prepareBatchResult.value } as SerializableObject, 'Enqueued batch'); + log.debug({ batchConfig: prepareBatchResult.value } as JsonObject, 'Enqueued batch'); }, }); }; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/getOpenAPISchema.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/getOpenAPISchema.ts index 37aed5ac71..bbf2a09b6a 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/getOpenAPISchema.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/getOpenAPISchema.ts @@ -1,12 +1,12 @@ import { logger } from 'app/logging/logger'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; -import type { SerializableObject } from 'common/types'; import { parseify } from 'common/util/serialize'; import { $templates } from 'features/nodes/store/nodesSlice'; import { parseSchema } from 'features/nodes/util/schema/parseSchema'; import { size } from 'lodash-es'; import { serializeError } from 'serialize-error'; import { appInfoApi } from 'services/api/endpoints/appInfo'; +import type { JsonObject } from 'type-fest'; const log = logger('system'); @@ -16,12 +16,12 @@ export const addGetOpenAPISchemaListener = (startAppListening: AppStartListening effect: (action, { getState }) => { const schemaJSON = action.payload; - log.debug({ schemaJSON: parseify(schemaJSON) } as SerializableObject, 'Received OpenAPI schema'); + log.debug({ schemaJSON: parseify(schemaJSON) } as JsonObject, 'Received OpenAPI schema'); const { nodesAllowlist, nodesDenylist } = getState().config; const nodeTemplates = parseSchema(schemaJSON, nodesAllowlist, nodesDenylist); - log.debug({ nodeTemplates } as SerializableObject, `Built ${size(nodeTemplates)} node templates`); + log.debug({ nodeTemplates } as JsonObject, `Built ${size(nodeTemplates)} node templates`); $templates.set(nodeTemplates); }, diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts index a3cc9c31ac..770e376687 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts @@ -1,7 +1,6 @@ import { logger } from 'app/logging/logger'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; import type { AppDispatch, RootState } from 'app/store/store'; -import type { SerializableObject } from 'common/types'; import { controlLayerModelChanged, referenceImageIPAdapterModelChanged, @@ -41,6 +40,7 @@ import { isSpandrelImageToImageModelConfig, isT5EncoderModelConfig, } from 'services/api/types'; +import type { JsonObject } from 'type-fest'; const log = logger('models'); @@ -85,7 +85,7 @@ type ModelHandler = ( models: AnyModelConfig[], state: RootState, dispatch: AppDispatch, - log: Logger + log: Logger ) => undefined; const handleMainModels: ModelHandler = (models, state, dispatch, log) => { diff --git a/invokeai/frontend/web/src/app/store/store.ts b/invokeai/frontend/web/src/app/store/store.ts index 7345f47d75..a36300cca9 100644 --- a/invokeai/frontend/web/src/app/store/store.ts +++ b/invokeai/frontend/web/src/app/store/store.ts @@ -3,7 +3,6 @@ import { autoBatchEnhancer, combineReducers, configureStore } from '@reduxjs/too import { logger } from 'app/logging/logger'; import { idbKeyValDriver } from 'app/store/enhancers/reduxRemember/driver'; import { errorHandler } from 'app/store/enhancers/reduxRemember/errors'; -import type { SerializableObject } from 'common/types'; import { deepClone } from 'common/util/deepClone'; import { changeBoardModalSlice } from 'features/changeBoardModal/store/slice'; import { canvasSettingsPersistConfig, canvasSettingsSlice } from 'features/controlLayers/store/canvasSettingsSlice'; @@ -37,6 +36,7 @@ import undoable 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 { STORAGE_PREFIX } from './constants'; import { actionSanitizer } from './middleware/devtools/actionSanitizer'; @@ -139,7 +139,7 @@ const unserialize: UnserializeFunction = (data, key) => { { persistedData: parsed, rehydratedData: transformed, - diff: diff(parsed, transformed) as SerializableObject, // this is always serializable + diff: diff(parsed, transformed) as JsonObject, // this is always serializable }, `Rehydrated slice "${key}"` ); diff --git a/invokeai/frontend/web/src/common/types.ts b/invokeai/frontend/web/src/common/types.ts deleted file mode 100644 index 52faed590a..0000000000 --- a/invokeai/frontend/web/src/common/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -type SerializableValue = - | string - | number - | boolean - | null - | undefined - | SerializableValue[] - | readonly SerializableValue[] - | SerializableObject; -export type SerializableObject = { - [k: string | number]: SerializableValue; -}; diff --git a/invokeai/frontend/web/src/features/controlLayers/hooks/saveCanvasHooks.ts b/invokeai/frontend/web/src/features/controlLayers/hooks/saveCanvasHooks.ts index 61313ee3db..b97a205e49 100644 --- a/invokeai/frontend/web/src/features/controlLayers/hooks/saveCanvasHooks.ts +++ b/invokeai/frontend/web/src/features/controlLayers/hooks/saveCanvasHooks.ts @@ -1,6 +1,5 @@ import { logger } from 'app/logging/logger'; import { useAppDispatch, useAppSelector, useAppStore } from 'app/store/storeHooks'; -import type { SerializableObject } from 'common/types'; import { deepClone } from 'common/util/deepClone'; import { withResultAsync } from 'common/util/result'; import { useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate'; @@ -31,6 +30,7 @@ import { useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { serializeError } from 'serialize-error'; import type { ImageDTO } from 'services/api/types'; +import type { JsonObject } from 'type-fest'; const log = logger('canvas'); @@ -64,7 +64,7 @@ const useSaveCanvas = ({ region, saveToGallery, toastOk, toastError, onSave, wit return; } - let metadata: SerializableObject | undefined = undefined; + let metadata: JsonObject | undefined = undefined; if (withMetadata) { metadata = selectCanvasMetadata(store.getState()); diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasCompositorModule.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasCompositorModule.ts index a61beb1ebb..876c94689f 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasCompositorModule.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasCompositorModule.ts @@ -1,4 +1,3 @@ -import type { SerializableObject } from 'common/types'; import { withResultAsync } from 'common/util/result'; import { CanvasCacheModule } from 'features/controlLayers/konva/CanvasCacheModule'; import type { CanvasEntityAdapter, CanvasEntityAdapterFromType } from 'features/controlLayers/konva/CanvasEntity/types'; @@ -41,6 +40,7 @@ import type { ImageDTO } from 'services/api/types'; import stableHash from 'stable-hash'; import type { Equals } from 'tsafe'; import { assert } from 'tsafe'; +import type { JsonObject } from 'type-fest'; type CompositingOptions = { /** @@ -173,14 +173,14 @@ export class CanvasCompositorModule extends CanvasModuleBase { return adapters as CanvasEntityAdapterFromType[]; }; - getCompositeHash = (adapters: CanvasEntityAdapter[], extra: SerializableObject): string => { - const adapterHashes: SerializableObject[] = []; + getCompositeHash = (adapters: CanvasEntityAdapter[], extra: JsonObject): string => { + const adapterHashes: JsonObject[] = []; for (const adapter of adapters) { adapterHashes.push(adapter.getHashableState()); } - const data: SerializableObject = { + const data: JsonObject = { extra, adapterHashes, }; diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterBase.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterBase.ts index b791fb78c5..ee366068f2 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterBase.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterBase.ts @@ -1,7 +1,6 @@ import type { Selector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit'; import type { RootState } from 'app/store/store'; -import type { SerializableObject } from 'common/types'; import { deepClone } from 'common/util/deepClone'; import type { CanvasEntityBufferObjectRenderer } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityBufferObjectRenderer'; import type { CanvasEntityFilterer } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityFilterer'; @@ -37,6 +36,7 @@ import type { Logger } from 'roarr'; import type { ImageDTO } from 'services/api/types'; import stableHash from 'stable-hash'; import { assert } from 'tsafe'; +import type { Jsonifiable, JsonObject } from 'type-fest'; // Ideally, we'd type `adapter` as `CanvasEntityAdapterBase`, but the generics make this tricky. `CanvasEntityAdapter` // is a union of all entity adapters and is functionally identical to `CanvasEntityAdapterBase`. We'll need to do a @@ -111,7 +111,7 @@ export abstract class CanvasEntityAdapterBase< * * This is used for caching. */ - abstract getHashableState: () => SerializableObject; + abstract getHashableState: () => JsonObject; /** * Callbacks that are executed when the module is initialized. @@ -566,7 +566,7 @@ export abstract class CanvasEntityAdapterBase< * Gets a hash of the entity's state, as provided by `getHashableState`. If `extra` is provided, it will be included in * the hash. */ - hash = (extra?: SerializableObject): string => { + hash = (extra?: Jsonifiable): string => { const arg = { state: this.getHashableState(), extra, @@ -614,8 +614,8 @@ export abstract class CanvasEntityAdapterBase< transformer: this.transformer.repr(), renderer: this.renderer.repr(), bufferRenderer: this.bufferRenderer.repr(), - segmentAnything: this.segmentAnything?.repr(), - filterer: this.filterer?.repr(), + segmentAnything: this.segmentAnything?.repr() ?? null, + filterer: this.filterer?.repr() ?? null, hasCache: this.$canvasCache.get() !== null, isLocked: this.$isLocked.get(), isDisabled: this.$isDisabled.get(), diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterControlLayer.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterControlLayer.ts index ad242d61c8..583f0eff37 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterControlLayer.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterControlLayer.ts @@ -1,4 +1,3 @@ -import type { SerializableObject } from 'common/types'; import { CanvasEntityAdapterBase } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterBase'; import { CanvasEntityBufferObjectRenderer } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityBufferObjectRenderer'; import { CanvasEntityFilterer } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityFilterer'; @@ -9,6 +8,7 @@ import { CanvasSegmentAnythingModule } from 'features/controlLayers/konva/Canvas import type { CanvasControlLayerState, CanvasEntityIdentifier, Rect } from 'features/controlLayers/store/types'; import type { GroupConfig } from 'konva/lib/Group'; import { omit } from 'lodash-es'; +import type { JsonObject } from 'type-fest'; export class CanvasEntityAdapterControlLayer extends CanvasEntityAdapterBase< CanvasControlLayerState, @@ -77,7 +77,7 @@ export class CanvasEntityAdapterControlLayer extends CanvasEntityAdapterBase< return canvas; }; - getHashableState = (): SerializableObject => { + getHashableState = (): JsonObject => { const keysToOmit: (keyof CanvasControlLayerState)[] = [ 'name', 'controlAdapter', diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterInpaintMask.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterInpaintMask.ts index 4fc4d2c4a9..03988f6efe 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterInpaintMask.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterInpaintMask.ts @@ -1,4 +1,3 @@ -import type { SerializableObject } from 'common/types'; import { CanvasEntityAdapterBase } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterBase'; import { CanvasEntityBufferObjectRenderer } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityBufferObjectRenderer'; import { CanvasEntityObjectRenderer } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityObjectRenderer'; @@ -7,6 +6,7 @@ import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasEntityIdentifier, CanvasInpaintMaskState, Rect } from 'features/controlLayers/store/types'; import type { GroupConfig } from 'konva/lib/Group'; import { omit } from 'lodash-es'; +import type { JsonObject } from 'type-fest'; export class CanvasEntityAdapterInpaintMask extends CanvasEntityAdapterBase< CanvasInpaintMaskState, @@ -69,7 +69,7 @@ export class CanvasEntityAdapterInpaintMask extends CanvasEntityAdapterBase< } }; - getHashableState = (): SerializableObject => { + getHashableState = (): JsonObject => { const keysToOmit: (keyof CanvasInpaintMaskState)[] = ['fill', 'name', 'opacity', 'isLocked']; return omit(this.state, keysToOmit); }; diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterRasterLayer.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterRasterLayer.ts index ed582ef6c1..52d39848b5 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterRasterLayer.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterRasterLayer.ts @@ -1,4 +1,3 @@ -import type { SerializableObject } from 'common/types'; import { CanvasEntityAdapterBase } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterBase'; import { CanvasEntityBufferObjectRenderer } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityBufferObjectRenderer'; import { CanvasEntityFilterer } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityFilterer'; @@ -9,6 +8,7 @@ import { CanvasSegmentAnythingModule } from 'features/controlLayers/konva/Canvas import type { CanvasEntityIdentifier, CanvasRasterLayerState, Rect } from 'features/controlLayers/store/types'; import type { GroupConfig } from 'konva/lib/Group'; import { omit } from 'lodash-es'; +import type { JsonObject } from 'type-fest'; export class CanvasEntityAdapterRasterLayer extends CanvasEntityAdapterBase< CanvasRasterLayerState, @@ -70,7 +70,7 @@ export class CanvasEntityAdapterRasterLayer extends CanvasEntityAdapterBase< return canvas; }; - getHashableState = (): SerializableObject => { + getHashableState = (): JsonObject => { const keysToOmit: (keyof CanvasRasterLayerState)[] = ['name', 'isLocked']; return omit(this.state, keysToOmit); }; diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterRegionalGuidance.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterRegionalGuidance.ts index df1b90abaa..a56ea2ce0f 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterRegionalGuidance.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterRegionalGuidance.ts @@ -1,4 +1,3 @@ -import type { SerializableObject } from 'common/types'; import { CanvasEntityAdapterBase } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityAdapterBase'; import { CanvasEntityBufferObjectRenderer } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityBufferObjectRenderer'; import { CanvasEntityObjectRenderer } from 'features/controlLayers/konva/CanvasEntity/CanvasEntityObjectRenderer'; @@ -7,6 +6,7 @@ import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasEntityIdentifier, CanvasRegionalGuidanceState, Rect } from 'features/controlLayers/store/types'; import type { GroupConfig } from 'konva/lib/Group'; import { omit } from 'lodash-es'; +import type { JsonObject } from 'type-fest'; export class CanvasEntityAdapterRegionalGuidance extends CanvasEntityAdapterBase< CanvasRegionalGuidanceState, @@ -69,7 +69,7 @@ export class CanvasEntityAdapterRegionalGuidance extends CanvasEntityAdapterBase } }; - getHashableState = (): SerializableObject => { + getHashableState = (): JsonObject => { const keysToOmit: (keyof CanvasRegionalGuidanceState)[] = [ 'fill', 'name', diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityBufferObjectRenderer.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityBufferObjectRenderer.ts index a6022abf17..2dc5bdab26 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityBufferObjectRenderer.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasEntity/CanvasEntityBufferObjectRenderer.ts @@ -260,7 +260,7 @@ export class CanvasEntityBufferObjectRenderer extends CanvasModuleBase { path: this.path, parent: this.parent.id, bufferState: deepClone(this.state), - bufferRenderer: this.renderer?.repr(), + bufferRenderer: this.renderer?.repr() ?? null, }; }; } diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasManager.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasManager.ts index 59ff083abc..4145197edf 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasManager.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasManager.ts @@ -1,6 +1,5 @@ import { logger } from 'app/logging/logger'; import type { AppStore } from 'app/store/store'; -import type { SerializableObject } from 'common/types'; import { SyncableMap } from 'common/util/SyncableMap/SyncableMap'; import { CanvasCacheModule } from 'features/controlLayers/konva/CanvasCacheModule'; import { CanvasCompositorModule } from 'features/controlLayers/konva/CanvasCompositorModule'; @@ -35,6 +34,7 @@ import { computed } from 'nanostores'; import type { Logger } from 'roarr'; import type { AppSocket } from 'services/events/types'; import { assert } from 'tsafe'; +import type { JsonObject } from 'type-fest'; import { CanvasBackgroundModule } from './CanvasBackgroundModule'; import { CanvasStateApiModule } from './CanvasStateApiModule'; @@ -294,7 +294,7 @@ export class CanvasManager extends CanvasModuleBase { }; }; - getLoggingContext = (): SerializableObject => ({ path: this.path }); + getLoggingContext = (): JsonObject => ({ path: this.path }); buildPath = (canvasModule: CanvasModuleBase): string[] => { return canvasModule.parent.path.concat(canvasModule.id); diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasModuleBase.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasModuleBase.ts index 5912d4cfa3..09270e875f 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasModuleBase.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasModuleBase.ts @@ -1,6 +1,6 @@ -import type { SerializableObject } from 'common/types'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { Logger } from 'roarr'; +import type { JsonObject } from 'type-fest'; /** * Base class for all canvas modules. @@ -81,7 +81,7 @@ export abstract class CanvasModuleBase { * }; * ``` */ - getLoggingContext: () => SerializableObject = () => { + getLoggingContext: () => JsonObject = () => { return { ...this.parent.getLoggingContext(), path: this.path.join(' > '), @@ -135,7 +135,7 @@ export abstract class CanvasModuleBase { * }; * ``` */ - repr: () => SerializableObject = () => { + repr: () => JsonObject = () => { return { id: this.id, type: this.type, diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasSegmentAnythingModule.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasSegmentAnythingModule.ts index 0ee97212eb..e1b206245c 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasSegmentAnythingModule.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasSegmentAnythingModule.ts @@ -891,7 +891,7 @@ export class CanvasSegmentAnythingModule extends CanvasModuleBase { circle: getKonvaNodeDebugAttrs(konva.circle), })), imageState: deepClone(this.$imageState.get()), - imageModule: this.imageModule?.repr(), + imageModule: this.imageModule?.repr() ?? null, config: deepClone(this.config), $isSegmenting: this.$isSegmenting.get(), $lastProcessedHash: this.$lastProcessedHash.get(), diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApiModule.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApiModule.ts index 8635e0ce0d..2b3613717c 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApiModule.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApiModule.ts @@ -686,13 +686,13 @@ export class CanvasStateApiModule extends CanvasModuleBase { id: this.id, type: this.type, path: this.path, - $filteringAdapter: this.$filteringAdapter.get()?.entityIdentifier, + $filteringAdapter: this.$filteringAdapter.get()?.entityIdentifier ?? null, $isFiltering: this.$isFiltering.get(), - $transformingAdapter: this.$transformingAdapter.get()?.entityIdentifier, + $transformingAdapter: this.$transformingAdapter.get()?.entityIdentifier ?? null, $isTransforming: this.$isTransforming.get(), - $rasterizingAdapter: this.$rasterizingAdapter.get()?.entityIdentifier, + $rasterizingAdapter: this.$rasterizingAdapter.get()?.entityIdentifier ?? null, $isRasterizing: this.$isRasterizing.get(), - $segmentingAdapter: this.$segmentingAdapter.get()?.entityIdentifier, + $segmentingAdapter: this.$segmentingAdapter.get()?.entityIdentifier ?? null, $isSegmenting: this.$isSegmenting.get(), }; }; diff --git a/invokeai/frontend/web/src/features/controlLayers/store/types.ts b/invokeai/frontend/web/src/features/controlLayers/store/types.ts index 13e973db0c..d82253bdbf 100644 --- a/invokeai/frontend/web/src/features/controlLayers/store/types.ts +++ b/invokeai/frontend/web/src/features/controlLayers/store/types.ts @@ -1,4 +1,3 @@ -import type { SerializableObject } from 'common/types'; import { fetchModelConfigByIdentifier } from 'features/metadata/util/modelFetchingHelpers'; import { zMainModelBase, zModelIdentifierField } from 'features/nodes/types/common'; import type { ParameterLoRAModel } from 'features/parameters/types/parameterSchemas'; @@ -9,6 +8,7 @@ import { } from 'features/parameters/types/parameterSchemas'; import { getImageDTOSafe } from 'services/api/endpoints/images'; import type { ImageDTO } from 'services/api/types'; +import type { JsonObject } from 'type-fest'; import { z } from 'zod'; const zId = z.string().min(1); @@ -429,7 +429,7 @@ export type StageAttrs = { }; export type EntityIdentifierPayload< - T extends SerializableObject | void = void, + T extends JsonObject | void = void, U extends CanvasEntityType = CanvasEntityType, > = T extends void ? { diff --git a/invokeai/frontend/web/src/features/nodes/util/schema/parseSchema.ts b/invokeai/frontend/web/src/features/nodes/util/schema/parseSchema.ts index e412aee77a..a09b341c28 100644 --- a/invokeai/frontend/web/src/features/nodes/util/schema/parseSchema.ts +++ b/invokeai/frontend/web/src/features/nodes/util/schema/parseSchema.ts @@ -1,5 +1,4 @@ import { logger } from 'app/logging/logger'; -import type { SerializableObject } from 'common/types'; import { deepClone } from 'common/util/deepClone'; import { parseify } from 'common/util/serialize'; import type { Templates } from 'features/nodes/store/types'; @@ -21,6 +20,7 @@ import { t } from 'i18next'; import { isEqual, reduce } from 'lodash-es'; import type { OpenAPIV3_1 } from 'openapi-types'; import { serializeError } from 'serialize-error'; +import type { JsonObject } from 'type-fest'; import { buildFieldInputTemplate } from './buildFieldInputTemplate'; import { buildFieldOutputTemplate } from './buildFieldOutputTemplate'; @@ -89,7 +89,7 @@ export const parseSchema = ( (inputsAccumulator: Record, property, propertyName) => { if (isReservedInputField(type, propertyName)) { log.trace( - { node: type, field: propertyName, schema: property } as SerializableObject, + { node: type, field: propertyName, schema: property } as JsonObject, 'Skipped reserved input field' ); return inputsAccumulator; diff --git a/invokeai/frontend/web/src/features/nodes/util/workflow/validateWorkflow.ts b/invokeai/frontend/web/src/features/nodes/util/workflow/validateWorkflow.ts index 39a1b03aa6..801f7d1fbf 100644 --- a/invokeai/frontend/web/src/features/nodes/util/workflow/validateWorkflow.ts +++ b/invokeai/frontend/web/src/features/nodes/util/workflow/validateWorkflow.ts @@ -1,4 +1,3 @@ -import type { SerializableObject } from 'common/types'; import { parseify } from 'common/util/serialize'; import type { Templates } from 'features/nodes/store/types'; import { @@ -11,13 +10,14 @@ import { isWorkflowInvocationNode } from 'features/nodes/types/workflow'; import { getNeedsUpdate } from 'features/nodes/util/node/nodeUpdate'; import { t } from 'i18next'; import { keyBy } from 'lodash-es'; +import type { JsonObject } from 'type-fest'; import { parseAndMigrateWorkflow } from './migrations'; type WorkflowWarning = { message: string; issues?: string[]; - data: SerializableObject; + data: JsonObject; }; type ValidateWorkflowResult = { diff --git a/invokeai/frontend/web/src/services/api/endpoints/images.ts b/invokeai/frontend/web/src/services/api/endpoints/images.ts index 436601fb6f..c830eddf61 100644 --- a/invokeai/frontend/web/src/services/api/endpoints/images.ts +++ b/invokeai/frontend/web/src/services/api/endpoints/images.ts @@ -1,6 +1,5 @@ import type { StartQueryActionCreatorOptions } from '@reduxjs/toolkit/dist/query/core/buildInitiate'; import { getStore } from 'app/store/nanostores/store'; -import type { SerializableObject } from 'common/types'; import type { BoardId } from 'features/gallery/store/types'; import { ASSETS_CATEGORIES, IMAGE_CATEGORIES } from 'features/gallery/store/types'; import type { components, paths } from 'services/api/schema'; @@ -76,7 +75,7 @@ export const imagesApi = api.injectEndpoints({ query: (image_name) => ({ url: buildImagesUrl(`i/${image_name}`) }), providesTags: (result, error, image_name) => [{ type: 'Image', id: image_name }], }), - getImageMetadata: build.query({ + getImageMetadata: build.query({ query: (image_name) => ({ url: buildImagesUrl(`i/${image_name}/metadata`) }), providesTags: (result, error, image_name) => [{ type: 'ImageMetadata', id: image_name }], }), @@ -270,7 +269,7 @@ export const imagesApi = api.injectEndpoints({ session_id?: string; board_id?: string; crop_visible?: boolean; - metadata?: SerializableObject; + metadata?: JsonObject; isFirstUploadOfBatch?: boolean; } >({ @@ -613,7 +612,7 @@ export const getImageDTO = (image_name: string, options?: StartQueryActionCreato export const getImageMetadata = ( image_name: string, options?: StartQueryActionCreatorOptions -): Promise => { +): Promise => { const _options = { subscribe: false, ...options, diff --git a/invokeai/frontend/web/src/services/events/onInvocationComplete.tsx b/invokeai/frontend/web/src/services/events/onInvocationComplete.tsx index 617528e225..78f9b27a09 100644 --- a/invokeai/frontend/web/src/services/events/onInvocationComplete.tsx +++ b/invokeai/frontend/web/src/services/events/onInvocationComplete.tsx @@ -1,6 +1,5 @@ import { logger } from 'app/logging/logger'; import type { AppDispatch, RootState } from 'app/store/store'; -import type { SerializableObject } from 'common/types'; import { deepClone } from 'common/util/deepClone'; import { stagingAreaImageStaged } from 'features/controlLayers/store/canvasStagingAreaSlice'; import { boardIdSelected, galleryViewChanged, imageSelected, offsetChanged } from 'features/gallery/store/gallerySlice'; @@ -12,6 +11,7 @@ import { getImageDTOSafe, imagesApi } from 'services/api/endpoints/images'; import type { ImageDTO, S } from 'services/api/types'; import { getCategories, getListImagesUrl } from 'services/api/util'; import { $lastProgressEvent } from 'services/events/stores'; +import type { JsonObject } from 'type-fest'; const log = logger('events'); @@ -145,7 +145,7 @@ export const buildOnInvocationComplete = (getState: () => RootState, dispatch: A return async (data: S['InvocationCompleteEvent']) => { log.debug( - { data } as SerializableObject, + { data } as JsonObject, `Invocation complete (${data.invocation.type}, ${data.invocation_source_id})` ); diff --git a/invokeai/frontend/web/src/services/events/setEventListeners.tsx b/invokeai/frontend/web/src/services/events/setEventListeners.tsx index d181ebb0a3..ac1de8c4be 100644 --- a/invokeai/frontend/web/src/services/events/setEventListeners.tsx +++ b/invokeai/frontend/web/src/services/events/setEventListeners.tsx @@ -5,7 +5,6 @@ import { $baseUrl } from 'app/store/nanostores/baseUrl'; import { $bulkDownloadId } from 'app/store/nanostores/bulkDownloadId'; import { $queueId } from 'app/store/nanostores/queueId'; import type { AppStore } from 'app/store/store'; -import type { SerializableObject } from 'common/types'; import { deepClone } from 'common/util/deepClone'; import { $isHFForbiddenToastOpen } from 'features/modelManagerV2/hooks/useHFForbiddenToast'; import { $isHFLoginToastOpen } from 'features/modelManagerV2/hooks/useHFLoginToast'; @@ -22,6 +21,7 @@ import { queueApi, queueItemsAdapter } from 'services/api/endpoints/queue'; import { buildOnInvocationComplete } from 'services/events/onInvocationComplete'; import type { ClientToServerEvents, ServerToClientEvents } from 'services/events/types'; import type { Socket } from 'socket.io-client'; +import type { JsonObject } from 'type-fest'; import { $lastProgressEvent } from './stores'; @@ -76,7 +76,7 @@ export const setEventListeners = ({ socket, store, setIsConnected }: SetEventLis socket.on('invocation_started', (data) => { const { invocation_source_id, invocation } = data; - log.debug({ data } as SerializableObject, `Invocation started (${invocation.type}, ${invocation_source_id})`); + log.debug({ data } as JsonObject, `Invocation started (${invocation.type}, ${invocation_source_id})`); const nes = deepClone($nodeExecutionStates.get()[invocation_source_id]); if (nes) { nes.status = zNodeStatus.enum.IN_PROGRESS; @@ -96,7 +96,7 @@ export const setEventListeners = ({ socket, store, setIsConnected }: SetEventLis } _message += ` (${invocation.type}, ${invocation_source_id})`; - log.trace({ data } as SerializableObject, _message); + log.trace({ data } as JsonObject, _message); $lastProgressEvent.set(data); @@ -113,7 +113,7 @@ export const setEventListeners = ({ socket, store, setIsConnected }: SetEventLis socket.on('invocation_error', (data) => { const { invocation_source_id, invocation, error_type, error_message, error_traceback } = data; - log.error({ data } as SerializableObject, `Invocation error (${invocation.type}, ${invocation_source_id})`); + log.error({ data } as JsonObject, `Invocation error (${invocation.type}, ${invocation_source_id})`); const nes = deepClone($nodeExecutionStates.get()[invocation_source_id]); if (nes) { nes.status = zNodeStatus.enum.FAILED;