tidy(ui): reduce use of parseify util

This commit is contained in:
psychedelicious 2024-08-23 11:19:51 +10:00
parent 8bc72a2744
commit ac9b5f246d
28 changed files with 71 additions and 75 deletions

View File

@ -1,5 +1,4 @@
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import { parseify } from 'common/util/serialize';
import { PersistError, RehydrateError } from 'redux-remember'; import { PersistError, RehydrateError } from 'redux-remember';
import { serializeError } from 'serialize-error'; import { serializeError } from 'serialize-error';
@ -41,6 +40,6 @@ export const errorHandler = (err: PersistError | RehydrateError) => {
} else if (err instanceof RehydrateError) { } else if (err instanceof RehydrateError) {
log.error({ error: serializeError(err) }, 'Problem rehydrating state'); log.error({ error: serializeError(err) }, 'Problem rehydrating state');
} else { } else {
log.error({ error: parseify(err) }, 'Problem in persistence layer'); log.error({ error: serializeError(err) }, 'Problem in persistence layer');
} }
}; };

View File

@ -1,7 +1,7 @@
import { createAction } from '@reduxjs/toolkit'; import { createAction } from '@reduxjs/toolkit';
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { parseify } from 'common/util/serialize'; import type { SerializableObject } from 'common/types';
import { buildAdHocPostProcessingGraph } from 'features/nodes/util/graph/buildAdHocPostProcessingGraph'; import { buildAdHocPostProcessingGraph } from 'features/nodes/util/graph/buildAdHocPostProcessingGraph';
import { toast } from 'features/toast/toast'; import { toast } from 'features/toast/toast';
import { t } from 'i18next'; import { t } from 'i18next';
@ -39,9 +39,9 @@ export const addAdHocPostProcessingRequestedListener = (startAppListening: AppSt
const enqueueResult = await req.unwrap(); const enqueueResult = await req.unwrap();
req.reset(); req.reset();
log.debug({ enqueueResult: parseify(enqueueResult) }, t('queue.graphQueued')); log.debug({ enqueueResult } as SerializableObject, t('queue.graphQueued'));
} catch (error) { } catch (error) {
log.error({ enqueueBatchArg: parseify(enqueueBatchArg) }, t('queue.graphFailedToQueue')); log.error({ enqueueBatchArg } as SerializableObject, t('queue.graphFailedToQueue'));
if (error instanceof Object && 'status' in error && error.status === 403) { if (error instanceof Object && 'status' in error && error.status === 403) {
return; return;

View File

@ -1,10 +1,11 @@
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { parseify } from 'common/util/serialize'; import type { SerializableObject } from 'common/types';
import { zPydanticValidationError } from 'features/system/store/zodSchemas'; import { zPydanticValidationError } from 'features/system/store/zodSchemas';
import { toast } from 'features/toast/toast'; import { toast } from 'features/toast/toast';
import { t } from 'i18next'; import { t } from 'i18next';
import { truncate, upperFirst } from 'lodash-es'; import { truncate, upperFirst } from 'lodash-es';
import { serializeError } from 'serialize-error';
import { queueApi } from 'services/api/endpoints/queue'; import { queueApi } from 'services/api/endpoints/queue';
const log = logger('queue'); const log = logger('queue');
@ -13,17 +14,17 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) =
// success // success
startAppListening({ startAppListening({
matcher: queueApi.endpoints.enqueueBatch.matchFulfilled, matcher: queueApi.endpoints.enqueueBatch.matchFulfilled,
effect: async (action) => { effect: (action) => {
const response = action.payload; const enqueueResult = action.payload;
const arg = action.meta.arg.originalArgs; const arg = action.meta.arg.originalArgs;
log.debug({ enqueueResult: parseify(response) }, 'Batch enqueued'); log.debug({ enqueueResult } as SerializableObject, 'Batch enqueued');
toast({ toast({
id: 'QUEUE_BATCH_SUCCEEDED', id: 'QUEUE_BATCH_SUCCEEDED',
title: t('queue.batchQueued'), title: t('queue.batchQueued'),
status: 'success', status: 'success',
description: t('queue.batchQueuedDesc', { description: t('queue.batchQueuedDesc', {
count: response.enqueued, count: enqueueResult.enqueued,
direction: arg.prepend ? t('queue.front') : t('queue.back'), direction: arg.prepend ? t('queue.front') : t('queue.back'),
}), }),
}); });
@ -33,9 +34,9 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) =
// error // error
startAppListening({ startAppListening({
matcher: queueApi.endpoints.enqueueBatch.matchRejected, matcher: queueApi.endpoints.enqueueBatch.matchRejected,
effect: async (action) => { effect: (action) => {
const response = action.payload; const response = action.payload;
const arg = action.meta.arg.originalArgs; const batchConfig = action.meta.arg.originalArgs;
if (!response) { if (!response) {
toast({ toast({
@ -44,7 +45,7 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) =
status: 'error', status: 'error',
description: t('common.unknownError'), description: t('common.unknownError'),
}); });
log.error({ batchConfig: parseify(arg), error: parseify(response) }, t('queue.batchFailedToQueue')); log.error({ batchConfig } as SerializableObject, t('queue.batchFailedToQueue'));
return; return;
} }
@ -70,7 +71,7 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) =
description: t('common.unknownError'), description: t('common.unknownError'),
}); });
} }
log.error({ batchConfig: parseify(arg), error: parseify(response) }, t('queue.batchFailedToQueue')); log.error({ batchConfig, error: serializeError(response) } as SerializableObject, t('queue.batchFailedToQueue'));
}, },
}); });
}; };

