feat(ui): logging cleanup

- simplify access to app logger
- spruce up and make consistent log format
- improve messaging
This commit is contained in:
psychedelicious 2023-07-22 21:03:56 +10:00
parent 907ff165be
commit 75863e7181
65 changed files with 480 additions and 573 deletions

View File

@ -69,6 +69,7 @@
"@mantine/core": "^6.0.14", "@mantine/core": "^6.0.14",
"@mantine/form": "^6.0.15", "@mantine/form": "^6.0.15",
"@mantine/hooks": "^6.0.14", "@mantine/hooks": "^6.0.14",
"@nanostores/react": "^0.7.1",
"@reduxjs/toolkit": "^1.9.5", "@reduxjs/toolkit": "^1.9.5",
"@roarr/browser-log-writer": "^1.1.5", "@roarr/browser-log-writer": "^1.1.5",
"chakra-ui-contextmenu": "^1.0.5", "chakra-ui-contextmenu": "^1.0.5",

View File

@ -14,6 +14,7 @@ import FloatingParametersPanelButtons from 'features/ui/components/FloatingParam
import InvokeTabs from 'features/ui/components/InvokeTabs'; import InvokeTabs from 'features/ui/components/InvokeTabs';
import ParametersDrawer from 'features/ui/components/ParametersDrawer'; import ParametersDrawer from 'features/ui/components/ParametersDrawer';
import i18n from 'i18n'; import i18n from 'i18n';
import { size } from 'lodash-es';
import { ReactNode, memo, useEffect } from 'react'; import { ReactNode, memo, useEffect } from 'react';
import UpdateImageBoardModal from '../../features/gallery/components/Boards/UpdateImageBoardModal'; import UpdateImageBoardModal from '../../features/gallery/components/Boards/UpdateImageBoardModal';
import GlobalHotkeys from './GlobalHotkeys'; import GlobalHotkeys from './GlobalHotkeys';
@ -29,8 +30,7 @@ interface Props {
const App = ({ config = DEFAULT_CONFIG, headerComponent }: Props) => { const App = ({ config = DEFAULT_CONFIG, headerComponent }: Props) => {
const language = useAppSelector(languageSelector); const language = useAppSelector(languageSelector);
const log = useLogger(); const logger = useLogger();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
useEffect(() => { useEffect(() => {
@ -38,9 +38,11 @@ const App = ({ config = DEFAULT_CONFIG, headerComponent }: Props) => {
}, [language]); }, [language]);
useEffect(() => { useEffect(() => {
log.info({ namespace: 'App', data: config }, 'Received config'); if (size(config)) {
dispatch(configChanged(config)); logger.info({ namespace: 'App', config }, 'Received config');
}, [dispatch, config, log]); dispatch(configChanged(config));
}
}, [dispatch, config, logger]);
useEffect(() => { useEffect(() => {
dispatch(appStarted()); dispatch(appStarted());

View File

@ -0,0 +1,46 @@
import { createLogWriter } from '@roarr/browser-log-writer';
import { atom } from 'nanostores';
import { Logger, ROARR, Roarr } from 'roarr';
ROARR.write = createLogWriter();
export const BASE_CONTEXT = {};
export const log = Roarr.child(BASE_CONTEXT);
export const $logger = atom<Logger>(Roarr.child(BASE_CONTEXT));
type LoggerNamespace =
| 'images'
| 'models'
| 'config'
| 'canvas'
| 'txt2img'
| 'img2img'
| 'nodes'
| 'system'
| 'socketio'
| 'session';
export const logger = (namespace: LoggerNamespace) =>
$logger.get().child({ namespace });
export const VALID_LOG_LEVELS = [
'trace',
'debug',
'info',
'warn',
'error',
'fatal',
] as const;
export type InvokeLogLevel = (typeof VALID_LOG_LEVELS)[number];
// Translate human-readable log levels to numbers, used for log filtering
export const LOG_LEVEL_MAP: Record<InvokeLogLevel, number> = {
trace: 10,
debug: 20,
info: 30,
warn: 40,
error: 50,
fatal: 60,
};

View File

@ -1,48 +1,19 @@
import { useStore } from '@nanostores/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { createLogWriter } from '@roarr/browser-log-writer';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import { systemSelector } from 'features/system/store/systemSelectors'; import { systemSelector } from 'features/system/store/systemSelectors';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { LogLevelName, ROARR, Roarr } from 'roarr'; import { ROARR, Roarr } from 'roarr';
import { createLogWriter } from '@roarr/browser-log-writer'; import { $logger, BASE_CONTEXT, LOG_LEVEL_MAP } from './logger';
// Base logging context includes only the package name
const baseContext = { package: '@invoke-ai/invoke-ai-ui' };
// Create browser log writer
ROARR.write = createLogWriter();
// Module-scoped logger - can be imported and used anywhere
export let log = Roarr.child(baseContext);
// Translate human-readable log levels to numbers, used for log filtering
export const LOG_LEVEL_MAP: Record<LogLevelName, number> = {
trace: 10,
debug: 20,
info: 30,
warn: 40,
error: 50,
fatal: 60,
};
export const VALID_LOG_LEVELS = [
'trace',
'debug',
'info',
'warn',
'error',
'fatal',
] as const;
export type InvokeLogLevel = (typeof VALID_LOG_LEVELS)[number];
const selector = createSelector( const selector = createSelector(
systemSelector, systemSelector,
(system) => { (system) => {
const { app_version, consoleLogLevel, shouldLogToConsole } = system; const { consoleLogLevel, shouldLogToConsole } = system;
return { return {
version: app_version,
consoleLogLevel, consoleLogLevel,
shouldLogToConsole, shouldLogToConsole,
}; };
@ -55,8 +26,7 @@ const selector = createSelector(
); );
export const useLogger = () => { export const useLogger = () => {
const { version, consoleLogLevel, shouldLogToConsole } = const { consoleLogLevel, shouldLogToConsole } = useAppSelector(selector);
useAppSelector(selector);
// The provided Roarr browser log writer uses localStorage to config logging to console // The provided Roarr browser log writer uses localStorage to config logging to console
useEffect(() => { useEffect(() => {
@ -79,16 +49,13 @@ export const useLogger = () => {
// Update the module-scoped logger context as needed // Update the module-scoped logger context as needed
useEffect(() => { useEffect(() => {
const newContext: Record<string, any> = { const newContext: Record<string, any> = {
...baseContext, ...BASE_CONTEXT,
}; };
if (version) { $logger.set(Roarr.child(newContext));
newContext.version = version; }, []);
}
log = Roarr.child(newContext); const logger = useStore($logger);
}, [version]);
// Use the logger within components - no different than just importing it directly return logger;
return log;
}; };

View File

@ -8,10 +8,11 @@ import {
import type { AppDispatch, RootState } from '../../store'; import type { AppDispatch, RootState } from '../../store';
import { addCommitStagingAreaImageListener } from './listeners/addCommitStagingAreaImageListener'; import { addCommitStagingAreaImageListener } from './listeners/addCommitStagingAreaImageListener';
import { addFirstListImagesListener } from './listeners/addFirstListImagesListener.ts';
import { addAppConfigReceivedListener } from './listeners/appConfigReceived'; import { addAppConfigReceivedListener } from './listeners/appConfigReceived';
import { addAppStartedListener } from './listeners/appStarted'; import { addAppStartedListener } from './listeners/appStarted';
import { addBoardIdSelectedListener } from './listeners/boardIdSelected';
import { addDeleteBoardAndImagesFulfilledListener } from './listeners/boardAndImagesDeleted'; import { addDeleteBoardAndImagesFulfilledListener } from './listeners/boardAndImagesDeleted';
import { addBoardIdSelectedListener } from './listeners/boardIdSelected';
import { addCanvasCopiedToClipboardListener } from './listeners/canvasCopiedToClipboard'; import { addCanvasCopiedToClipboardListener } from './listeners/canvasCopiedToClipboard';
import { addCanvasDownloadedAsImageListener } from './listeners/canvasDownloadedAsImage'; import { addCanvasDownloadedAsImageListener } from './listeners/canvasDownloadedAsImage';
import { addCanvasMergedListener } from './listeners/canvasMerged'; import { addCanvasMergedListener } from './listeners/canvasMerged';
@ -34,10 +35,6 @@ import {
addImageRemovedFromBoardRejectedListener, addImageRemovedFromBoardRejectedListener,
} from './listeners/imageRemovedFromBoard'; } from './listeners/imageRemovedFromBoard';
import { addImageToDeleteSelectedListener } from './listeners/imageToDeleteSelected'; import { addImageToDeleteSelectedListener } from './listeners/imageToDeleteSelected';
import {
addImageUpdatedFulfilledListener,
addImageUpdatedRejectedListener,
} from './listeners/imageUpdated';
import { import {
addImageUploadedFulfilledListener, addImageUploadedFulfilledListener,
addImageUploadedRejectedListener, addImageUploadedRejectedListener,
@ -69,17 +66,15 @@ import { addGraphExecutionStateCompleteEventListener as addGraphExecutionStateCo
import { addInvocationCompleteEventListener as addInvocationCompleteListener } from './listeners/socketio/socketInvocationComplete'; import { addInvocationCompleteEventListener as addInvocationCompleteListener } from './listeners/socketio/socketInvocationComplete';
import { addInvocationErrorEventListener as addInvocationErrorListener } from './listeners/socketio/socketInvocationError'; import { addInvocationErrorEventListener as addInvocationErrorListener } from './listeners/socketio/socketInvocationError';
import { addInvocationStartedEventListener as addInvocationStartedListener } from './listeners/socketio/socketInvocationStarted'; import { addInvocationStartedEventListener as addInvocationStartedListener } from './listeners/socketio/socketInvocationStarted';
import { addModelLoadEventListener } from './listeners/socketio/socketModelLoad';
import { addSocketSubscribedEventListener as addSocketSubscribedListener } from './listeners/socketio/socketSubscribed'; import { addSocketSubscribedEventListener as addSocketSubscribedListener } from './listeners/socketio/socketSubscribed';
import { addSocketUnsubscribedEventListener as addSocketUnsubscribedListener } from './listeners/socketio/socketUnsubscribed'; import { addSocketUnsubscribedEventListener as addSocketUnsubscribedListener } from './listeners/socketio/socketUnsubscribed';
import { addStagingAreaImageSavedListener } from './listeners/stagingAreaImageSaved'; import { addStagingAreaImageSavedListener } from './listeners/stagingAreaImageSaved';
import { addUpscaleRequestedListener } from './listeners/upscaleRequested';
import { addUserInvokedCanvasListener } from './listeners/userInvokedCanvas'; import { addUserInvokedCanvasListener } from './listeners/userInvokedCanvas';
import { addUserInvokedImageToImageListener } from './listeners/userInvokedImageToImage'; import { addUserInvokedImageToImageListener } from './listeners/userInvokedImageToImage';
import { addUserInvokedNodesListener } from './listeners/userInvokedNodes'; import { addUserInvokedNodesListener } from './listeners/userInvokedNodes';
import { addUserInvokedTextToImageListener } from './listeners/userInvokedTextToImage'; import { addUserInvokedTextToImageListener } from './listeners/userInvokedTextToImage';
import { addModelLoadStartedEventListener } from './listeners/socketio/socketModelLoadStarted';
import { addModelLoadCompletedEventListener } from './listeners/socketio/socketModelLoadCompleted';
import { addUpscaleRequestedListener } from './listeners/upscaleRequested';
import { addFirstListImagesListener } from './listeners/addFirstListImagesListener.ts';
export const listenerMiddleware = createListenerMiddleware(); export const listenerMiddleware = createListenerMiddleware();
@ -109,10 +104,6 @@ export type AppListenerEffect = ListenerEffect<
addImageUploadedFulfilledListener(); addImageUploadedFulfilledListener();
addImageUploadedRejectedListener(); addImageUploadedRejectedListener();
// Image updated
addImageUpdatedFulfilledListener();
addImageUpdatedRejectedListener();
// Image selected // Image selected
addInitialImageSelectedListener(); addInitialImageSelectedListener();
@ -161,8 +152,7 @@ addSocketConnectedListener();
addSocketDisconnectedListener(); addSocketDisconnectedListener();
addSocketSubscribedListener(); addSocketSubscribedListener();
addSocketUnsubscribedListener(); addSocketUnsubscribedListener();
addModelLoadStartedEventListener(); addModelLoadEventListener();
addModelLoadCompletedEventListener();
// Session Created // Session Created
addSessionCreatedPendingListener(); addSessionCreatedPendingListener();

View File

@ -1,14 +1,13 @@
import { startAppListening } from '..'; import { logger } from 'app/logging/logger';
import { log } from 'app/logging/useLogger';
import { commitStagingAreaImage } from 'features/canvas/store/canvasSlice'; import { commitStagingAreaImage } from 'features/canvas/store/canvasSlice';
import { sessionCanceled } from 'services/api/thunks/session'; import { sessionCanceled } from 'services/api/thunks/session';
import { startAppListening } from '..';
const moduleLog = log.child({ namespace: 'canvas' });
export const addCommitStagingAreaImageListener = () => { export const addCommitStagingAreaImageListener = () => {
startAppListening({ startAppListening({
actionCreator: commitStagingAreaImage, actionCreator: commitStagingAreaImage,
effect: async (action, { dispatch, getState }) => { effect: async (action, { dispatch, getState }) => {
const log = logger('canvas');
const state = getState(); const state = getState();
const { sessionId: session_id, isProcessing } = state.system; const { sessionId: session_id, isProcessing } = state.system;
const canvasSessionId = action.payload; const canvasSessionId = action.payload;
@ -19,17 +18,15 @@ export const addCommitStagingAreaImageListener = () => {
} }
if (!canvasSessionId) { if (!canvasSessionId) {
moduleLog.debug('No canvas session, skipping cancel'); log.debug('No canvas session, skipping cancel');
return; return;
} }
if (canvasSessionId !== session_id) { if (canvasSessionId !== session_id) {
moduleLog.debug( log.debug(
{ {
data: { canvasSessionId,
canvasSessionId, session_id,
session_id,
},
}, },
'Canvas session does not match global session, skipping cancel' 'Canvas session does not match global session, skipping cancel'
); );

View File

@ -1,4 +1,4 @@
import { log } from 'app/logging/useLogger'; import { isAnyOf } from '@reduxjs/toolkit';
import { import {
ASSETS_CATEGORIES, ASSETS_CATEGORIES,
IMAGE_CATEGORIES, IMAGE_CATEGORIES,
@ -8,9 +8,6 @@ import {
} from 'features/gallery/store/gallerySlice'; } from 'features/gallery/store/gallerySlice';
import { imagesApi } from 'services/api/endpoints/images'; import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..'; import { startAppListening } from '..';
import { isAnyOf } from '@reduxjs/toolkit';
const moduleLog = log.child({ namespace: 'boards' });
export const addBoardIdSelectedListener = () => { export const addBoardIdSelectedListener = () => {
startAppListening({ startAppListening({

View File

@ -1,16 +1,17 @@
import { canvasCopiedToClipboard } from 'features/canvas/store/actions'; import { canvasCopiedToClipboard } from 'features/canvas/store/actions';
import { startAppListening } from '..'; import { startAppListening } from '..';
import { log } from 'app/logging/useLogger'; import { $logger } from 'app/logging/logger';
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob'; import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
import { addToast } from 'features/system/store/systemSlice'; import { addToast } from 'features/system/store/systemSlice';
import { copyBlobToClipboard } from 'features/canvas/util/copyBlobToClipboard'; import { copyBlobToClipboard } from 'features/canvas/util/copyBlobToClipboard';
const moduleLog = log.child({ namespace: 'canvasCopiedToClipboardListener' });
export const addCanvasCopiedToClipboardListener = () => { export const addCanvasCopiedToClipboardListener = () => {
startAppListening({ startAppListening({
actionCreator: canvasCopiedToClipboard, actionCreator: canvasCopiedToClipboard,
effect: async (action, { dispatch, getState }) => { effect: async (action, { dispatch, getState }) => {
const moduleLog = $logger
.get()
.child({ namespace: 'canvasCopiedToClipboardListener' });
const state = getState(); const state = getState();
const blob = await getBaseLayerBlob(state); const blob = await getBaseLayerBlob(state);

View File

@ -1,16 +1,17 @@
import { canvasDownloadedAsImage } from 'features/canvas/store/actions'; import { canvasDownloadedAsImage } from 'features/canvas/store/actions';
import { startAppListening } from '..'; import { startAppListening } from '..';
import { log } from 'app/logging/useLogger'; import { $logger } from 'app/logging/logger';
import { downloadBlob } from 'features/canvas/util/downloadBlob'; import { downloadBlob } from 'features/canvas/util/downloadBlob';
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob'; import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
import { addToast } from 'features/system/store/systemSlice'; import { addToast } from 'features/system/store/systemSlice';
const moduleLog = log.child({ namespace: 'canvasSavedToGalleryListener' });
export const addCanvasDownloadedAsImageListener = () => { export const addCanvasDownloadedAsImageListener = () => {
startAppListening({ startAppListening({
actionCreator: canvasDownloadedAsImage, actionCreator: canvasDownloadedAsImage,
effect: async (action, { dispatch, getState }) => { effect: async (action, { dispatch, getState }) => {
const moduleLog = $logger
.get()
.child({ namespace: 'canvasSavedToGalleryListener' });
const state = getState(); const state = getState();
const blob = await getBaseLayerBlob(state); const blob = await getBaseLayerBlob(state);

View File

@ -1,4 +1,4 @@
import { log } from 'app/logging/useLogger'; import { $logger } from 'app/logging/logger';
import { canvasMerged } from 'features/canvas/store/actions'; import { canvasMerged } from 'features/canvas/store/actions';
import { setMergedCanvas } from 'features/canvas/store/canvasSlice'; import { setMergedCanvas } from 'features/canvas/store/canvasSlice';
import { getFullBaseLayerBlob } from 'features/canvas/util/getFullBaseLayerBlob'; import { getFullBaseLayerBlob } from 'features/canvas/util/getFullBaseLayerBlob';
@ -7,12 +7,13 @@ import { addToast } from 'features/system/store/systemSlice';
import { imagesApi } from 'services/api/endpoints/images'; import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..'; import { startAppListening } from '..';
const moduleLog = log.child({ namespace: 'canvasCopiedToClipboardListener' });
export const addCanvasMergedListener = () => { export const addCanvasMergedListener = () => {
startAppListening({ startAppListening({
actionCreator: canvasMerged, actionCreator: canvasMerged,
effect: async (action, { dispatch, getState, take }) => { effect: async (action, { dispatch, getState, take }) => {
const moduleLog = $logger
.get()
.child({ namespace: 'canvasCopiedToClipboardListener' });
const blob = await getFullBaseLayerBlob(); const blob = await getFullBaseLayerBlob();
if (!blob) { if (!blob) {

View File

@ -1,22 +1,21 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { canvasSavedToGallery } from 'features/canvas/store/actions'; import { canvasSavedToGallery } from 'features/canvas/store/actions';
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob'; import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
import { addToast } from 'features/system/store/systemSlice'; import { addToast } from 'features/system/store/systemSlice';
import { imagesApi } from 'services/api/endpoints/images'; import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..'; import { startAppListening } from '..';
const moduleLog = log.child({ namespace: 'canvasSavedToGalleryListener' });
export const addCanvasSavedToGalleryListener = () => { export const addCanvasSavedToGalleryListener = () => {
startAppListening({ startAppListening({
actionCreator: canvasSavedToGallery, actionCreator: canvasSavedToGallery,
effect: async (action, { dispatch, getState, take }) => { effect: async (action, { dispatch, getState, take }) => {
const log = logger('canvas');
const state = getState(); const state = getState();
const blob = await getBaseLayerBlob(state); const blob = await getBaseLayerBlob(state);
if (!blob) { if (!blob) {
moduleLog.error('Problem getting base layer blob'); log.error('Problem getting base layer blob');
dispatch( dispatch(
addToast({ addToast({
title: 'Problem Saving Canvas', title: 'Problem Saving Canvas',

View File

@ -1,6 +1,6 @@
import { AnyListenerPredicate } from '@reduxjs/toolkit'; import { AnyListenerPredicate } from '@reduxjs/toolkit';
import { startAppListening } from '..'; import { logger } from 'app/logging/logger';
import { log } from 'app/logging/useLogger'; import { RootState } from 'app/store/store';
import { controlNetImageProcessed } from 'features/controlNet/store/actions'; import { controlNetImageProcessed } from 'features/controlNet/store/actions';
import { import {
controlNetAutoConfigToggled, controlNetAutoConfigToggled,
@ -9,9 +9,7 @@ import {
controlNetProcessorParamsChanged, controlNetProcessorParamsChanged,
controlNetProcessorTypeChanged, controlNetProcessorTypeChanged,
} from 'features/controlNet/store/controlNetSlice'; } from 'features/controlNet/store/controlNetSlice';
import { RootState } from 'app/store/store'; import { startAppListening } from '..';
const moduleLog = log.child({ namespace: 'controlNet' });
const predicate: AnyListenerPredicate<RootState> = ( const predicate: AnyListenerPredicate<RootState> = (
action, action,
@ -68,14 +66,12 @@ export const addControlNetAutoProcessListener = () => {
action, action,
{ dispatch, getState, cancelActiveListeners, delay } { dispatch, getState, cancelActiveListeners, delay }
) => { ) => {
const log = logger('session');
const { controlNetId } = action.payload; const { controlNetId } = action.payload;
// Cancel any in-progress instances of this listener // Cancel any in-progress instances of this listener
cancelActiveListeners(); cancelActiveListeners();
moduleLog.trace( log.trace('ControlNet auto-process triggered');
{ data: action.payload },
'ControlNet auto-process triggered'
);
// Delay before starting actual work // Delay before starting actual work
await delay(300); await delay(300);

View File

@ -1,4 +1,4 @@
import { log } from 'app/logging/useLogger'; import { $logger, logger } from 'app/logging/logger';
import { controlNetImageProcessed } from 'features/controlNet/store/actions'; import { controlNetImageProcessed } from 'features/controlNet/store/actions';
import { controlNetProcessedImageChanged } from 'features/controlNet/store/controlNetSlice'; import { controlNetProcessedImageChanged } from 'features/controlNet/store/controlNetSlice';
import { sessionReadyToInvoke } from 'features/system/store/actions'; import { sessionReadyToInvoke } from 'features/system/store/actions';
@ -9,8 +9,6 @@ import { Graph, ImageDTO } from 'services/api/types';
import { socketInvocationComplete } from 'services/events/actions'; import { socketInvocationComplete } from 'services/events/actions';
import { startAppListening } from '..'; import { startAppListening } from '..';
const moduleLog = log.child({ namespace: 'controlNet' });
export const addControlNetImageProcessedListener = () => { export const addControlNetImageProcessedListener = () => {
startAppListening({ startAppListening({
actionCreator: controlNetImageProcessed, actionCreator: controlNetImageProcessed,
@ -18,11 +16,12 @@ export const addControlNetImageProcessedListener = () => {
action, action,
{ dispatch, getState, take, unsubscribe, subscribe } { dispatch, getState, take, unsubscribe, subscribe }
) => { ) => {
const log = logger('session');
const { controlNetId } = action.payload; const { controlNetId } = action.payload;
const controlNet = getState().controlNet.controlNets[controlNetId]; const controlNet = getState().controlNet.controlNets[controlNetId];
if (!controlNet.controlImage) { if (!controlNet.controlImage) {
moduleLog.error('Unable to process ControlNet image'); log.error('Unable to process ControlNet image');
return; return;
} }
@ -70,8 +69,8 @@ export const addControlNetImageProcessedListener = () => {
const processedControlImage = payload as ImageDTO; const processedControlImage = payload as ImageDTO;
moduleLog.debug( log.debug(
{ data: { arg: action.payload, processedControlImage } }, { controlNetId: action.payload, processedControlImage },
'ControlNet image processed' 'ControlNet image processed'
); );

View File

@ -1,18 +1,17 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { imagesApi } from 'services/api/endpoints/images'; import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..'; import { startAppListening } from '..';
const moduleLog = log.child({ namespace: 'boards' });
export const addImageAddedToBoardFulfilledListener = () => { export const addImageAddedToBoardFulfilledListener = () => {
startAppListening({ startAppListening({
matcher: imagesApi.endpoints.addImageToBoard.matchFulfilled, matcher: imagesApi.endpoints.addImageToBoard.matchFulfilled,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const log = logger('images');
const { board_id, imageDTO } = action.meta.arg.originalArgs; const { board_id, imageDTO } = action.meta.arg.originalArgs;
// TODO: update listImages cache for this board // TODO: update listImages cache for this board
moduleLog.debug({ data: { board_id, imageDTO } }, 'Image added to board'); log.debug({ board_id, imageDTO }, 'Image added to board');
}, },
}); });
}; };
@ -21,12 +20,10 @@ export const addImageAddedToBoardRejectedListener = () => {
startAppListening({ startAppListening({
matcher: imagesApi.endpoints.addImageToBoard.matchRejected, matcher: imagesApi.endpoints.addImageToBoard.matchRejected,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const log = logger('images');
const { board_id, imageDTO } = action.meta.arg.originalArgs; const { board_id, imageDTO } = action.meta.arg.originalArgs;
moduleLog.debug( log.debug({ board_id, imageDTO }, 'Problem adding image to board');
{ data: { board_id, imageDTO } },
'Problem adding image to board'
);
}, },
}); });
}; };

View File

@ -1,4 +1,4 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { resetCanvas } from 'features/canvas/store/canvasSlice'; import { resetCanvas } from 'features/canvas/store/canvasSlice';
import { controlNetReset } from 'features/controlNet/store/controlNetSlice'; import { controlNetReset } from 'features/controlNet/store/controlNetSlice';
import { selectListImagesBaseQueryArgs } from 'features/gallery/store/gallerySelectors'; import { selectListImagesBaseQueryArgs } from 'features/gallery/store/gallerySelectors';
@ -14,8 +14,6 @@ import { api } from 'services/api';
import { imagesApi } from 'services/api/endpoints/images'; import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..'; import { startAppListening } from '..';
const moduleLog = log.child({ namespace: 'image' });
/** /**
* Called when the user requests an image deletion * Called when the user requests an image deletion
*/ */
@ -23,6 +21,7 @@ export const addRequestedImageDeletionListener = () => {
startAppListening({ startAppListening({
actionCreator: imageDeletionConfirmed, actionCreator: imageDeletionConfirmed,
effect: async (action, { dispatch, getState, condition }) => { effect: async (action, { dispatch, getState, condition }) => {
const log = logger('images');
const { imageDTO, imageUsage } = action.payload; const { imageDTO, imageUsage } = action.payload;
dispatch(isModalOpenChanged(false)); dispatch(isModalOpenChanged(false));
@ -108,6 +107,7 @@ export const addImageDeletedPendingListener = () => {
startAppListening({ startAppListening({
matcher: imagesApi.endpoints.deleteImage.matchPending, matcher: imagesApi.endpoints.deleteImage.matchPending,
effect: (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
const log = logger('images');
// //
}, },
}); });
@ -120,10 +120,8 @@ export const addImageDeletedFulfilledListener = () => {
startAppListening({ startAppListening({
matcher: imagesApi.endpoints.deleteImage.matchFulfilled, matcher: imagesApi.endpoints.deleteImage.matchFulfilled,
effect: (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
moduleLog.debug( const log = logger('images');
{ data: { image: action.meta.arg.originalArgs } }, log.debug({ imageDTO: action.meta.arg.originalArgs }, 'Image deleted');
'Image deleted'
);
}, },
}); });
}; };
@ -135,8 +133,9 @@ export const addImageDeletedRejectedListener = () => {
startAppListening({ startAppListening({
matcher: imagesApi.endpoints.deleteImage.matchRejected, matcher: imagesApi.endpoints.deleteImage.matchRejected,
effect: (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
moduleLog.debug( const log = logger('images');
{ data: { image: action.meta.arg.originalArgs } }, log.debug(
{ imageDTO: action.meta.arg.originalArgs },
'Unable to delete image' 'Unable to delete image'
); );
}, },

View File

@ -3,7 +3,7 @@ import {
TypesafeDraggableData, TypesafeDraggableData,
TypesafeDroppableData, TypesafeDroppableData,
} from 'app/components/ImageDnd/typesafeDnd'; } from 'app/components/ImageDnd/typesafeDnd';
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice'; import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
import { controlNetImageChanged } from 'features/controlNet/store/controlNetSlice'; import { controlNetImageChanged } from 'features/controlNet/store/controlNetSlice';
import { import {
@ -15,8 +15,6 @@ import { initialImageChanged } from 'features/parameters/store/generationSlice';
import { imagesApi } from 'services/api/endpoints/images'; import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '../'; import { startAppListening } from '../';
const moduleLog = log.child({ namespace: 'dnd' });
export const dndDropped = createAction<{ export const dndDropped = createAction<{
overData: TypesafeDroppableData; overData: TypesafeDroppableData;
activeData: TypesafeDraggableData; activeData: TypesafeDraggableData;
@ -26,13 +24,10 @@ export const addImageDroppedListener = () => {
startAppListening({ startAppListening({
actionCreator: dndDropped, actionCreator: dndDropped,
effect: async (action, { dispatch, getState, take }) => { effect: async (action, { dispatch, getState, take }) => {
const log = logger('images');
const { activeData, overData } = action.payload; const { activeData, overData } = action.payload;
const state = getState();
moduleLog.debug( log.debug({ activeData, overData }, 'Image or selection dropped');
{ data: { activeData, overData } },
'Image or selection dropped'
);
// set current image // set current image
if ( if (

View File

@ -1,19 +1,15 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { imagesApi } from 'services/api/endpoints/images'; import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..'; import { startAppListening } from '..';
const moduleLog = log.child({ namespace: 'boards' });
export const addImageRemovedFromBoardFulfilledListener = () => { export const addImageRemovedFromBoardFulfilledListener = () => {
startAppListening({ startAppListening({
matcher: imagesApi.endpoints.removeImageFromBoard.matchFulfilled, matcher: imagesApi.endpoints.removeImageFromBoard.matchFulfilled,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const { board_id, image_name } = action.meta.arg.originalArgs; const log = logger('images');
const imageDTO = action.meta.arg.originalArgs;
moduleLog.debug( log.debug({ imageDTO }, 'Image removed from board');
{ data: { board_id, image_name } },
'Image added to board'
);
}, },
}); });
}; };
@ -22,12 +18,10 @@ export const addImageRemovedFromBoardRejectedListener = () => {
startAppListening({ startAppListening({
matcher: imagesApi.endpoints.removeImageFromBoard.matchRejected, matcher: imagesApi.endpoints.removeImageFromBoard.matchRejected,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const { board_id, image_name } = action.meta.arg.originalArgs; const log = logger('images');
const imageDTO = action.meta.arg.originalArgs;
moduleLog.debug( log.debug({ imageDTO }, 'Problem removing image from board');
{ data: { board_id, image_name } },
'Problem adding image to board'
);
}, },
}); });
}; };

View File

@ -1,13 +1,10 @@
import { startAppListening } from '..';
import { log } from 'app/logging/useLogger';
import { import {
imageDeletionConfirmed, imageDeletionConfirmed,
imageToDeleteSelected, imageToDeleteSelected,
isModalOpenChanged, isModalOpenChanged,
selectImageUsage, selectImageUsage,
} from 'features/imageDeletion/store/imageDeletionSlice'; } from 'features/imageDeletion/store/imageDeletionSlice';
import { startAppListening } from '..';
const moduleLog = log.child({ namespace: 'image' });
export const addImageToDeleteSelectedListener = () => { export const addImageToDeleteSelectedListener = () => {
startAppListening({ startAppListening({

View File

@ -1,34 +0,0 @@
import { log } from 'app/logging/useLogger';
import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..';
const moduleLog = log.child({ namespace: 'image' });
export const addImageUpdatedFulfilledListener = () => {
// startAppListening({
// matcher: imagesApi.endpoints.updateImage.matchFulfilled,
// effect: (action, { dispatch, getState }) => {
// moduleLog.debug(
// {
// data: {
// oldImage: action.meta.arg.originalArgs,
// updatedImage: action.payload,
// },
// },
// 'Image updated'
// );
// },
// });
};
export const addImageUpdatedRejectedListener = () => {
// startAppListening({
// matcher: imagesApi.endpoints.updateImage.matchRejected,
// effect: (action, { dispatch }) => {
// moduleLog.debug(
// { data: action.meta.arg.originalArgs },
// 'Image update failed'
// );
// },
// });
};

View File

@ -1,5 +1,5 @@
import { UseToastOptions } from '@chakra-ui/react'; import { UseToastOptions } from '@chakra-ui/react';
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice'; import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
import { controlNetImageChanged } from 'features/controlNet/store/controlNetSlice'; import { controlNetImageChanged } from 'features/controlNet/store/controlNetSlice';
import { imagesAddedToBatch } from 'features/gallery/store/gallerySlice'; import { imagesAddedToBatch } from 'features/gallery/store/gallerySlice';
@ -10,8 +10,6 @@ import { boardsApi } from 'services/api/endpoints/boards';
import { startAppListening } from '..'; import { startAppListening } from '..';
import { imagesApi } from '../../../../../services/api/endpoints/images'; import { imagesApi } from '../../../../../services/api/endpoints/images';
const moduleLog = log.child({ namespace: 'image' });
const DEFAULT_UPLOADED_TOAST: UseToastOptions = { const DEFAULT_UPLOADED_TOAST: UseToastOptions = {
title: 'Image Uploaded', title: 'Image Uploaded',
status: 'success', status: 'success',
@ -21,11 +19,12 @@ export const addImageUploadedFulfilledListener = () => {
startAppListening({ startAppListening({
matcher: imagesApi.endpoints.uploadImage.matchFulfilled, matcher: imagesApi.endpoints.uploadImage.matchFulfilled,
effect: (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
const log = logger('images');
const imageDTO = action.payload; const imageDTO = action.payload;
const state = getState(); const state = getState();
const { selectedBoardId, autoAddBoardId } = state.gallery; const { selectedBoardId, autoAddBoardId } = state.gallery;
moduleLog.debug({ arg: '<Blob>', imageDTO }, 'Image uploaded'); log.debug({ imageDTO }, 'Image uploaded');
const { postUploadAction } = action.meta.arg.originalArgs; const { postUploadAction } = action.meta.arg.originalArgs;
@ -140,9 +139,10 @@ export const addImageUploadedRejectedListener = () => {
startAppListening({ startAppListening({
matcher: imagesApi.endpoints.uploadImage.matchRejected, matcher: imagesApi.endpoints.uploadImage.matchRejected,
effect: (action, { dispatch }) => { effect: (action, { dispatch }) => {
const log = logger('images');
const { file, postUploadAction, ...rest } = action.meta.arg.originalArgs; const { file, postUploadAction, ...rest } = action.meta.arg.originalArgs;
const sanitizedData = { arg: { ...rest, file: '<Blob>' } }; const sanitizedData = { arg: { ...rest, file: '<Blob>' } };
moduleLog.error({ data: sanitizedData }, 'Image upload failed'); log.error({ ...sanitizedData }, 'Image upload failed');
dispatch( dispatch(
addToast({ addToast({
title: 'Image Upload Failed', title: 'Image Upload Failed',

View File

@ -1,5 +1,5 @@
import { makeToast } from 'app/components/Toaster'; import { makeToast } from 'app/components/Toaster';
import { log } from 'app/logging/useLogger'; import { $logger, logger } from 'app/logging/logger';
import { loraRemoved } from 'features/lora/store/loraSlice'; import { loraRemoved } from 'features/lora/store/loraSlice';
import { modelSelected } from 'features/parameters/store/actions'; import { modelSelected } from 'features/parameters/store/actions';
import { import {
@ -12,17 +12,17 @@ import { forEach } from 'lodash-es';
import { startAppListening } from '..'; import { startAppListening } from '..';
import { controlNetRemoved } from 'features/controlNet/store/controlNetSlice'; import { controlNetRemoved } from 'features/controlNet/store/controlNetSlice';
const moduleLog = log.child({ module: 'models' });
export const addModelSelectedListener = () => { export const addModelSelectedListener = () => {
startAppListening({ startAppListening({
actionCreator: modelSelected, actionCreator: modelSelected,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const log = logger('models');
const state = getState(); const state = getState();
const result = zMainModel.safeParse(action.payload); const result = zMainModel.safeParse(action.payload);
if (!result.success) { if (!result.success) {
moduleLog.error( log.error(
{ error: result.error.format() }, { error: result.error.format() },
'Failed to parse main model' 'Failed to parse main model'
); );

View File

@ -1,4 +1,4 @@
import { log } from 'app/logging/useLogger'; import { $logger, logger } from 'app/logging/logger';
import { loraRemoved } from 'features/lora/store/loraSlice'; import { loraRemoved } from 'features/lora/store/loraSlice';
import { import {
modelChanged, modelChanged,
@ -13,13 +13,16 @@ import { modelsApi } from 'services/api/endpoints/models';
import { startAppListening } from '..'; import { startAppListening } from '..';
import { controlNetRemoved } from 'features/controlNet/store/controlNetSlice'; import { controlNetRemoved } from 'features/controlNet/store/controlNetSlice';
const moduleLog = log.child({ module: 'models' });
export const addModelsLoadedListener = () => { export const addModelsLoadedListener = () => {
startAppListening({ startAppListening({
matcher: modelsApi.endpoints.getMainModels.matchFulfilled, matcher: modelsApi.endpoints.getMainModels.matchFulfilled,
effect: async (action, { getState, dispatch }) => { effect: async (action, { getState, dispatch }) => {
// models loaded, we need to ensure the selected model is available and if not, select the first one // models loaded, we need to ensure the selected model is available and if not, select the first one
const log = logger('models');
log.info(
{ models: action.payload.entities },
`Main models loaded (${action.payload.ids.length})`
);
const currentModel = getState().generation.model; const currentModel = getState().generation.model;
@ -46,7 +49,7 @@ export const addModelsLoadedListener = () => {
const result = zMainModel.safeParse(firstModel); const result = zMainModel.safeParse(firstModel);
if (!result.success) { if (!result.success) {
moduleLog.error( log.error(
{ error: result.error.format() }, { error: result.error.format() },
'Failed to parse main model' 'Failed to parse main model'
); );
@ -60,6 +63,11 @@ export const addModelsLoadedListener = () => {
matcher: modelsApi.endpoints.getVaeModels.matchFulfilled, matcher: modelsApi.endpoints.getVaeModels.matchFulfilled,
effect: async (action, { getState, dispatch }) => { effect: async (action, { getState, dispatch }) => {
// VAEs loaded, need to reset the VAE is it's no longer available // VAEs loaded, need to reset the VAE is it's no longer available
const log = logger('models');
log.info(
{ models: action.payload.entities },
`VAEs loaded (${action.payload.ids.length})`
);
const currentVae = getState().generation.vae; const currentVae = getState().generation.vae;
@ -91,7 +99,7 @@ export const addModelsLoadedListener = () => {
const result = zVaeModel.safeParse(firstModel); const result = zVaeModel.safeParse(firstModel);
if (!result.success) { if (!result.success) {
moduleLog.error( log.error(
{ error: result.error.format() }, { error: result.error.format() },
'Failed to parse VAE model' 'Failed to parse VAE model'
); );
@ -105,6 +113,11 @@ export const addModelsLoadedListener = () => {
matcher: modelsApi.endpoints.getLoRAModels.matchFulfilled, matcher: modelsApi.endpoints.getLoRAModels.matchFulfilled,
effect: async (action, { getState, dispatch }) => { effect: async (action, { getState, dispatch }) => {
// LoRA models loaded - need to remove missing LoRAs from state // LoRA models loaded - need to remove missing LoRAs from state
const log = logger('models');
log.info(
{ models: action.payload.entities },
`LoRAs loaded (${action.payload.ids.length})`
);
const loras = getState().lora.loras; const loras = getState().lora.loras;
@ -128,6 +141,12 @@ export const addModelsLoadedListener = () => {
matcher: modelsApi.endpoints.getControlNetModels.matchFulfilled, matcher: modelsApi.endpoints.getControlNetModels.matchFulfilled,
effect: async (action, { getState, dispatch }) => { effect: async (action, { getState, dispatch }) => {
// ControlNet models loaded - need to remove missing ControlNets from state // ControlNet models loaded - need to remove missing ControlNets from state
const log = logger('models');
log.info(
{ models: action.payload.entities },
`ControlNet models loaded (${action.payload.ids.length})`
);
const controlNets = getState().controlNet.controlNets; const controlNets = getState().controlNet.controlNets;
forEach(controlNets, (controlNet, controlNetId) => { forEach(controlNets, (controlNet, controlNetId) => {
@ -146,4 +165,14 @@ export const addModelsLoadedListener = () => {
}); });
}, },
}); });
startAppListening({
matcher: modelsApi.endpoints.getTextualInversionModels.matchFulfilled,
effect: async (action, { getState, dispatch }) => {
const log = logger('models');
log.info(
{ models: action.payload.entities },
`Embeddings loaded (${action.payload.ids.length})`
);
},
});
}; };

View File

@ -1,24 +1,24 @@
import { logger } from 'app/logging/logger';
import { nodeTemplatesBuilt } from 'features/nodes/store/nodesSlice';
import { parseSchema } from 'features/nodes/util/parseSchema';
import { size } from 'lodash-es';
import { receivedOpenAPISchema } from 'services/api/thunks/schema'; import { receivedOpenAPISchema } from 'services/api/thunks/schema';
import { startAppListening } from '..'; import { startAppListening } from '..';
import { log } from 'app/logging/useLogger'; import { parseify } from 'common/util/serialize';
import { parseSchema } from 'features/nodes/util/parseSchema';
import { nodeTemplatesBuilt } from 'features/nodes/store/nodesSlice';
import { size } from 'lodash-es';
const schemaLog = log.child({ namespace: 'schema' });
export const addReceivedOpenAPISchemaListener = () => { export const addReceivedOpenAPISchemaListener = () => {
startAppListening({ startAppListening({
actionCreator: receivedOpenAPISchema.fulfilled, actionCreator: receivedOpenAPISchema.fulfilled,
effect: (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
const log = logger('system');
const schemaJSON = action.payload; const schemaJSON = action.payload;
schemaLog.info({ data: { schemaJSON } }, 'Dereferenced OpenAPI schema'); log.debug({ schemaJSON }, 'Dereferenced OpenAPI schema');
const nodeTemplates = parseSchema(schemaJSON); const nodeTemplates = parseSchema(schemaJSON);
schemaLog.info( log.debug(
{ data: { nodeTemplates } }, { nodeTemplates: parseify(nodeTemplates) },
`Built ${size(nodeTemplates)} node templates` `Built ${size(nodeTemplates)} node templates`
); );
@ -29,7 +29,8 @@ export const addReceivedOpenAPISchemaListener = () => {
startAppListening({ startAppListening({
actionCreator: receivedOpenAPISchema.rejected, actionCreator: receivedOpenAPISchema.rejected,
effect: (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
schemaLog.error('Problem dereferencing OpenAPI Schema'); const log = logger('system');
log.error('Problem dereferencing OpenAPI Schema');
}, },
}); });
}; };

View File

@ -1,14 +1,13 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { startAppListening } from '..';
import { sessionCanceled } from 'services/api/thunks/session';
import { serializeError } from 'serialize-error'; import { serializeError } from 'serialize-error';
import { sessionCanceled } from 'services/api/thunks/session';
const moduleLog = log.child({ namespace: 'session' }); import { startAppListening } from '..';
export const addSessionCanceledPendingListener = () => { export const addSessionCanceledPendingListener = () => {
startAppListening({ startAppListening({
actionCreator: sessionCanceled.pending, actionCreator: sessionCanceled.pending,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const log = logger('session');
// //
}, },
}); });
@ -18,11 +17,9 @@ export const addSessionCanceledFulfilledListener = () => {
startAppListening({ startAppListening({
actionCreator: sessionCanceled.fulfilled, actionCreator: sessionCanceled.fulfilled,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const log = logger('session');
const { session_id } = action.meta.arg; const { session_id } = action.meta.arg;
moduleLog.debug( log.debug({ session_id }, `Session canceled (${session_id})`);
{ data: { session_id } },
`Session canceled (${session_id})`
);
}, },
}); });
}; };
@ -31,14 +28,14 @@ export const addSessionCanceledRejectedListener = () => {
startAppListening({ startAppListening({
actionCreator: sessionCanceled.rejected, actionCreator: sessionCanceled.rejected,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const log = logger('session');
const { session_id } = action.meta.arg;
if (action.payload) { if (action.payload) {
const { arg, error } = action.payload; const { error } = action.payload;
moduleLog.error( log.error(
{ {
data: { session_id,
arg, error: serializeError(error),
error: serializeError(error),
},
}, },
`Problem canceling session` `Problem canceling session`
); );

View File

@ -1,14 +1,14 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { parseify } from 'common/util/serialize';
import { serializeError } from 'serialize-error'; import { serializeError } from 'serialize-error';
import { sessionCreated } from 'services/api/thunks/session'; import { sessionCreated } from 'services/api/thunks/session';
import { startAppListening } from '..'; import { startAppListening } from '..';
const moduleLog = log.child({ namespace: 'session' });
export const addSessionCreatedPendingListener = () => { export const addSessionCreatedPendingListener = () => {
startAppListening({ startAppListening({
actionCreator: sessionCreated.pending, actionCreator: sessionCreated.pending,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const log = logger('session');
// //
}, },
}); });
@ -18,8 +18,12 @@ export const addSessionCreatedFulfilledListener = () => {
startAppListening({ startAppListening({
actionCreator: sessionCreated.fulfilled, actionCreator: sessionCreated.fulfilled,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const log = logger('session');
const session = action.payload; const session = action.payload;
moduleLog.debug({ data: { session } }, `Session created (${session.id})`); log.debug(
{ session: parseify(session) },
`Session created (${session.id})`
);
}, },
}); });
}; };
@ -28,16 +32,13 @@ export const addSessionCreatedRejectedListener = () => {
startAppListening({ startAppListening({
actionCreator: sessionCreated.rejected, actionCreator: sessionCreated.rejected,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const log = logger('session');
if (action.payload) { if (action.payload) {
const { arg, error } = action.payload; const { arg, error } = action.payload;
const graph = parseify(action.meta.arg);
const stringifiedError = JSON.stringify(error); const stringifiedError = JSON.stringify(error);
moduleLog.error( log.error(
{ { graph, error: serializeError(error) },
data: {
arg,
error: serializeError(error),
},
},
`Problem creating session: ${stringifiedError}` `Problem creating session: ${stringifiedError}`
); );
} }

View File

@ -1,14 +1,13 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { startAppListening } from '..';
import { sessionInvoked } from 'services/api/thunks/session';
import { serializeError } from 'serialize-error'; import { serializeError } from 'serialize-error';
import { sessionInvoked } from 'services/api/thunks/session';
const moduleLog = log.child({ namespace: 'session' }); import { startAppListening } from '..';
export const addSessionInvokedPendingListener = () => { export const addSessionInvokedPendingListener = () => {
startAppListening({ startAppListening({
actionCreator: sessionInvoked.pending, actionCreator: sessionInvoked.pending,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const log = logger('session');
// //
}, },
}); });
@ -18,11 +17,9 @@ export const addSessionInvokedFulfilledListener = () => {
startAppListening({ startAppListening({
actionCreator: sessionInvoked.fulfilled, actionCreator: sessionInvoked.fulfilled,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const log = logger('session');
const { session_id } = action.meta.arg; const { session_id } = action.meta.arg;
moduleLog.debug( log.debug({ session_id }, `Session invoked (${session_id})`);
{ data: { session_id } },
`Session invoked (${session_id})`
);
}, },
}); });
}; };
@ -31,15 +28,15 @@ export const addSessionInvokedRejectedListener = () => {
startAppListening({ startAppListening({
actionCreator: sessionInvoked.rejected, actionCreator: sessionInvoked.rejected,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const log = logger('session');
const { session_id } = action.meta.arg;
if (action.payload) { if (action.payload) {
const { arg, error } = action.payload; const { arg, error } = action.payload;
const stringifiedError = JSON.stringify(error); const stringifiedError = JSON.stringify(error);
moduleLog.error( log.error(
{ {
data: { session_id,
arg, error: serializeError(error),
error: serializeError(error),
},
}, },
`Problem invoking session: ${stringifiedError}` `Problem invoking session: ${stringifiedError}`
); );

View File

@ -1,20 +1,16 @@
import { startAppListening } from '..'; import { logger } from 'app/logging/logger';
import { sessionInvoked } from 'services/api/thunks/session';
import { log } from 'app/logging/useLogger';
import { sessionReadyToInvoke } from 'features/system/store/actions'; import { sessionReadyToInvoke } from 'features/system/store/actions';
import { sessionInvoked } from 'services/api/thunks/session';
const moduleLog = log.child({ namespace: 'session' }); import { startAppListening } from '..';
export const addSessionReadyToInvokeListener = () => { export const addSessionReadyToInvokeListener = () => {
startAppListening({ startAppListening({
actionCreator: sessionReadyToInvoke, actionCreator: sessionReadyToInvoke,
effect: (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const log = logger('session');
const { sessionId: session_id } = getState().system; const { sessionId: session_id } = getState().system;
if (session_id) { if (session_id) {
moduleLog.debug( log.debug({ session_id }, `Session ready to invoke (${session_id})})`);
{ session_id },
`Session ready to invoke (${session_id})})`
);
dispatch(sessionInvoked({ session_id })); dispatch(sessionInvoked({ session_id }));
} }
}, },

View File

@ -1,18 +1,16 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { modelsApi } from 'services/api/endpoints/models'; import { modelsApi } from 'services/api/endpoints/models';
import { receivedOpenAPISchema } from 'services/api/thunks/schema'; import { receivedOpenAPISchema } from 'services/api/thunks/schema';
import { appSocketConnected, socketConnected } from 'services/events/actions'; import { appSocketConnected, socketConnected } from 'services/events/actions';
import { startAppListening } from '../..'; import { startAppListening } from '../..';
const moduleLog = log.child({ namespace: 'socketio' });
export const addSocketConnectedEventListener = () => { export const addSocketConnectedEventListener = () => {
startAppListening({ startAppListening({
actionCreator: socketConnected, actionCreator: socketConnected,
effect: (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
const { timestamp } = action.payload; const log = logger('socketio');
moduleLog.debug({ timestamp }, 'Connected'); log.debug('Connected');
const { nodes, config } = getState(); const { nodes, config } = getState();

View File

@ -1,17 +1,16 @@
import { startAppListening } from '../..'; import { logger } from 'app/logging/logger';
import { log } from 'app/logging/useLogger';
import { import {
socketDisconnected,
appSocketDisconnected, appSocketDisconnected,
socketDisconnected,
} from 'services/events/actions'; } from 'services/events/actions';
import { startAppListening } from '../..';
const moduleLog = log.child({ namespace: 'socketio' });
export const addSocketDisconnectedEventListener = () => { export const addSocketDisconnectedEventListener = () => {
startAppListening({ startAppListening({
actionCreator: socketDisconnected, actionCreator: socketDisconnected,
effect: (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
moduleLog.debug(action.payload, 'Disconnected'); const log = logger('socketio');
log.debug('Disconnected');
// pass along the socket event as an application action // pass along the socket event as an application action
dispatch(appSocketDisconnected(action.payload)); dispatch(appSocketDisconnected(action.payload));
}, },

View File

@ -1,28 +1,27 @@
import { startAppListening } from '../..'; import { logger } from 'app/logging/logger';
import { log } from 'app/logging/useLogger';
import { import {
appSocketGeneratorProgress, appSocketGeneratorProgress,
socketGeneratorProgress, socketGeneratorProgress,
} from 'services/events/actions'; } from 'services/events/actions';
import { startAppListening } from '../..';
const moduleLog = log.child({ namespace: 'socketio' });
export const addGeneratorProgressEventListener = () => { export const addGeneratorProgressEventListener = () => {
startAppListening({ startAppListening({
actionCreator: socketGeneratorProgress, actionCreator: socketGeneratorProgress,
effect: (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
const log = logger('socketio');
if ( if (
getState().system.canceledSession === getState().system.canceledSession ===
action.payload.data.graph_execution_state_id action.payload.data.graph_execution_state_id
) { ) {
moduleLog.trace( log.trace(
action.payload, action.payload,
'Ignored generator progress for canceled session' 'Ignored generator progress for canceled session'
); );
return; return;
} }
moduleLog.trace( log.trace(
action.payload, action.payload,
`Generator progress (${action.payload.data.node.type})` `Generator progress (${action.payload.data.node.type})`
); );

View File

@ -1,20 +1,16 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { import {
appSocketGraphExecutionStateComplete, appSocketGraphExecutionStateComplete,
socketGraphExecutionStateComplete, socketGraphExecutionStateComplete,
} from 'services/events/actions'; } from 'services/events/actions';
import { startAppListening } from '../..'; import { startAppListening } from '../..';
const moduleLog = log.child({ namespace: 'socketio' });
export const addGraphExecutionStateCompleteEventListener = () => { export const addGraphExecutionStateCompleteEventListener = () => {
startAppListening({ startAppListening({
actionCreator: socketGraphExecutionStateComplete, actionCreator: socketGraphExecutionStateComplete,
effect: (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
moduleLog.debug( const log = logger('socketio');
action.payload, log.debug(action.payload, 'Session complete');
`Session invocation complete (${action.payload.data.graph_execution_state_id})`
);
// pass along the socket event as an application action // pass along the socket event as an application action
dispatch(appSocketGraphExecutionStateComplete(action.payload)); dispatch(appSocketGraphExecutionStateComplete(action.payload));
}, },

View File

@ -1,4 +1,5 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { parseify } from 'common/util/serialize';
import { addImageToStagingArea } from 'features/canvas/store/canvasSlice'; import { addImageToStagingArea } from 'features/canvas/store/canvasSlice';
import { import {
IMAGE_CATEGORIES, IMAGE_CATEGORIES,
@ -16,15 +17,16 @@ import {
} from 'services/events/actions'; } from 'services/events/actions';
import { startAppListening } from '../..'; import { startAppListening } from '../..';
const moduleLog = log.child({ namespace: 'socketio' });
const nodeDenylist = ['dataURL_image']; const nodeDenylist = ['dataURL_image'];
export const addInvocationCompleteEventListener = () => { export const addInvocationCompleteEventListener = () => {
startAppListening({ startAppListening({
actionCreator: socketInvocationComplete, actionCreator: socketInvocationComplete,
effect: async (action, { dispatch, getState, take }) => { effect: async (action, { dispatch, getState, take }) => {
moduleLog.debug( const log = logger('socketio');
{ data: action.payload }, const { data } = action.payload;
log.debug(
{ data: parseify(data) },
`Invocation complete (${action.payload.data.node.type})` `Invocation complete (${action.payload.data.node.type})`
); );
const session_id = action.payload.data.graph_execution_state_id; const session_id = action.payload.data.graph_execution_state_id;
@ -36,7 +38,6 @@ export const addInvocationCompleteEventListener = () => {
dispatch(sessionCanceled({ session_id })); dispatch(sessionCanceled({ session_id }));
} }
const { data } = action.payload;
const { result, node, graph_execution_state_id } = data; const { result, node, graph_execution_state_id } = data;
// This complete event has an associated image output // This complete event has an associated image output

View File

@ -1,19 +1,18 @@
import { startAppListening } from '../..'; import { logger } from 'app/logging/logger';
import { log } from 'app/logging/useLogger';
import { import {
appSocketInvocationError, appSocketInvocationError,
socketInvocationError, socketInvocationError,
} from 'services/events/actions'; } from 'services/events/actions';
import { startAppListening } from '../..';
const moduleLog = log.child({ namespace: 'socketio' });
export const addInvocationErrorEventListener = () => { export const addInvocationErrorEventListener = () => {
startAppListening({ startAppListening({
actionCreator: socketInvocationError, actionCreator: socketInvocationError,
effect: (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
moduleLog.error( const log = logger('socketio');
log.error(
action.payload, action.payload,
`Invocation error (${action.payload.data.node.type}): ${action.payload.data.error}` `Invocation error (${action.payload.data.node.type})`
); );
dispatch(appSocketInvocationError(action.payload)); dispatch(appSocketInvocationError(action.payload));
}, },

View File

@ -1,31 +1,27 @@
import { startAppListening } from '../..'; import { logger } from 'app/logging/logger';
import { log } from 'app/logging/useLogger';
import { import {
appSocketInvocationStarted, appSocketInvocationStarted,
socketInvocationStarted, socketInvocationStarted,
} from 'services/events/actions'; } from 'services/events/actions';
import { startAppListening } from '../..';
const moduleLog = log.child({ namespace: 'socketio' });
export const addInvocationStartedEventListener = () => { export const addInvocationStartedEventListener = () => {
startAppListening({ startAppListening({
actionCreator: socketInvocationStarted, actionCreator: socketInvocationStarted,
effect: (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
const log = logger('socketio');
if ( if (
getState().system.canceledSession === getState().system.canceledSession ===
action.payload.data.graph_execution_state_id action.payload.data.graph_execution_state_id
) { ) {
moduleLog.trace( log.trace(
action.payload, action.payload,
'Ignored invocation started for canceled session' 'Ignored invocation started for canceled session'
); );
return; return;
} }
moduleLog.debug( log.debug(action.payload, 'Invocation started');
action.payload,
`Invocation started (${action.payload.data.node.type})`
);
dispatch(appSocketInvocationStarted(action.payload)); dispatch(appSocketInvocationStarted(action.payload));
}, },
}); });

View File

@ -0,0 +1,58 @@
import { logger } from 'app/logging/logger';
import { ModelType } from 'services/api/types';
import {
appSocketModelLoadCompleted,
appSocketModelLoadStarted,
socketModelLoadCompleted,
socketModelLoadStarted,
} from 'services/events/actions';
import { startAppListening } from '../..';
const MODEL_TYPES: Record<ModelType, string> = {
main: 'main',
vae: 'VAE',
lora: 'LoRA',
controlnet: 'ControlNet',
embedding: 'embedding',
};
export const addModelLoadEventListener = () => {
startAppListening({
actionCreator: socketModelLoadStarted,
effect: (action, { dispatch, getState }) => {
const log = logger('socketio');
const { base_model, model_name, model_type, submodel } =
action.payload.data;
let message = `Model load started: ${base_model}/${model_type}/${model_name}`;
if (submodel) {
message = message.concat(`/${submodel}`);
}
log.debug(action.payload, message);
// pass along the socket event as an application action
dispatch(appSocketModelLoadStarted(action.payload));
},
});
startAppListening({
actionCreator: socketModelLoadCompleted,
effect: (action, { dispatch, getState }) => {
const log = logger('socketio');
const { base_model, model_name, model_type, submodel } =
action.payload.data;
let message = `Model load complete: ${base_model}/${model_type}/${model_name}`;
if (submodel) {
message = message.concat(`/${submodel}`);
}
log.debug(action.payload, message);
// pass along the socket event as an application action
dispatch(appSocketModelLoadCompleted(action.payload));
},
});
};

View File

@ -1,28 +0,0 @@
import { log } from 'app/logging/useLogger';
import {
appSocketModelLoadCompleted,
socketModelLoadCompleted,
} from 'services/events/actions';
import { startAppListening } from '../..';
const moduleLog = log.child({ namespace: 'socketio' });
export const addModelLoadCompletedEventListener = () => {
startAppListening({
actionCreator: socketModelLoadCompleted,
effect: (action, { dispatch, getState }) => {
const { model_name, model_type, submodel } = action.payload.data;
let modelString = `${model_type} model: ${model_name}`;
if (submodel) {
modelString = modelString.concat(`, submodel: ${submodel}`);
}
moduleLog.debug(action.payload, `Model load completed (${modelString})`);
// pass along the socket event as an application action
dispatch(appSocketModelLoadCompleted(action.payload));
},
});
};

View File

@ -1,28 +0,0 @@
import { log } from 'app/logging/useLogger';
import {
appSocketModelLoadStarted,
socketModelLoadStarted,
} from 'services/events/actions';
import { startAppListening } from '../..';
const moduleLog = log.child({ namespace: 'socketio' });
export const addModelLoadStartedEventListener = () => {
startAppListening({
actionCreator: socketModelLoadStarted,
effect: (action, { dispatch, getState }) => {
const { model_name, model_type, submodel } = action.payload.data;
let modelString = `${model_type} model: ${model_name}`;
if (submodel) {
modelString = modelString.concat(`, submodel: ${submodel}`);
}
moduleLog.debug(action.payload, `Model load started (${modelString})`);
// pass along the socket event as an application action
dispatch(appSocketModelLoadStarted(action.payload));
},
});
};

View File

@ -1,17 +1,13 @@
import { startAppListening } from '../..'; import { logger } from 'app/logging/logger';
import { log } from 'app/logging/useLogger';
import { appSocketSubscribed, socketSubscribed } from 'services/events/actions'; import { appSocketSubscribed, socketSubscribed } from 'services/events/actions';
import { startAppListening } from '../..';
const moduleLog = log.child({ namespace: 'socketio' });
export const addSocketSubscribedEventListener = () => { export const addSocketSubscribedEventListener = () => {
startAppListening({ startAppListening({
actionCreator: socketSubscribed, actionCreator: socketSubscribed,
effect: (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
moduleLog.debug( const log = logger('socketio');
action.payload, log.debug(action.payload, 'Subscribed');
`Subscribed (${action.payload.sessionId}))`
);
dispatch(appSocketSubscribed(action.payload)); dispatch(appSocketSubscribed(action.payload));
}, },
}); });

View File

@ -1,20 +1,16 @@
import { startAppListening } from '../..'; import { logger } from 'app/logging/logger';
import { log } from 'app/logging/useLogger';
import { import {
appSocketUnsubscribed, appSocketUnsubscribed,
socketUnsubscribed, socketUnsubscribed,
} from 'services/events/actions'; } from 'services/events/actions';
import { startAppListening } from '../..';
const moduleLog = log.child({ namespace: 'socketio' });
export const addSocketUnsubscribedEventListener = () => { export const addSocketUnsubscribedEventListener = () => {
startAppListening({ startAppListening({
actionCreator: socketUnsubscribed, actionCreator: socketUnsubscribed,
effect: (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
moduleLog.debug( const log = logger('socketio');
action.payload, log.debug(action.payload, 'Unsubscribed');
`Unsubscribed (${action.payload.sessionId})`
);
dispatch(appSocketUnsubscribed(action.payload)); dispatch(appSocketUnsubscribed(action.payload));
}, },
}); });

View File

@ -1,15 +1,14 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { stagingAreaImageSaved } from 'features/canvas/store/actions'; import { stagingAreaImageSaved } from 'features/canvas/store/actions';
import { addToast } from 'features/system/store/systemSlice'; import { addToast } from 'features/system/store/systemSlice';
import { imagesApi } from 'services/api/endpoints/images'; import { imagesApi } from 'services/api/endpoints/images';
import { startAppListening } from '..'; import { startAppListening } from '..';
const moduleLog = log.child({ namespace: 'canvas' });
export const addStagingAreaImageSavedListener = () => { export const addStagingAreaImageSavedListener = () => {
startAppListening({ startAppListening({
actionCreator: stagingAreaImageSaved, actionCreator: stagingAreaImageSaved,
effect: async (action, { dispatch, getState, take }) => { effect: async (action, { dispatch, getState, take }) => {
const log = logger('canvas');
const { imageDTO } = action.payload; const { imageDTO } = action.payload;
try { try {

View File

@ -1,12 +1,9 @@
import { createAction } from '@reduxjs/toolkit'; import { createAction } from '@reduxjs/toolkit';
import { log } from 'app/logging/useLogger';
import { buildAdHocUpscaleGraph } from 'features/nodes/util/graphBuilders/buildAdHocUpscaleGraph'; import { buildAdHocUpscaleGraph } from 'features/nodes/util/graphBuilders/buildAdHocUpscaleGraph';
import { sessionReadyToInvoke } from 'features/system/store/actions'; import { sessionReadyToInvoke } from 'features/system/store/actions';
import { sessionCreated } from 'services/api/thunks/session'; import { sessionCreated } from 'services/api/thunks/session';
import { startAppListening } from '..'; import { startAppListening } from '..';
const moduleLog = log.child({ namespace: 'upscale' });
export const upscaleRequested = createAction<{ image_name: string }>( export const upscaleRequested = createAction<{ image_name: string }>(
`upscale/upscaleRequested` `upscale/upscaleRequested`
); );

View File

@ -1,4 +1,4 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { userInvoked } from 'app/store/actions'; import { userInvoked } from 'app/store/actions';
import openBase64ImageInTab from 'common/util/openBase64ImageInTab'; import openBase64ImageInTab from 'common/util/openBase64ImageInTab';
import { import {
@ -15,8 +15,7 @@ import { imagesApi } from 'services/api/endpoints/images';
import { sessionCreated } from 'services/api/thunks/session'; import { sessionCreated } from 'services/api/thunks/session';
import { ImageDTO } from 'services/api/types'; import { ImageDTO } from 'services/api/types';
import { startAppListening } from '..'; import { startAppListening } from '..';
import { parseify } from 'common/util/serialize';
const moduleLog = log.child({ namespace: 'invoke' });
/** /**
* This listener is responsible invoking the canvas. This involves a number of steps: * This listener is responsible invoking the canvas. This involves a number of steps:
@ -36,13 +35,15 @@ export const addUserInvokedCanvasListener = () => {
predicate: (action): action is ReturnType<typeof userInvoked> => predicate: (action): action is ReturnType<typeof userInvoked> =>
userInvoked.match(action) && action.payload === 'unifiedCanvas', userInvoked.match(action) && action.payload === 'unifiedCanvas',
effect: async (action, { getState, dispatch, take }) => { effect: async (action, { getState, dispatch, take }) => {
const log = logger('session');
const state = getState(); const state = getState();
// Build canvas blobs // Build canvas blobs
const canvasBlobsAndImageData = await getCanvasData(state); const canvasBlobsAndImageData = await getCanvasData(state);
if (!canvasBlobsAndImageData) { if (!canvasBlobsAndImageData) {
moduleLog.error('Unable to create canvas data'); log.error('Unable to create canvas data');
return; return;
} }
@ -64,7 +65,7 @@ export const addUserInvokedCanvasListener = () => {
]); ]);
} }
moduleLog.debug(`Generation mode: ${generationMode}`); log.debug(`Generation mode: ${generationMode}`);
// Temp placeholders for the init and mask images // Temp placeholders for the init and mask images
let canvasInitImage: ImageDTO | undefined; let canvasInitImage: ImageDTO | undefined;
@ -105,7 +106,7 @@ export const addUserInvokedCanvasListener = () => {
canvasMaskImage canvasMaskImage
); );
moduleLog.debug({ graph }, `Canvas graph built`); log.debug({ graph: parseify(graph) }, `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,23 +1,23 @@
import { startAppListening } from '..'; import { logger } from 'app/logging/logger';
import { sessionCreated } from 'services/api/thunks/session';
import { log } from 'app/logging/useLogger';
import { imageToImageGraphBuilt } from 'features/nodes/store/actions';
import { userInvoked } from 'app/store/actions'; import { userInvoked } from 'app/store/actions';
import { sessionReadyToInvoke } from 'features/system/store/actions'; import { parseify } from 'common/util/serialize';
import { imageToImageGraphBuilt } from 'features/nodes/store/actions';
import { buildLinearImageToImageGraph } from 'features/nodes/util/graphBuilders/buildLinearImageToImageGraph'; import { buildLinearImageToImageGraph } from 'features/nodes/util/graphBuilders/buildLinearImageToImageGraph';
import { sessionReadyToInvoke } from 'features/system/store/actions';
const moduleLog = log.child({ namespace: 'invoke' }); import { sessionCreated } from 'services/api/thunks/session';
import { startAppListening } from '..';
export const addUserInvokedImageToImageListener = () => { export const addUserInvokedImageToImageListener = () => {
startAppListening({ startAppListening({
predicate: (action): action is ReturnType<typeof userInvoked> => predicate: (action): action is ReturnType<typeof userInvoked> =>
userInvoked.match(action) && action.payload === 'img2img', userInvoked.match(action) && action.payload === 'img2img',
effect: async (action, { getState, dispatch, take }) => { effect: async (action, { getState, dispatch, take }) => {
const log = logger('session');
const state = getState(); const state = getState();
const graph = buildLinearImageToImageGraph(state); const graph = buildLinearImageToImageGraph(state);
dispatch(imageToImageGraphBuilt(graph)); dispatch(imageToImageGraphBuilt(graph));
moduleLog.debug({ data: graph }, 'Image to Image graph built'); log.debug({ graph: parseify(graph) }, 'Image to Image graph built');
dispatch(sessionCreated({ graph })); dispatch(sessionCreated({ graph }));

View File

@ -1,23 +1,23 @@
import { startAppListening } from '..'; import { logger } from 'app/logging/logger';
import { sessionCreated } from 'services/api/thunks/session';
import { buildNodesGraph } from 'features/nodes/util/graphBuilders/buildNodesGraph';
import { log } from 'app/logging/useLogger';
import { nodesGraphBuilt } from 'features/nodes/store/actions';
import { userInvoked } from 'app/store/actions'; import { userInvoked } from 'app/store/actions';
import { parseify } from 'common/util/serialize';
import { nodesGraphBuilt } from 'features/nodes/store/actions';
import { buildNodesGraph } from 'features/nodes/util/graphBuilders/buildNodesGraph';
import { sessionReadyToInvoke } from 'features/system/store/actions'; import { sessionReadyToInvoke } from 'features/system/store/actions';
import { sessionCreated } from 'services/api/thunks/session';
const moduleLog = log.child({ namespace: 'invoke' }); import { startAppListening } from '..';
export const addUserInvokedNodesListener = () => { export const addUserInvokedNodesListener = () => {
startAppListening({ startAppListening({
predicate: (action): action is ReturnType<typeof userInvoked> => predicate: (action): action is ReturnType<typeof userInvoked> =>
userInvoked.match(action) && action.payload === 'nodes', userInvoked.match(action) && action.payload === 'nodes',
effect: async (action, { getState, dispatch, take }) => { effect: async (action, { getState, dispatch, take }) => {
const log = logger('session');
const state = getState(); const state = getState();
const graph = buildNodesGraph(state); const graph = buildNodesGraph(state);
dispatch(nodesGraphBuilt(graph)); dispatch(nodesGraphBuilt(graph));
moduleLog.debug({ data: graph }, 'Nodes graph built'); log.debug({ graph: parseify(graph) }, 'Nodes graph built');
dispatch(sessionCreated({ graph })); dispatch(sessionCreated({ graph }));

View File

@ -1,25 +1,25 @@
import { startAppListening } from '..'; import { logger } from 'app/logging/logger';
import { sessionCreated } from 'services/api/thunks/session';
import { log } from 'app/logging/useLogger';
import { textToImageGraphBuilt } from 'features/nodes/store/actions';
import { userInvoked } from 'app/store/actions'; import { userInvoked } from 'app/store/actions';
import { sessionReadyToInvoke } from 'features/system/store/actions'; import { parseify } from 'common/util/serialize';
import { textToImageGraphBuilt } from 'features/nodes/store/actions';
import { buildLinearTextToImageGraph } from 'features/nodes/util/graphBuilders/buildLinearTextToImageGraph'; import { buildLinearTextToImageGraph } from 'features/nodes/util/graphBuilders/buildLinearTextToImageGraph';
import { sessionReadyToInvoke } from 'features/system/store/actions';
const moduleLog = log.child({ namespace: 'invoke' }); import { sessionCreated } from 'services/api/thunks/session';
import { startAppListening } from '..';
export const addUserInvokedTextToImageListener = () => { export const addUserInvokedTextToImageListener = () => {
startAppListening({ startAppListening({
predicate: (action): action is ReturnType<typeof userInvoked> => predicate: (action): action is ReturnType<typeof userInvoked> =>
userInvoked.match(action) && action.payload === 'txt2img', userInvoked.match(action) && action.payload === 'txt2img',
effect: async (action, { getState, dispatch, take }) => { effect: async (action, { getState, dispatch, take }) => {
const log = logger('session');
const state = getState(); const state = getState();
const graph = buildLinearTextToImageGraph(state); const graph = buildLinearTextToImageGraph(state);
dispatch(textToImageGraphBuilt(graph)); dispatch(textToImageGraphBuilt(graph));
moduleLog.debug({ data: graph }, 'Text to Image graph built'); log.debug({ graph: parseify(graph) }, 'Text to Image graph built');
dispatch(sessionCreated({ graph })); dispatch(sessionCreated({ graph }));

View File

@ -0,0 +1,4 @@
/**
* Serialize an object to JSON and back to a new object
*/
export const parseify = (obj: unknown) => JSON.parse(JSON.stringify(obj));

View File

@ -1,22 +1,22 @@
import { logger } from 'app/logging/logger';
import { RootState } from 'app/store/store'; import { RootState } from 'app/store/store';
import { getCanvasBaseLayer, getCanvasStage } from './konvaInstanceProvider';
import { isCanvasMaskLine } from '../store/canvasTypes'; import { isCanvasMaskLine } from '../store/canvasTypes';
import { log } from 'app/logging/useLogger';
import createMaskStage from './createMaskStage'; import createMaskStage from './createMaskStage';
import { konvaNodeToImageData } from './konvaNodeToImageData'; import { getCanvasBaseLayer, getCanvasStage } from './konvaInstanceProvider';
import { konvaNodeToBlob } from './konvaNodeToBlob'; import { konvaNodeToBlob } from './konvaNodeToBlob';
import { konvaNodeToImageData } from './konvaNodeToImageData';
const moduleLog = log.child({ namespace: 'getCanvasDataURLs' });
/** /**
* Gets Blob and ImageData objects for the base and mask layers * Gets Blob and ImageData objects for the base and mask layers
*/ */
export const getCanvasData = async (state: RootState) => { export const getCanvasData = async (state: RootState) => {
const log = logger('canvas');
const canvasBaseLayer = getCanvasBaseLayer(); const canvasBaseLayer = getCanvasBaseLayer();
const canvasStage = getCanvasStage(); const canvasStage = getCanvasStage();
if (!canvasBaseLayer || !canvasStage) { if (!canvasBaseLayer || !canvasStage) {
moduleLog.error('Unable to find canvas / stage'); log.error('Unable to find canvas / stage');
return; return;
} }

View File

@ -1,4 +1,3 @@
import { log } from 'app/logging/useLogger';
import { RootState } from 'app/store/store'; import { RootState } from 'app/store/store';
import { NonNullableGraph } from 'features/nodes/types/types'; import { NonNullableGraph } from 'features/nodes/types/types';
import { ImageDTO } from 'services/api/types'; import { ImageDTO } from 'services/api/types';
@ -6,8 +5,6 @@ import { buildCanvasImageToImageGraph } from './buildCanvasImageToImageGraph';
import { buildCanvasInpaintGraph } from './buildCanvasInpaintGraph'; import { buildCanvasInpaintGraph } from './buildCanvasInpaintGraph';
import { buildCanvasTextToImageGraph } from './buildCanvasTextToImageGraph'; import { buildCanvasTextToImageGraph } from './buildCanvasTextToImageGraph';
const moduleLog = log.child({ namespace: 'nodes' });
export const buildCanvasGraph = ( export const buildCanvasGraph = (
state: RootState, state: RootState,
generationMode: 'txt2img' | 'img2img' | 'inpaint' | 'outpaint', generationMode: 'txt2img' | 'img2img' | 'inpaint' | 'outpaint',

View File

@ -1,4 +1,4 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { RootState } from 'app/store/store'; import { RootState } from 'app/store/store';
import { NonNullableGraph } from 'features/nodes/types/types'; import { NonNullableGraph } from 'features/nodes/types/types';
import { initialGenerationState } from 'features/parameters/store/generationSlice'; import { initialGenerationState } from 'features/parameters/store/generationSlice';
@ -25,8 +25,6 @@ import {
RESIZE, RESIZE,
} from './constants'; } from './constants';
const moduleLog = log.child({ namespace: 'nodes' });
/** /**
* Builds the Canvas tab's Image to Image graph. * Builds the Canvas tab's Image to Image graph.
*/ */
@ -34,6 +32,7 @@ export const buildCanvasImageToImageGraph = (
state: RootState, state: RootState,
initialImage: ImageDTO initialImage: ImageDTO
): NonNullableGraph => { ): NonNullableGraph => {
const log = logger('nodes');
const { const {
positivePrompt, positivePrompt,
negativePrompt, negativePrompt,
@ -53,7 +52,7 @@ export const buildCanvasImageToImageGraph = (
const { shouldAutoSave } = state.canvas; const { shouldAutoSave } = state.canvas;
if (!model) { if (!model) {
moduleLog.error('No model found in state'); log.error('No model found in state');
throw new Error('No model found in state'); throw new Error('No model found in state');
} }

View File

@ -1,4 +1,4 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { RootState } from 'app/store/store'; import { RootState } from 'app/store/store';
import { NonNullableGraph } from 'features/nodes/types/types'; import { NonNullableGraph } from 'features/nodes/types/types';
import { import {
@ -21,8 +21,6 @@ import {
RANGE_OF_SIZE, RANGE_OF_SIZE,
} from './constants'; } from './constants';
const moduleLog = log.child({ namespace: 'nodes' });
/** /**
* Builds the Canvas tab's Inpaint graph. * Builds the Canvas tab's Inpaint graph.
*/ */
@ -31,6 +29,7 @@ export const buildCanvasInpaintGraph = (
canvasInitImage: ImageDTO, canvasInitImage: ImageDTO,
canvasMaskImage: ImageDTO canvasMaskImage: ImageDTO
): NonNullableGraph => { ): NonNullableGraph => {
const log = logger('nodes');
const { const {
positivePrompt, positivePrompt,
negativePrompt, negativePrompt,
@ -53,7 +52,7 @@ export const buildCanvasInpaintGraph = (
} = state.generation; } = state.generation;
if (!model) { if (!model) {
moduleLog.error('No model found in state'); log.error('No model found in state');
throw new Error('No model found in state'); throw new Error('No model found in state');
} }

View File

@ -1,4 +1,4 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { RootState } from 'app/store/store'; import { RootState } from 'app/store/store';
import { NonNullableGraph } from 'features/nodes/types/types'; import { NonNullableGraph } from 'features/nodes/types/types';
import { initialGenerationState } from 'features/parameters/store/generationSlice'; import { initialGenerationState } from 'features/parameters/store/generationSlice';
@ -18,14 +18,13 @@ import {
TEXT_TO_LATENTS, TEXT_TO_LATENTS,
} from './constants'; } from './constants';
const moduleLog = log.child({ namespace: 'nodes' });
/** /**
* Builds the Canvas tab's Text to Image graph. * Builds the Canvas tab's Text to Image graph.
*/ */
export const buildCanvasTextToImageGraph = ( export const buildCanvasTextToImageGraph = (
state: RootState state: RootState
): NonNullableGraph => { ): NonNullableGraph => {
const log = logger('nodes');
const { const {
positivePrompt, positivePrompt,
negativePrompt, negativePrompt,
@ -44,7 +43,7 @@ export const buildCanvasTextToImageGraph = (
const { shouldAutoSave } = state.canvas; const { shouldAutoSave } = state.canvas;
if (!model) { if (!model) {
moduleLog.error('No model found in state'); log.error('No model found in state');
throw new Error('No model found in state'); throw new Error('No model found in state');
} }

View File

@ -1,4 +1,4 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { RootState } from 'app/store/store'; import { RootState } from 'app/store/store';
import { NonNullableGraph } from 'features/nodes/types/types'; import { NonNullableGraph } from 'features/nodes/types/types';
import { initialGenerationState } from 'features/parameters/store/generationSlice'; import { initialGenerationState } from 'features/parameters/store/generationSlice';
@ -24,14 +24,13 @@ import {
RESIZE, RESIZE,
} from './constants'; } from './constants';
const moduleLog = log.child({ namespace: 'nodes' });
/** /**
* Builds the Image to Image tab graph. * Builds the Image to Image tab graph.
*/ */
export const buildLinearImageToImageGraph = ( export const buildLinearImageToImageGraph = (
state: RootState state: RootState
): NonNullableGraph => { ): NonNullableGraph => {
const log = logger('nodes');
const { const {
positivePrompt, positivePrompt,
negativePrompt, negativePrompt,
@ -69,12 +68,12 @@ export const buildLinearImageToImageGraph = (
*/ */
if (!initialImage) { if (!initialImage) {
moduleLog.error('No initial image found in state'); log.error('No initial image found in state');
throw new Error('No initial image found in state'); throw new Error('No initial image found in state');
} }
if (!model) { if (!model) {
moduleLog.error('No model found in state'); log.error('No model found in state');
throw new Error('No model found in state'); throw new Error('No model found in state');
} }

View File

@ -1,4 +1,4 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { RootState } from 'app/store/store'; import { RootState } from 'app/store/store';
import { NonNullableGraph } from 'features/nodes/types/types'; import { NonNullableGraph } from 'features/nodes/types/types';
import { initialGenerationState } from 'features/parameters/store/generationSlice'; import { initialGenerationState } from 'features/parameters/store/generationSlice';
@ -18,11 +18,10 @@ import {
TEXT_TO_LATENTS, TEXT_TO_LATENTS,
} from './constants'; } from './constants';
const moduleLog = log.child({ namespace: 'nodes' });
export const buildLinearTextToImageGraph = ( export const buildLinearTextToImageGraph = (
state: RootState state: RootState
): NonNullableGraph => { ): NonNullableGraph => {
const log = logger('nodes');
const { const {
positivePrompt, positivePrompt,
negativePrompt, negativePrompt,
@ -42,7 +41,7 @@ export const buildLinearTextToImageGraph = (
: initialGenerationState.shouldUseCpuNoise; : initialGenerationState.shouldUseCpuNoise;
if (!model) { if (!model) {
moduleLog.error('No model found in state'); log.error('No model found in state');
throw new Error('No model found in state'); throw new Error('No model found in state');
} }

View File

@ -1,12 +1,11 @@
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
import { zControlNetModel } from 'features/parameters/types/parameterSchemas'; import { zControlNetModel } from 'features/parameters/types/parameterSchemas';
import { ControlNetModelField } from 'services/api/types'; import { ControlNetModelField } from 'services/api/types';
const moduleLog = log.child({ module: 'models' });
export const modelIdToControlNetModelParam = ( export const modelIdToControlNetModelParam = (
controlNetModelId: string controlNetModelId: string
): ControlNetModelField | undefined => { ): ControlNetModelField | undefined => {
const log = logger('models');
const [base_model, model_type, model_name] = controlNetModelId.split('/'); const [base_model, model_type, model_name] = controlNetModelId.split('/');
const result = zControlNetModel.safeParse({ const result = zControlNetModel.safeParse({
@ -15,7 +14,7 @@ export const modelIdToControlNetModelParam = (
}); });
if (!result.success) { if (!result.success) {
moduleLog.error( log.error(
{ {
controlNetModelId, controlNetModelId,
errors: result.error.format(), errors: result.error.format(),

View File

@ -1,11 +1,11 @@
import { logger } from 'app/logging/logger';
import { LoRAModelParam, zLoRAModel } from '../types/parameterSchemas'; import { LoRAModelParam, zLoRAModel } from '../types/parameterSchemas';
import { log } from 'app/logging/useLogger';
const moduleLog = log.child({ module: 'models' });
export const modelIdToLoRAModelParam = ( export const modelIdToLoRAModelParam = (
loraModelId: string loraModelId: string
): LoRAModelParam | undefined => { ): LoRAModelParam | undefined => {
const log = logger('models');
const [base_model, model_type, model_name] = loraModelId.split('/'); const [base_model, model_type, model_name] = loraModelId.split('/');
const result = zLoRAModel.safeParse({ const result = zLoRAModel.safeParse({
@ -14,7 +14,7 @@ export const modelIdToLoRAModelParam = (
}); });
if (!result.success) { if (!result.success) {
moduleLog.error( log.error(
{ {
loraModelId, loraModelId,
errors: result.error.format(), errors: result.error.format(),

View File

@ -1,14 +1,13 @@
import { logger } from 'app/logging/logger';
import { import {
MainModelParam, MainModelParam,
zMainModel, zMainModel,
} from 'features/parameters/types/parameterSchemas'; } from 'features/parameters/types/parameterSchemas';
import { log } from 'app/logging/useLogger';
const moduleLog = log.child({ module: 'models' });
export const modelIdToMainModelParam = ( export const modelIdToMainModelParam = (
mainModelId: string mainModelId: string
): MainModelParam | undefined => { ): MainModelParam | undefined => {
const log = logger('models');
const [base_model, model_type, model_name] = mainModelId.split('/'); const [base_model, model_type, model_name] = mainModelId.split('/');
const result = zMainModel.safeParse({ const result = zMainModel.safeParse({
@ -17,7 +16,7 @@ export const modelIdToMainModelParam = (
}); });
if (!result.success) { if (!result.success) {
moduleLog.error( log.error(
{ {
mainModelId, mainModelId,
errors: result.error.format(), errors: result.error.format(),

View File

@ -1,11 +1,10 @@
import { logger } from 'app/logging/logger';
import { VaeModelParam, zVaeModel } from '../types/parameterSchemas'; import { VaeModelParam, zVaeModel } from '../types/parameterSchemas';
import { log } from 'app/logging/useLogger';
const moduleLog = log.child({ module: 'models' });
export const modelIdToVAEModelParam = ( export const modelIdToVAEModelParam = (
vaeModelId: string vaeModelId: string
): VaeModelParam | undefined => { ): VaeModelParam | undefined => {
const log = logger('models');
const [base_model, model_type, model_name] = vaeModelId.split('/'); const [base_model, model_type, model_name] = vaeModelId.split('/');
const result = zVaeModel.safeParse({ const result = zVaeModel.safeParse({
@ -14,7 +13,7 @@ export const modelIdToVAEModelParam = (
}); });
if (!result.success) { if (!result.success) {
moduleLog.error( log.error(
{ {
vaeModelId, vaeModelId,
errors: result.error.format(), errors: result.error.format(),

View File

@ -12,7 +12,7 @@ import {
useDisclosure, useDisclosure,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { VALID_LOG_LEVELS } from 'app/logging/useLogger'; import { VALID_LOG_LEVELS } from 'app/logging/logger';
import { LOCALSTORAGE_KEYS, LOCALSTORAGE_PREFIX } from 'app/store/constants'; import { LOCALSTORAGE_KEYS, LOCALSTORAGE_PREFIX } from 'app/store/constants';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIButton from 'common/components/IAIButton'; import IAIButton from 'common/components/IAIButton';

View File

@ -1,7 +1,7 @@
import { UseToastOptions } from '@chakra-ui/react'; import { UseToastOptions } from '@chakra-ui/react';
import { PayloadAction, createSlice } from '@reduxjs/toolkit'; import { PayloadAction, createSlice } from '@reduxjs/toolkit';
import { InvokeLogLevel } from 'app/logging/useLogger'; import { InvokeLogLevel } from 'app/logging/logger';
import { userInvoked } from 'app/store/actions'; import { userInvoked } from 'app/store/actions';
import { nodeTemplatesBuilt } from 'features/nodes/store/nodesSlice'; import { nodeTemplatesBuilt } from 'features/nodes/store/nodesSlice';
import { t } from 'i18next'; import { t } from 'i18next';

View File

@ -1,7 +1,5 @@
import { createAsyncThunk } from '@reduxjs/toolkit'; import { createAsyncThunk } from '@reduxjs/toolkit';
import { log } from 'app/logging/useLogger'; import { logger } from 'app/logging/logger';
const schemaLog = log.child({ namespace: 'schema' });
function getCircularReplacer() { function getCircularReplacer() {
const ancestors: Record<string, any>[] = []; const ancestors: Record<string, any>[] = [];
@ -26,11 +24,12 @@ function getCircularReplacer() {
export const receivedOpenAPISchema = createAsyncThunk( export const receivedOpenAPISchema = createAsyncThunk(
'nodes/receivedOpenAPISchema', 'nodes/receivedOpenAPISchema',
async (_, { dispatch, rejectWithValue }) => { async (_, { dispatch, rejectWithValue }) => {
const log = logger('system');
try { try {
const response = await fetch(`openapi.json`); const response = await fetch(`openapi.json`);
const openAPISchema = await response.json(); const openAPISchema = await response.json();
schemaLog.info({ openAPISchema }, 'Received OpenAPI schema'); log.info({ openAPISchema }, 'Received OpenAPI schema');
const schemaJSON = JSON.parse( const schemaJSON = JSON.parse(
JSON.stringify(openAPISchema, getCircularReplacer()) JSON.stringify(openAPISchema, getCircularReplacer())

View File

@ -1,13 +1,10 @@
import { createAppAsyncThunk } from 'app/store/storeUtils';
import { log } from 'app/logging/useLogger';
import { isObject } from 'lodash-es';
import { isAnyOf } from '@reduxjs/toolkit'; import { isAnyOf } from '@reduxjs/toolkit';
import { paths } from 'services/api/schema'; import { createAppAsyncThunk } from 'app/store/storeUtils';
import { isObject } from 'lodash-es';
import { $client } from 'services/api/client'; import { $client } from 'services/api/client';
import { paths } from 'services/api/schema';
import { O } from 'ts-toolbelt'; import { O } from 'ts-toolbelt';
const sessionLog = log.child({ namespace: 'session' });
type CreateSessionArg = { type CreateSessionArg = {
graph: NonNullable< graph: NonNullable<
paths['/api/v1/sessions/']['post']['requestBody'] paths['/api/v1/sessions/']['post']['requestBody']

View File

@ -9,11 +9,6 @@ import {
ModelLoadStartedEvent, ModelLoadStartedEvent,
} from 'services/events/types'; } from 'services/events/types';
// Common socket action payload data
type BaseSocketPayload = {
timestamp: string;
};
// Create actions for each socket // Create actions for each socket
// Middleware and redux can then respond to them as needed // Middleware and redux can then respond to them as needed
@ -22,30 +17,24 @@ type BaseSocketPayload = {
* *
* Do not use. Only for use in middleware. * Do not use. Only for use in middleware.
*/ */
export const socketConnected = createAction<BaseSocketPayload>( export const socketConnected = createAction('socket/socketConnected');
'socket/socketConnected'
);
/** /**
* App-level Socket.IO Connected * App-level Socket.IO Connected
*/ */
export const appSocketConnected = createAction<BaseSocketPayload>( export const appSocketConnected = createAction('socket/appSocketConnected');
'socket/appSocketConnected'
);
/** /**
* Socket.IO Disconnect * Socket.IO Disconnect
* *
* Do not use. Only for use in middleware. * Do not use. Only for use in middleware.
*/ */
export const socketDisconnected = createAction<BaseSocketPayload>( export const socketDisconnected = createAction('socket/socketDisconnected');
'socket/socketDisconnected'
);
/** /**
* App-level Socket.IO Disconnected * App-level Socket.IO Disconnected
*/ */
export const appSocketDisconnected = createAction<BaseSocketPayload>( export const appSocketDisconnected = createAction(
'socket/appSocketDisconnected' 'socket/appSocketDisconnected'
); );
@ -54,145 +43,141 @@ export const appSocketDisconnected = createAction<BaseSocketPayload>(
* *
* Do not use. Only for use in middleware. * Do not use. Only for use in middleware.
*/ */
export const socketSubscribed = createAction< export const socketSubscribed = createAction<{
BaseSocketPayload & { sessionId: string; boardId: string | undefined } sessionId: string;
>('socket/socketSubscribed'); }>('socket/socketSubscribed');
/** /**
* App-level Socket.IO Subscribed * App-level Socket.IO Subscribed
*/ */
export const appSocketSubscribed = createAction< export const appSocketSubscribed = createAction<{
BaseSocketPayload & { sessionId: string; boardId: string | undefined } sessionId: string;
>('socket/appSocketSubscribed'); }>('socket/appSocketSubscribed');
/** /**
* Socket.IO Unsubscribed * Socket.IO Unsubscribed
* *
* Do not use. Only for use in middleware. * Do not use. Only for use in middleware.
*/ */
export const socketUnsubscribed = createAction< export const socketUnsubscribed = createAction<{ sessionId: string }>(
BaseSocketPayload & { sessionId: string } 'socket/socketUnsubscribed'
>('socket/socketUnsubscribed'); );
/** /**
* App-level Socket.IO Unsubscribed * App-level Socket.IO Unsubscribed
*/ */
export const appSocketUnsubscribed = createAction< export const appSocketUnsubscribed = createAction<{ sessionId: string }>(
BaseSocketPayload & { sessionId: string } 'socket/appSocketUnsubscribed'
>('socket/appSocketUnsubscribed'); );
/** /**
* Socket.IO Invocation Started * Socket.IO Invocation Started
* *
* Do not use. Only for use in middleware. * Do not use. Only for use in middleware.
*/ */
export const socketInvocationStarted = createAction< export const socketInvocationStarted = createAction<{
BaseSocketPayload & { data: InvocationStartedEvent } data: InvocationStartedEvent;
>('socket/socketInvocationStarted'); }>('socket/socketInvocationStarted');
/** /**
* App-level Socket.IO Invocation Started * App-level Socket.IO Invocation Started
*/ */
export const appSocketInvocationStarted = createAction< export const appSocketInvocationStarted = createAction<{
BaseSocketPayload & { data: InvocationStartedEvent } data: InvocationStartedEvent;
>('socket/appSocketInvocationStarted'); }>('socket/appSocketInvocationStarted');
/** /**
* Socket.IO Invocation Complete * Socket.IO Invocation Complete
* *
* Do not use. Only for use in middleware. * Do not use. Only for use in middleware.
*/ */
export const socketInvocationComplete = createAction< export const socketInvocationComplete = createAction<{
BaseSocketPayload & { data: InvocationCompleteEvent;
data: InvocationCompleteEvent; }>('socket/socketInvocationComplete');
}
>('socket/socketInvocationComplete');
/** /**
* App-level Socket.IO Invocation Complete * App-level Socket.IO Invocation Complete
*/ */
export const appSocketInvocationComplete = createAction< export const appSocketInvocationComplete = createAction<{
BaseSocketPayload & { data: InvocationCompleteEvent;
data: InvocationCompleteEvent; }>('socket/appSocketInvocationComplete');
}
>('socket/appSocketInvocationComplete');
/** /**
* Socket.IO Invocation Error * Socket.IO Invocation Error
* *
* Do not use. Only for use in middleware. * Do not use. Only for use in middleware.
*/ */
export const socketInvocationError = createAction< export const socketInvocationError = createAction<{
BaseSocketPayload & { data: InvocationErrorEvent } data: InvocationErrorEvent;
>('socket/socketInvocationError'); }>('socket/socketInvocationError');
/** /**
* App-level Socket.IO Invocation Error * App-level Socket.IO Invocation Error
*/ */
export const appSocketInvocationError = createAction< export const appSocketInvocationError = createAction<{
BaseSocketPayload & { data: InvocationErrorEvent } data: InvocationErrorEvent;
>('socket/appSocketInvocationError'); }>('socket/appSocketInvocationError');
/** /**
* Socket.IO Graph Execution State Complete * Socket.IO Graph Execution State Complete
* *
* Do not use. Only for use in middleware. * Do not use. Only for use in middleware.
*/ */
export const socketGraphExecutionStateComplete = createAction< export const socketGraphExecutionStateComplete = createAction<{
BaseSocketPayload & { data: GraphExecutionStateCompleteEvent } data: GraphExecutionStateCompleteEvent;
>('socket/socketGraphExecutionStateComplete'); }>('socket/socketGraphExecutionStateComplete');
/** /**
* App-level Socket.IO Graph Execution State Complete * App-level Socket.IO Graph Execution State Complete
*/ */
export const appSocketGraphExecutionStateComplete = createAction< export const appSocketGraphExecutionStateComplete = createAction<{
BaseSocketPayload & { data: GraphExecutionStateCompleteEvent } data: GraphExecutionStateCompleteEvent;
>('socket/appSocketGraphExecutionStateComplete'); }>('socket/appSocketGraphExecutionStateComplete');
/** /**
* Socket.IO Generator Progress * Socket.IO Generator Progress
* *
* Do not use. Only for use in middleware. * Do not use. Only for use in middleware.
*/ */
export const socketGeneratorProgress = createAction< export const socketGeneratorProgress = createAction<{
BaseSocketPayload & { data: GeneratorProgressEvent } data: GeneratorProgressEvent;
>('socket/socketGeneratorProgress'); }>('socket/socketGeneratorProgress');
/** /**
* App-level Socket.IO Generator Progress * App-level Socket.IO Generator Progress
*/ */
export const appSocketGeneratorProgress = createAction< export const appSocketGeneratorProgress = createAction<{
BaseSocketPayload & { data: GeneratorProgressEvent } data: GeneratorProgressEvent;
>('socket/appSocketGeneratorProgress'); }>('socket/appSocketGeneratorProgress');
/** /**
* Socket.IO Model Load Started * Socket.IO Model Load Started
* *
* Do not use. Only for use in middleware. * Do not use. Only for use in middleware.
*/ */
export const socketModelLoadStarted = createAction< export const socketModelLoadStarted = createAction<{
BaseSocketPayload & { data: ModelLoadStartedEvent } data: ModelLoadStartedEvent;
>('socket/socketModelLoadStarted'); }>('socket/socketModelLoadStarted');
/** /**
* App-level Model Load Started * App-level Model Load Started
*/ */
export const appSocketModelLoadStarted = createAction< export const appSocketModelLoadStarted = createAction<{
BaseSocketPayload & { data: ModelLoadStartedEvent } data: ModelLoadStartedEvent;
>('socket/appSocketModelLoadStarted'); }>('socket/appSocketModelLoadStarted');
/** /**
* Socket.IO Model Load Started * Socket.IO Model Load Started
* *
* Do not use. Only for use in middleware. * Do not use. Only for use in middleware.
*/ */
export const socketModelLoadCompleted = createAction< export const socketModelLoadCompleted = createAction<{
BaseSocketPayload & { data: ModelLoadCompletedEvent } data: ModelLoadCompletedEvent;
>('socket/socketModelLoadCompleted'); }>('socket/socketModelLoadCompleted');
/** /**
* App-level Model Load Completed * App-level Model Load Completed
*/ */
export const appSocketModelLoadCompleted = createAction< export const appSocketModelLoadCompleted = createAction<{
BaseSocketPayload & { data: ModelLoadCompletedEvent } data: ModelLoadCompletedEvent;
>('socket/appSocketModelLoadCompleted'); }>('socket/appSocketModelLoadCompleted');

View File

@ -1,20 +1,14 @@
import { Middleware, MiddlewareAPI } from '@reduxjs/toolkit'; import { Middleware, MiddlewareAPI } from '@reduxjs/toolkit';
import { Socket, io } from 'socket.io-client';
import { AppThunkDispatch, RootState } from 'app/store/store'; import { AppThunkDispatch, RootState } from 'app/store/store';
import { getTimestamp } from 'common/util/getTimestamp'; import { $authToken, $baseUrl } from 'services/api/client';
import { sessionCreated } from 'services/api/thunks/session'; import { sessionCreated } from 'services/api/thunks/session';
import { import {
ClientToServerEvents, ClientToServerEvents,
ServerToClientEvents, ServerToClientEvents,
} from 'services/events/types'; } from 'services/events/types';
import { socketSubscribed, socketUnsubscribed } from './actions';
// import { OpenAPI } from 'services/api/types';
import { log } from 'app/logging/useLogger';
import { $authToken, $baseUrl } from 'services/api/client';
import { setEventListeners } from 'services/events/util/setEventListeners'; import { setEventListeners } from 'services/events/util/setEventListeners';
import { Socket, io } from 'socket.io-client';
const socketioLog = log.child({ namespace: 'socketio' }); import { socketSubscribed, socketUnsubscribed } from './actions';
export const socketMiddleware = () => { export const socketMiddleware = () => {
let areListenersSet = false; let areListenersSet = false;
@ -58,7 +52,7 @@ export const socketMiddleware = () => {
// Set listeners for `connect` and `disconnect` events once // Set listeners for `connect` and `disconnect` events once
// Must happen in middleware to get access to `dispatch` // Must happen in middleware to get access to `dispatch`
if (!areListenersSet) { if (!areListenersSet) {
setEventListeners({ storeApi, socket, log: socketioLog }); setEventListeners({ storeApi, socket });
areListenersSet = true; areListenersSet = true;
@ -77,7 +71,6 @@ export const socketMiddleware = () => {
dispatch( dispatch(
socketUnsubscribed({ socketUnsubscribed({
sessionId: oldSessionId, sessionId: oldSessionId,
timestamp: getTimestamp(),
}) })
); );
} }
@ -87,8 +80,6 @@ export const socketMiddleware = () => {
dispatch( dispatch(
socketSubscribed({ socketSubscribed({
sessionId: sessionId, sessionId: sessionId,
timestamp: getTimestamp(),
boardId: getState().gallery.selectedBoardId,
}) })
); );
} }

View File

@ -1,42 +1,40 @@
import { MiddlewareAPI } from '@reduxjs/toolkit'; import { MiddlewareAPI } from '@reduxjs/toolkit';
import { logger } from 'app/logging/logger';
import { AppDispatch, RootState } from 'app/store/store'; import { AppDispatch, RootState } from 'app/store/store';
import { getTimestamp } from 'common/util/getTimestamp';
import { Socket } from 'socket.io-client'; import { Socket } from 'socket.io-client';
import { makeToast } from '../../../app/components/Toaster';
import { addToast } from '../../../features/system/store/systemSlice';
import { import {
socketConnected,
socketDisconnected,
socketGeneratorProgress, socketGeneratorProgress,
socketGraphExecutionStateComplete, socketGraphExecutionStateComplete,
socketInvocationComplete, socketInvocationComplete,
socketInvocationError, socketInvocationError,
socketInvocationStarted, socketInvocationStarted,
socketConnected,
socketDisconnected,
socketSubscribed,
socketModelLoadStarted,
socketModelLoadCompleted, socketModelLoadCompleted,
socketModelLoadStarted,
socketSubscribed,
} from '../actions'; } from '../actions';
import { ClientToServerEvents, ServerToClientEvents } from '../types'; import { ClientToServerEvents, ServerToClientEvents } from '../types';
import { Logger } from 'roarr';
import { JsonObject } from 'roarr/dist/types';
import { makeToast } from '../../../app/components/Toaster';
import { addToast } from '../../../features/system/store/systemSlice';
type SetEventListenersArg = { type SetEventListenersArg = {
socket: Socket<ServerToClientEvents, ClientToServerEvents>; socket: Socket<ServerToClientEvents, ClientToServerEvents>;
storeApi: MiddlewareAPI<AppDispatch, RootState>; storeApi: MiddlewareAPI<AppDispatch, RootState>;
log: Logger<JsonObject>;
}; };
export const setEventListeners = (arg: SetEventListenersArg) => { export const setEventListeners = (arg: SetEventListenersArg) => {
const { socket, storeApi, log } = arg; const { socket, storeApi } = arg;
const { dispatch, getState } = storeApi; const { dispatch, getState } = storeApi;
/** /**
* Connect * Connect
*/ */
socket.on('connect', () => { socket.on('connect', () => {
const log = logger('socketio');
log.debug('Connected'); log.debug('Connected');
dispatch(socketConnected({ timestamp: getTimestamp() })); dispatch(socketConnected());
const { sessionId } = getState().system; const { sessionId } = getState().system;
@ -45,8 +43,6 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
dispatch( dispatch(
socketSubscribed({ socketSubscribed({
sessionId, sessionId,
timestamp: getTimestamp(),
boardId: getState().gallery.selectedBoardId,
}) })
); );
} }
@ -73,28 +69,28 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
* Disconnect * Disconnect
*/ */
socket.on('disconnect', () => { socket.on('disconnect', () => {
dispatch(socketDisconnected({ timestamp: getTimestamp() })); dispatch(socketDisconnected());
}); });
/** /**
* Invocation started * Invocation started
*/ */
socket.on('invocation_started', (data) => { socket.on('invocation_started', (data) => {
dispatch(socketInvocationStarted({ data, timestamp: getTimestamp() })); dispatch(socketInvocationStarted({ data }));
}); });
/** /**
* Generator progress * Generator progress
*/ */
socket.on('generator_progress', (data) => { socket.on('generator_progress', (data) => {
dispatch(socketGeneratorProgress({ data, timestamp: getTimestamp() })); dispatch(socketGeneratorProgress({ data }));
}); });
/** /**
* Invocation error * Invocation error
*/ */
socket.on('invocation_error', (data) => { socket.on('invocation_error', (data) => {
dispatch(socketInvocationError({ data, timestamp: getTimestamp() })); dispatch(socketInvocationError({ data }));
}); });
/** /**
@ -104,7 +100,6 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
dispatch( dispatch(
socketInvocationComplete({ socketInvocationComplete({
data, data,
timestamp: getTimestamp(),
}) })
); );
}); });
@ -116,7 +111,6 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
dispatch( dispatch(
socketGraphExecutionStateComplete({ socketGraphExecutionStateComplete({
data, data,
timestamp: getTimestamp(),
}) })
); );
}); });
@ -128,7 +122,6 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
dispatch( dispatch(
socketModelLoadStarted({ socketModelLoadStarted({
data, data,
timestamp: getTimestamp(),
}) })
); );
}); });
@ -140,7 +133,6 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
dispatch( dispatch(
socketModelLoadCompleted({ socketModelLoadCompleted({
data, data,
timestamp: getTimestamp(),
}) })
); );
}); });

View File

@ -1511,6 +1511,11 @@
resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz#c3ec604a0b54b9a9b87e9735dfc59e1a5da6a5fb" resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz#c3ec604a0b54b9a9b87e9735dfc59e1a5da6a5fb"
integrity sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug== integrity sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==
"@nanostores/react@^0.7.1":
version "0.7.1"
resolved "https://registry.yarnpkg.com/@nanostores/react/-/react-0.7.1.tgz#e0446f5cacc9fa53448c454f5d00ddb0f906a37a"
integrity sha512-EXQg9N4MdI4eJQz/AZLIx3hxQ6BuBmV4Q55bCd5YCSgEOAW7tGTsIZxpRXxvxLXzflNvHTBvfrDNY38TlSVBkQ==
"@nodelib/fs.scandir@2.1.5": "@nodelib/fs.scandir@2.1.5":
version "2.1.5" version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"