View File

@ -2,6 +2,7 @@ import { isAnyOf } from '@reduxjs/toolkit';
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import type { AppDispatch } from 'app/store/store'; import type { AppDispatch } from 'app/store/store';
import type { SerializableObject } from 'common/types';
import { parseify } from 'common/util/serialize'; import { parseify } from 'common/util/serialize';
import { import {
caImageChanged, caImageChanged,
@ -125,7 +126,7 @@ export const addControlAdapterPreprocessor = (startAppListening: AppStartListeni
// TODO(psyche): Update the pydantic models, pretty sure we will _always_ have a batch_id here, but the model says it's optional // TODO(psyche): Update the pydantic models, pretty sure we will _always_ have a batch_id here, but the model says it's optional
assert(enqueueResult.batch.batch_id, 'Batch ID not returned from queue'); assert(enqueueResult.batch.batch_id, 'Batch ID not returned from queue');
dispatch(caProcessorPendingBatchIdChanged({ id, batchId: enqueueResult.batch.batch_id })); dispatch(caProcessorPendingBatchIdChanged({ id, batchId: enqueueResult.batch.batch_id }));
log.debug({ enqueueResult: parseify(enqueueResult) }, t('queue.graphQueued')); log.debug({ enqueueResult } as SerializableObject, t('queue.graphQueued'));
// Wait for the processor node to complete // Wait for the processor node to complete
const [invocationCompleteAction] = await take( const [invocationCompleteAction] = await take(

View File

@ -1,8 +1,8 @@
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import { enqueueRequested } from 'app/store/actions'; import { enqueueRequested } from 'app/store/actions';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import type { SerializableObject } from 'common/types';
import openBase64ImageInTab from 'common/util/openBase64ImageInTab'; import openBase64ImageInTab from 'common/util/openBase64ImageInTab';
import { parseify } from 'common/util/serialize';
import { canvasBatchIdAdded, stagingAreaInitialized } from 'features/canvas/store/canvasSlice'; import { canvasBatchIdAdded, stagingAreaInitialized } from 'features/canvas/store/canvasSlice';
import { getCanvasData } from 'features/canvas/util/getCanvasData'; import { getCanvasData } from 'features/canvas/util/getCanvasData';
import { getCanvasGenerationMode } from 'features/canvas/util/getCanvasGenerationMode'; import { getCanvasGenerationMode } from 'features/canvas/util/getCanvasGenerationMode';
@ -104,7 +104,7 @@ export const addEnqueueRequestedCanvasListener = (startAppListening: AppStartLis
const graph = await buildCanvasGraph(state, generationMode, canvasInitImage, canvasMaskImage); const graph = await buildCanvasGraph(state, generationMode, canvasInitImage, canvasMaskImage);
log.debug({ graph: parseify(graph) }, `Canvas graph built`); log.debug({ graph } as SerializableObject, `Canvas graph built`);
// currently this action is just listened to for logging // currently this action is just listened to for logging
dispatch(canvasGraphBuilt(graph)); dispatch(canvasGraphBuilt(graph));

View File

@ -1,9 +1,11 @@
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import type { SerializableObject } from 'common/types';
import { parseify } from 'common/util/serialize'; import { parseify } from 'common/util/serialize';
import { $templates } from 'features/nodes/store/nodesSlice'; import { $templates } from 'features/nodes/store/nodesSlice';
import { parseSchema } from 'features/nodes/util/schema/parseSchema'; import { parseSchema } from 'features/nodes/util/schema/parseSchema';
import { size } from 'lodash-es'; import { size } from 'lodash-es';
import { serializeError } from 'serialize-error';
import { appInfoApi } from 'services/api/endpoints/appInfo'; import { appInfoApi } from 'services/api/endpoints/appInfo';
const log = logger('system'); const log = logger('system');
@ -14,12 +16,12 @@ export const addGetOpenAPISchemaListener = (startAppListening: AppStartListening
effect: (action, { getState }) => { effect: (action, { getState }) => {
const schemaJSON = action.payload; const schemaJSON = action.payload;
log.debug({ schemaJSON: parseify(schemaJSON) }, 'Received OpenAPI schema'); log.debug({ schemaJSON: parseify(schemaJSON) } as SerializableObject, 'Received OpenAPI schema');
const { nodesAllowlist, nodesDenylist } = getState().config; const { nodesAllowlist, nodesDenylist } = getState().config;
const nodeTemplates = parseSchema(schemaJSON, nodesAllowlist, nodesDenylist); const nodeTemplates = parseSchema(schemaJSON, nodesAllowlist, nodesDenylist);
log.debug({ nodeTemplates: parseify(nodeTemplates) }, `Built ${size(nodeTemplates)} node templates`); log.debug({ nodeTemplates } as SerializableObject, `Built ${size(nodeTemplates)} node templates`);
$templates.set(nodeTemplates); $templates.set(nodeTemplates);
}, },
@ -31,7 +33,7 @@ export const addGetOpenAPISchemaListener = (startAppListening: AppStartListening
// If action.meta.condition === true, the request was canceled/skipped because another request was in flight or // If action.meta.condition === true, the request was canceled/skipped because another request was in flight or
// the value was already in the cache. We don't want to log these errors. // the value was already in the cache. We don't want to log these errors.
if (!action.meta.condition) { if (!action.meta.condition) {
log.error({ error: parseify(action.error) }, 'Problem retrieving OpenAPI Schema'); log.error({ error: serializeError(action.error) }, 'Problem retrieving OpenAPI Schema');
} }
}, },
}); });

View File

@ -1,7 +1,6 @@
import { createAction } from '@reduxjs/toolkit'; import { createAction } from '@reduxjs/toolkit';
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { parseify } from 'common/util/serialize';
import { import {
controlLayerAdded, controlLayerAdded,
ipaImageChanged, ipaImageChanged,
@ -43,7 +42,7 @@ export const addImageDroppedListener = (startAppListening: AppStartListening) =>
} else if (activeData.payloadType === 'GALLERY_SELECTION') { } else if (activeData.payloadType === 'GALLERY_SELECTION') {
log.debug({ activeData, overData }, `Images (${getState().gallery.selection.length}) dropped`); log.debug({ activeData, overData }, `Images (${getState().gallery.selection.length}) dropped`);
} else if (activeData.payloadType === 'NODE_FIELD') { } else if (activeData.payloadType === 'NODE_FIELD') {
log.debug({ activeData: parseify(activeData), overData: parseify(overData) }, 'Node field dropped'); log.debug({ activeData, overData }, 'Node field dropped');
} else { } else {
log.debug({ activeData, overData }, `Unknown payload dropped`); log.debug({ activeData, overData }, `Unknown payload dropped`);
} }

View File

@ -1,7 +1,7 @@
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import type { AppDispatch, RootState } from 'app/store/store'; import type { AppDispatch, RootState } from 'app/store/store';
import type { JSONObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import { import {
bboxHeightChanged, bboxHeightChanged,
bboxWidthChanged, bboxWidthChanged,
@ -58,7 +58,7 @@ type ModelHandler = (
models: AnyModelConfig[], models: AnyModelConfig[],
state: RootState, state: RootState,
dispatch: AppDispatch, dispatch: AppDispatch,
log: Logger<JSONObject> log: Logger<SerializableObject>
) => undefined; ) => undefined;
const handleMainModels: ModelHandler = (models, state, dispatch, log) => { const handleMainModels: ModelHandler = (models, state, dispatch, log) => {

View File

@ -1,6 +1,5 @@
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
import { parseify } from 'common/util/serialize';
import { $nodeExecutionStates } from 'features/nodes/hooks/useExecutionState'; import { $nodeExecutionStates } from 'features/nodes/hooks/useExecutionState';
import { workflowLoaded, workflowLoadRequested } from 'features/nodes/store/actions'; import { workflowLoaded, workflowLoadRequested } from 'features/nodes/store/actions';
import { $templates } from 'features/nodes/store/nodesSlice'; import { $templates } from 'features/nodes/store/nodesSlice';
@ -11,6 +10,7 @@ import { graphToWorkflow } from 'features/nodes/util/workflow/graphToWorkflow';
import { validateWorkflow } from 'features/nodes/util/workflow/validateWorkflow'; import { validateWorkflow } from 'features/nodes/util/workflow/validateWorkflow';
import { toast } from 'features/toast/toast'; import { toast } from 'features/toast/toast';
import { t } from 'i18next'; import { t } from 'i18next';
import { serializeError } from 'serialize-error';
import { checkBoardAccess, checkImageAccess, checkModelAccess } from 'services/api/hooks/accessChecks'; import { checkBoardAccess, checkImageAccess, checkModelAccess } from 'services/api/hooks/accessChecks';
import type { GraphAndWorkflowResponse, NonNullableGraph } from 'services/api/types'; import type { GraphAndWorkflowResponse, NonNullableGraph } from 'services/api/types';
import { z } from 'zod'; import { z } from 'zod';
@ -72,7 +72,7 @@ export const addWorkflowLoadRequestedListener = (startAppListening: AppStartList
} catch (e) { } catch (e) {
if (e instanceof WorkflowVersionError) { if (e instanceof WorkflowVersionError) {
// The workflow version was not recognized in the valid list of versions // The workflow version was not recognized in the valid list of versions
log.error({ error: parseify(e) }, e.message); log.error({ error: serializeError(e) }, e.message);
toast({ toast({
id: 'UNABLE_TO_VALIDATE_WORKFLOW', id: 'UNABLE_TO_VALIDATE_WORKFLOW',
title: t('nodes.unableToValidateWorkflow'), title: t('nodes.unableToValidateWorkflow'),
@ -81,7 +81,7 @@ export const addWorkflowLoadRequestedListener = (startAppListening: AppStartList
}); });
} else if (e instanceof WorkflowMigrationError) { } else if (e instanceof WorkflowMigrationError) {
// There was a problem migrating the workflow to the latest version // There was a problem migrating the workflow to the latest version
log.error({ error: parseify(e) }, e.message); log.error({ error: serializeError(e) }, e.message);
toast({ toast({
id: 'UNABLE_TO_VALIDATE_WORKFLOW', id: 'UNABLE_TO_VALIDATE_WORKFLOW',
title: t('nodes.unableToValidateWorkflow'), title: t('nodes.unableToValidateWorkflow'),
@ -93,7 +93,7 @@ export const addWorkflowLoadRequestedListener = (startAppListening: AppStartList
const { message } = fromZodError(e, { const { message } = fromZodError(e, {
prefix: t('nodes.workflowValidation'), prefix: t('nodes.workflowValidation'),
}); });
log.error({ error: parseify(e) }, message); log.error({ error: serializeError(e) }, message);
toast({ toast({
id: 'UNABLE_TO_VALIDATE_WORKFLOW', id: 'UNABLE_TO_VALIDATE_WORKFLOW',
title: t('nodes.unableToValidateWorkflow'), title: t('nodes.unableToValidateWorkflow'),
@ -102,7 +102,7 @@ export const addWorkflowLoadRequestedListener = (startAppListening: AppStartList
}); });
} else { } else {
// Some other error occurred // Some other error occurred
log.error({ error: parseify(e) }, t('nodes.unknownErrorValidatingWorkflow')); log.error({ error: serializeError(e) }, t('nodes.unknownErrorValidatingWorkflow'));
toast({ toast({
id: 'UNABLE_TO_VALIDATE_WORKFLOW', id: 'UNABLE_TO_VALIDATE_WORKFLOW',
title: t('nodes.unableToValidateWorkflow'), title: t('nodes.unableToValidateWorkflow'),

View File

@ -3,7 +3,7 @@ import { autoBatchEnhancer, combineReducers, configureStore } from '@reduxjs/too
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import { idbKeyValDriver } from 'app/store/enhancers/reduxRemember/driver'; import { idbKeyValDriver } from 'app/store/enhancers/reduxRemember/driver';
import { errorHandler } from 'app/store/enhancers/reduxRemember/errors'; import { errorHandler } from 'app/store/enhancers/reduxRemember/errors';
import type { JSONObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import { deepClone } from 'common/util/deepClone'; import { deepClone } from 'common/util/deepClone';
import { changeBoardModalSlice } from 'features/changeBoardModal/store/slice'; import { changeBoardModalSlice } from 'features/changeBoardModal/store/slice';
import { canvasV2PersistConfig, canvasV2Slice } from 'features/controlLayers/store/canvasV2Slice'; import { canvasV2PersistConfig, canvasV2Slice } from 'features/controlLayers/store/canvasV2Slice';
@ -124,7 +124,7 @@ const unserialize: UnserializeFunction = (data, key) => {
{ {
persistedData: parsed, persistedData: parsed,
rehydratedData: transformed, rehydratedData: transformed,
diff: diff(parsed, transformed) as JSONObject, // this is always serializable diff: diff(parsed, transformed) as SerializableObject, // this is always serializable
}, },
`Rehydrated slice "${key}"` `Rehydrated slice "${key}"`
); );

View File

@ -1,9 +1,3 @@
type JSONValue = string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue };
export interface JSONObject {
[k: string]: JSONValue;
}
type SerializableValue = string | number | boolean | null | undefined | SerializableValue[] | SerializableObject; type SerializableValue = string | number | boolean | null | undefined | SerializableValue[] | SerializableObject;
export type SerializableObject = { export type SerializableObject = {
[k: string | number]: SerializableValue; [k: string | number]: SerializableValue;

View File

@ -1,4 +1,4 @@
import type { JSONObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import { roundToMultiple, roundToMultipleMin } from 'common/util/roundDownToMultiple'; import { roundToMultiple, roundToMultipleMin } from 'common/util/roundDownToMultiple';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import type { CanvasPreviewModule } from 'features/controlLayers/konva/CanvasPreviewModule'; import type { CanvasPreviewModule } from 'features/controlLayers/konva/CanvasPreviewModule';
@ -254,7 +254,7 @@ export class CanvasBboxModule {
}); });
} }
getLoggingContext = (): JSONObject => { getLoggingContext = (): SerializableObject => {
return { ...this.manager.getLoggingContext(), path: this.path.join('.') }; return { ...this.manager.getLoggingContext(), path: this.path.join('.') };
}; };
} }

View File

@ -1,4 +1,4 @@
import type { JSONObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import { rgbaColorToString } from 'common/util/colorCodeTransformers'; import { rgbaColorToString } from 'common/util/colorCodeTransformers';
import { deepClone } from 'common/util/deepClone'; import { deepClone } from 'common/util/deepClone';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
@ -88,7 +88,7 @@ export class CanvasBrushLineRenderer {
}; };
} }
getLoggingContext = (): JSONObject => { getLoggingContext = (): SerializableObject => {
return { ...this.parent.getLoggingContext(), path: this.path.join('.') }; return { ...this.parent.getLoggingContext(), path: this.path.join('.') };
}; };
} }

View File

@ -1,4 +1,4 @@
import type { JSONObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import { deepClone } from 'common/util/deepClone'; import { deepClone } from 'common/util/deepClone';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import type { CanvasObjectRenderer } from 'features/controlLayers/konva/CanvasObjectRenderer'; import type { CanvasObjectRenderer } from 'features/controlLayers/konva/CanvasObjectRenderer';
@ -87,7 +87,7 @@ export class CanvasEraserLineRenderer {
}; };
} }
getLoggingContext = (): JSONObject => { getLoggingContext = (): SerializableObject => {
return { ...this.parent.getLoggingContext(), path: this.path.join('.') }; return { ...this.parent.getLoggingContext(), path: this.path.join('.') };
}; };
} }

View File

@ -1,4 +1,4 @@
import type { JSONObject, SerializableObject } from 'common/types'; import type { SerializableObject, SerializableObject } from 'common/types';
import type { CanvasLayerAdapter } from 'features/controlLayers/konva/CanvasLayerAdapter'; import type { CanvasLayerAdapter } from 'features/controlLayers/konva/CanvasLayerAdapter';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import { getPrefixedId } from 'features/controlLayers/konva/util'; import { getPrefixedId } from 'features/controlLayers/konva/util';
@ -175,7 +175,7 @@ export class CanvasFilterModule {
}; };
}; };
getLoggingContext = (): JSONObject => { getLoggingContext = (): SerializableObject => {
return { ...this.manager.getLoggingContext(), path: this.path.join('.') }; return { ...this.manager.getLoggingContext(), path: this.path.join('.') };
}; };
} }

View File

@ -1,5 +1,5 @@
import { Mutex } from 'async-mutex'; import { Mutex } from 'async-mutex';
import type { JSONObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import { deepClone } from 'common/util/deepClone'; import { deepClone } from 'common/util/deepClone';
import type { CanvasFilterModule } from 'features/controlLayers/konva/CanvasFilterModule'; import type { CanvasFilterModule } from 'features/controlLayers/konva/CanvasFilterModule';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
@ -186,7 +186,7 @@ export class CanvasImageRenderer {
}; };
}; };
getLoggingContext = (): JSONObject => { getLoggingContext = (): SerializableObject => {
return { ...this.parent.getLoggingContext(), path: this.path.join('.') }; return { ...this.parent.getLoggingContext(), path: this.path.join('.') };
}; };
} }

View File

@ -1,4 +1,4 @@
import type { JSONObject, SerializableObject } from 'common/types'; import type { SerializableObject, SerializableObject } from 'common/types';
import { deepClone } from 'common/util/deepClone'; import { deepClone } from 'common/util/deepClone';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import { CanvasObjectRenderer } from 'features/controlLayers/konva/CanvasObjectRenderer'; import { CanvasObjectRenderer } from 'features/controlLayers/konva/CanvasObjectRenderer';
@ -146,7 +146,7 @@ export class CanvasLayerAdapter {
}; };
}; };
getLoggingContext = (): JSONObject => { getLoggingContext = (): SerializableObject => {
return { ...this.manager.getLoggingContext(), path: this.path.join('.') }; return { ...this.manager.getLoggingContext(), path: this.path.join('.') };
}; };

View File

@ -1,4 +1,4 @@
import type { JSONObject, SerializableObject } from 'common/types'; import type { SerializableObject, SerializableObject } from 'common/types';
import { deepClone } from 'common/util/deepClone'; import { deepClone } from 'common/util/deepClone';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import { CanvasObjectRenderer } from 'features/controlLayers/konva/CanvasObjectRenderer'; import { CanvasObjectRenderer } from 'features/controlLayers/konva/CanvasObjectRenderer';
@ -165,7 +165,7 @@ export class CanvasMaskAdapter {
const canvas = this.renderer.getCanvas(rect, attrs); const canvas = this.renderer.getCanvas(rect, attrs);
return canvas; return canvas;
}; };
getLoggingContext = (): JSONObject => { getLoggingContext = (): SerializableObject => {
return { ...this.manager.getLoggingContext(), path: this.path.join('.') }; return { ...this.manager.getLoggingContext(), path: this.path.join('.') };
}; };
} }

View File

@ -1,4 +1,4 @@
import type { JSONObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import { rgbColorToString } from 'common/util/colorCodeTransformers'; import { rgbColorToString } from 'common/util/colorCodeTransformers';
import { CanvasBrushLineRenderer } from 'features/controlLayers/konva/CanvasBrushLine'; import { CanvasBrushLineRenderer } from 'features/controlLayers/konva/CanvasBrushLine';
import { CanvasEraserLineRenderer } from 'features/controlLayers/konva/CanvasEraserLine'; import { CanvasEraserLineRenderer } from 'features/controlLayers/konva/CanvasEraserLine';
@ -613,7 +613,7 @@ export class CanvasObjectRenderer {
}; };
}; };
getLoggingContext = (): JSONObject => { getLoggingContext = (): SerializableObject => {
return { ...this.parent.getLoggingContext(), path: this.path.join('.') }; return { ...this.parent.getLoggingContext(), path: this.path.join('.') };
}; };
} }

View File

@ -1,5 +1,5 @@
import { Mutex } from 'async-mutex'; import { Mutex } from 'async-mutex';
import type { JSONObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import type { CanvasPreviewModule } from 'features/controlLayers/konva/CanvasPreviewModule'; import type { CanvasPreviewModule } from 'features/controlLayers/konva/CanvasPreviewModule';
import { getPrefixedId, loadImage } from 'features/controlLayers/konva/util'; import { getPrefixedId, loadImage } from 'features/controlLayers/konva/util';
@ -113,7 +113,7 @@ export class CanvasProgressImageModule {
this.konva.group.destroy(); this.konva.group.destroy();
}; };
getLoggingContext = (): JSONObject => { getLoggingContext = (): SerializableObject => {
return { ...this.manager.getLoggingContext(), path: this.path.join('.') }; return { ...this.manager.getLoggingContext(), path: this.path.join('.') };
}; };
} }

View File

@ -1,4 +1,4 @@
import type { JSONObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import { rgbaColorToString } from 'common/util/colorCodeTransformers'; import { rgbaColorToString } from 'common/util/colorCodeTransformers';
import { deepClone } from 'common/util/deepClone'; import { deepClone } from 'common/util/deepClone';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
@ -80,7 +80,7 @@ export class CanvasRectRenderer {
}; };
} }
getLoggingContext = (): JSONObject => { getLoggingContext = (): SerializableObject => {
return { ...this.parent.getLoggingContext(), path: this.path.join('.') }; return { ...this.parent.getLoggingContext(), path: this.path.join('.') };
}; };
} }

View File

@ -1,4 +1,4 @@
import type { JSONObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import { CanvasImageRenderer } from 'features/controlLayers/konva/CanvasImage'; import { CanvasImageRenderer } from 'features/controlLayers/konva/CanvasImage';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import type { CanvasPreviewModule } from 'features/controlLayers/konva/CanvasPreviewModule'; import type { CanvasPreviewModule } from 'features/controlLayers/konva/CanvasPreviewModule';
@ -104,7 +104,7 @@ export class CanvasStagingAreaModule {
}; };
}; };
getLoggingContext = (): JSONObject => { getLoggingContext = (): SerializableObject => {
return { ...this.manager.getLoggingContext(), path: this.path.join('.') }; return { ...this.manager.getLoggingContext(), path: this.path.join('.') };
}; };
} }

View File

@ -1,4 +1,4 @@
import type { JSONObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import { rgbaColorToString } from 'common/util/colorCodeTransformers'; import { rgbaColorToString } from 'common/util/colorCodeTransformers';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import type { CanvasPreviewModule } from 'features/controlLayers/konva/CanvasPreviewModule'; import type { CanvasPreviewModule } from 'features/controlLayers/konva/CanvasPreviewModule';
@ -297,7 +297,7 @@ export class CanvasToolModule {
} }
} }
getLoggingContext = (): JSONObject => { getLoggingContext = (): SerializableObject => {
return { ...this.manager.getLoggingContext(), path: this.path.join('.') }; return { ...this.manager.getLoggingContext(), path: this.path.join('.') };
}; };
} }

View File

@ -1,4 +1,4 @@
import type { JSONObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import type { CanvasLayerAdapter } from 'features/controlLayers/konva/CanvasLayerAdapter'; import type { CanvasLayerAdapter } from 'features/controlLayers/konva/CanvasLayerAdapter';
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager'; import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
import type { CanvasMaskAdapter } from 'features/controlLayers/konva/CanvasMaskAdapter'; import type { CanvasMaskAdapter } from 'features/controlLayers/konva/CanvasMaskAdapter';
@ -161,9 +161,6 @@ export class CanvasTransformer {
context.fillStrokeShape(anchor); context.fillStrokeShape(anchor);
}); });
}, },
// TODO(psyche): The konva Vector2D type is is apparently not compatible with the JSONObject type that the log
// function expects. The in-house Coordinate type is functionally the same - `{x: number; y: number}` - and
// TypeScript is happy with it.
anchorDragBoundFunc: (oldPos: Coordinate, newPos: Coordinate) => { anchorDragBoundFunc: (oldPos: Coordinate, newPos: Coordinate) => {
// The anchorDragBoundFunc callback puts constraints on the movement of the transformer anchors, which in // The anchorDragBoundFunc callback puts constraints on the movement of the transformer anchors, which in
// turn constrain the transformation. It is called on every anchor move. We'll use this to snap the anchors // turn constrain the transformation. It is called on every anchor move. We'll use this to snap the anchors
@ -755,7 +752,7 @@ export class CanvasTransformer {
this.konva.proxyRect.destroy(); this.konva.proxyRect.destroy();
}; };
getLoggingContext = (): JSONObject => { getLoggingContext = (): SerializableObject => {
return { ...this.parent.getLoggingContext(), path: this.path.join('.') }; return { ...this.parent.getLoggingContext(), path: this.path.join('.') };
}; };
} }

View File

@ -2,7 +2,6 @@ import { MouseSensor, TouchSensor, useSensor, useSensors } from '@dnd-kit/core';
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import { dndDropped } from 'app/store/middleware/listenerMiddleware/listeners/imageDropped'; import { dndDropped } from 'app/store/middleware/listenerMiddleware/listeners/imageDropped';
import { useAppDispatch } from 'app/store/storeHooks'; import { useAppDispatch } from 'app/store/storeHooks';
import { parseify } from 'common/util/serialize';
import DndOverlay from 'features/dnd/components/DndOverlay'; import DndOverlay from 'features/dnd/components/DndOverlay';
import type { DragEndEvent, DragStartEvent, TypesafeDraggableData } from 'features/dnd/types'; import type { DragEndEvent, DragStartEvent, TypesafeDraggableData } from 'features/dnd/types';
import { customPointerWithin } from 'features/dnd/util/customPointerWithin'; import { customPointerWithin } from 'features/dnd/util/customPointerWithin';
@ -19,7 +18,7 @@ const AppDndContext = (props: PropsWithChildren) => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const handleDragStart = useCallback((event: DragStartEvent) => { const handleDragStart = useCallback((event: DragStartEvent) => {
log.trace({ dragData: parseify(event.active.data.current) }, 'Drag started'); log.trace({ dragData: event.active.data.current }, 'Drag started');
const activeData = event.active.data.current; const activeData = event.active.data.current;
if (!activeData) { if (!activeData) {
return; return;
@ -29,7 +28,7 @@ const AppDndContext = (props: PropsWithChildren) => {
const handleDragEnd = useCallback( const handleDragEnd = useCallback(
(event: DragEndEvent) => { (event: DragEndEvent) => {
log.trace({ dragData: parseify(event.active.data.current) }, 'Drag ended'); log.trace({ dragData: event.active.data.current }, 'Drag ended');
const overData = event.over?.data.current; const overData = event.over?.data.current;
if (!activeDragData || !overData) { if (!activeDragData || !overData) {
return; return;

View File

@ -1,4 +1,5 @@
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import type { SerializableObject } from 'common/types';
import { deepClone } from 'common/util/deepClone'; import { deepClone } from 'common/util/deepClone';
import { parseify } from 'common/util/serialize'; import { parseify } from 'common/util/serialize';
import type { Templates } from 'features/nodes/store/types'; import type { Templates } from 'features/nodes/store/types';
@ -87,7 +88,10 @@ export const parseSchema = (
schema.properties, schema.properties,
(inputsAccumulator: Record<string, FieldInputTemplate>, property, propertyName) => { (inputsAccumulator: Record<string, FieldInputTemplate>, property, propertyName) => {
if (isReservedInputField(type, propertyName)) { if (isReservedInputField(type, propertyName)) {
log.trace({ node: type, field: propertyName, schema: parseify(property) }, 'Skipped reserved input field'); log.trace(
{ node: type, field: propertyName, schema: property } as SerializableObject,
'Skipped reserved input field'
);
return inputsAccumulator; return inputsAccumulator;
} }

View File

@ -1,4 +1,4 @@
import type { JSONObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import { parseify } from 'common/util/serialize'; import { parseify } from 'common/util/serialize';
import type { Templates } from 'features/nodes/store/types'; import type { Templates } from 'features/nodes/store/types';
import { import {
@ -17,7 +17,7 @@ import { parseAndMigrateWorkflow } from './migrations';
type WorkflowWarning = { type WorkflowWarning = {
message: string; message: string;
issues?: string[]; issues?: string[];
data: JSONObject; data: SerializableObject;
}; };
type ValidateWorkflowResult = { type ValidateWorkflowResult = {

View File

@ -1,5 +1,5 @@
import { getStore } from 'app/store/nanostores/store'; import { getStore } from 'app/store/nanostores/store';
import type { JSONObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import type { BoardId } from 'features/gallery/store/types'; import type { BoardId } from 'features/gallery/store/types';
import { ASSETS_CATEGORIES, IMAGE_CATEGORIES } from 'features/gallery/store/types'; import { ASSETS_CATEGORIES, IMAGE_CATEGORIES } from 'features/gallery/store/types';
import type { components, paths } from 'services/api/schema'; import type { components, paths } from 'services/api/schema';
@ -75,7 +75,7 @@ export const imagesApi = api.injectEndpoints({
query: (image_name) => ({ url: buildImagesUrl(`i/${image_name}`) }), query: (image_name) => ({ url: buildImagesUrl(`i/${image_name}`) }),
providesTags: (result, error, image_name) => [{ type: 'Image', id: image_name }], providesTags: (result, error, image_name) => [{ type: 'Image', id: image_name }],
}), }),
getImageMetadata: build.query<JSONObject | undefined, string>({ getImageMetadata: build.query<SerializableObject | undefined, string>({
query: (image_name) => ({ url: buildImagesUrl(`i/${image_name}/metadata`) }), query: (image_name) => ({ url: buildImagesUrl(`i/${image_name}/metadata`) }),
providesTags: (result, error, image_name) => [{ type: 'ImageMetadata', id: image_name }], providesTags: (result, error, image_name) => [{ type: 'ImageMetadata', id: image_name }],
}), }),
@ -270,7 +270,7 @@ export const imagesApi = api.injectEndpoints({
session_id?: string; session_id?: string;
board_id?: string; board_id?: string;
crop_visible?: boolean; crop_visible?: boolean;
metadata?: JSONObject; metadata?: SerializableObject;
} }
>({ >({
query: ({ file, image_category, is_intermediate, session_id, board_id, crop_visible, metadata }) => { query: ({ file, image_category, is_intermediate, session_id, board_id, crop_visible, metadata }) => {