From a4c258e9ec138b377bd2b49d54ce0a09cf5087a8 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sat, 29 Apr 2023 16:50:54 +1000 Subject: [PATCH] feat(ui): add roarr logger --- invokeai/frontend/web/package.json | 8 +- invokeai/frontend/web/public/locales/en.json | 3 +- .../frontend/web/src/app/components/App.tsx | 6 +- .../frontend/web/src/app/logging/useLogger.ts | 93 +++++++++++++ invokeai/frontend/web/src/app/store/store.ts | 3 +- .../SettingsModal/SettingsModal.tsx | 21 ++- .../src/features/system/store/systemSlice.ts | 14 +- .../web/src/services/events/middleware.ts | 28 ++-- .../services/events/util/setEventListeners.ts | 9 +- .../web/src/services/thunks/gallery.ts | 7 + .../frontend/web/src/services/thunks/image.ts | 14 ++ .../frontend/web/src/services/thunks/model.ts | 8 +- .../web/src/services/thunks/schema.ts | 9 +- .../web/src/services/thunks/session.ts | 15 ++- invokeai/frontend/web/yarn.lock | 122 +++++++++++++++++- 15 files changed, 328 insertions(+), 32 deletions(-) create mode 100644 invokeai/frontend/web/src/app/logging/useLogger.ts diff --git a/invokeai/frontend/web/package.json b/invokeai/frontend/web/package.json index 45f6b8e044..6ee6a9c8f4 100644 --- a/invokeai/frontend/web/package.json +++ b/invokeai/frontend/web/package.json @@ -65,6 +65,7 @@ "@emotion/styled": "^11.10.6", "@fontsource/inter": "^4.5.15", "@reduxjs/toolkit": "^1.9.5", + "@roarr/browser-log-writer": "^1.1.5", "chakra-ui-contextmenu": "^1.0.5", "dateformat": "^5.0.3", "formik": "^2.2.9", @@ -93,17 +94,19 @@ "redux-deep-persist": "^1.0.7", "redux-dynamic-middlewares": "^2.2.0", "redux-persist": "^6.0.0", + "roarr": "^7.15.0", "socket.io-client": "^4.6.0", "use-image": "^1.1.0", "uuid": "^9.0.0" }, "peerDependencies": { + "@chakra-ui/cli": "^2.4.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "ts-toolbelt": "^9.6.0", - "@chakra-ui/cli": "^2.4.0" + "ts-toolbelt": "^9.6.0" }, "devDependencies": { + "@chakra-ui/cli": "^2.4.0", "@types/dateformat": "^5.0.0", "@types/lodash-es": "^4.14.194", "@types/node": "^18.16.2", @@ -116,7 +119,6 @@ "@vitejs/plugin-react-swc": "^3.3.0", "axios": "^1.4.0", "babel-plugin-transform-imports": "^2.0.0", - "@chakra-ui/cli": "^2.4.0", "concurrently": "^8.0.1", "eslint": "^8.39.0", "eslint-config-prettier": "^8.8.0", diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index e5245c7ad5..d52f3c38c7 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -530,7 +530,8 @@ "resetWebUI": "Reset Web UI", "resetWebUIDesc1": "Resetting the web UI only resets the browser's local cache of your images and remembered settings. It does not delete any images from disk.", "resetWebUIDesc2": "If images aren't showing up in the gallery or something else isn't working, please try resetting before submitting an issue on GitHub.", - "resetComplete": "Web UI has been reset. Refresh the page to reload." + "resetComplete": "Web UI has been reset. Refresh the page to reload.", + "consoleLogLevel": "Console Log Level" }, "toast": { "serverError": "Server Error", diff --git a/invokeai/frontend/web/src/app/components/App.tsx b/invokeai/frontend/web/src/app/components/App.tsx index b33a7cac3f..b42c8a9c1a 100644 --- a/invokeai/frontend/web/src/app/components/App.tsx +++ b/invokeai/frontend/web/src/app/components/App.tsx @@ -27,6 +27,7 @@ import { PartialAppConfig } from 'app/types/invokeai'; import { useGlobalHotkeys } from 'common/hooks/useGlobalHotkeys'; import { configChanged } from 'features/system/store/configSlice'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; +import { useLogger } from 'app/logging/useLogger'; const DEFAULT_CONFIG = {}; @@ -37,6 +38,7 @@ interface Props extends PropsWithChildren { const App = ({ config = DEFAULT_CONFIG, children }: Props) => { useToastWatcher(); useGlobalHotkeys(); + const log = useLogger(); const currentTheme = useAppSelector((state) => state.ui.currentTheme); @@ -50,9 +52,9 @@ const App = ({ config = DEFAULT_CONFIG, children }: Props) => { const dispatch = useAppDispatch(); useEffect(() => { - console.log('Received config: ', config); + log.info({ namespace: 'App', data: config }, 'Received config'); dispatch(configChanged(config)); - }, [dispatch, config]); + }, [dispatch, config, log]); useEffect(() => { setColorMode(['light'].includes(currentTheme) ? 'light' : 'dark'); diff --git a/invokeai/frontend/web/src/app/logging/useLogger.ts b/invokeai/frontend/web/src/app/logging/useLogger.ts new file mode 100644 index 0000000000..ef1b27ad6b --- /dev/null +++ b/invokeai/frontend/web/src/app/logging/useLogger.ts @@ -0,0 +1,93 @@ +import { createSelector } from '@reduxjs/toolkit'; +import { useAppSelector } from 'app/store/storeHooks'; +import { systemSelector } from 'features/system/store/systemSelectors'; +import { isEqual } from 'lodash-es'; +import { useEffect } from 'react'; +import { LogLevelName, ROARR, Roarr } from 'roarr'; +import { createLogWriter } from '@roarr/browser-log-writer'; + +// 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 = { + trace: 10, + debug: 20, + info: 30, + warn: 40, + error: 50, + fatal: 60, +}; + +export const VALID_LOG_LEVELS = [ + 'trace', + 'debug', + 'info', + 'warn', + 'error', + 'fatal', + 'none', +] as const; + +export type InvokeLogLevel = (typeof VALID_LOG_LEVELS)[number]; + +const selector = createSelector( + systemSelector, + (system) => { + const { app_version, consoleLogLevel } = system; + + return { + version: app_version, + consoleLogLevel, + }; + }, + { + memoizeOptions: { + resultEqualityCheck: isEqual, + }, + } +); + +export const useLogger = () => { + const { version, consoleLogLevel } = useAppSelector(selector); + + // The provided Roarr browser log writer uses localStorage to config logging to console + useEffect(() => { + if (consoleLogLevel === 'none') { + // Disable console log output + localStorage.setItem('ROARR_LOG', 'false'); + } else { + // Enable console log output + localStorage.setItem('ROARR_LOG', 'true'); + + // Use a filter to show only logs of the given level + localStorage.setItem( + 'ROARR_FILTER', + `context.logLevel:>=${LOG_LEVEL_MAP[consoleLogLevel]}` + ); + } + ROARR.write = createLogWriter(); + }, [consoleLogLevel]); + + // Update the module-scoped logger context as needed + useEffect(() => { + const newContext: Record = { + ...baseContext, + }; + + if (version) { + newContext.version = version; + } + + log = Roarr.child(newContext); + }, [version]); + + // Use the logger within components - no different than just importing it directly + return log; +}; diff --git a/invokeai/frontend/web/src/app/store/store.ts b/invokeai/frontend/web/src/app/store/store.ts index 8a805d6f16..627c4f0063 100644 --- a/invokeai/frontend/web/src/app/store/store.ts +++ b/invokeai/frontend/web/src/app/store/store.ts @@ -28,7 +28,7 @@ import { lightboxDenylist } from 'features/lightbox/store/lightboxPersistDenylis import { modelsDenylist } from 'features/system/store/modelsPersistDenylist'; import { nodesDenylist } from 'features/nodes/store/nodesPersistDenylist'; import { postprocessingDenylist } from 'features/parameters/store/postprocessingPersistDenylist'; -import { systemDenylist } from 'features/system/store/systemPersistsDenylist'; +import { systemDenylist } from 'features/system/store/systemPersistDenylist'; import { uiDenylist } from 'features/ui/store/uiPersistDenylist'; /** @@ -82,7 +82,6 @@ const rootPersistConfig = getPersistConfig({ 'hotkeys', 'config', ], - debounce: 300, }); const persistedReducer = persistReducer(rootPersistConfig, rootReducer); diff --git a/invokeai/frontend/web/src/features/system/components/SettingsModal/SettingsModal.tsx b/invokeai/frontend/web/src/features/system/components/SettingsModal/SettingsModal.tsx index 3edd6229a4..da4dbe2572 100644 --- a/invokeai/frontend/web/src/features/system/components/SettingsModal/SettingsModal.tsx +++ b/invokeai/frontend/web/src/features/system/components/SettingsModal/SettingsModal.tsx @@ -23,6 +23,7 @@ import IAISelect from 'common/components/IAISelect'; import IAISwitch from 'common/components/IAISwitch'; import { systemSelector } from 'features/system/store/systemSelectors'; import { + consoleLogLevelChanged, InProgressImageType, setEnableImageDebugging, setSaveIntermediatesInterval, @@ -39,8 +40,10 @@ import { import { UIState } from 'features/ui/store/uiTypes'; import { isEqual, map } from 'lodash-es'; import { persistor } from 'app/store/persistor'; -import { ChangeEvent, cloneElement, ReactElement } from 'react'; +import { ChangeEvent, cloneElement, ReactElement, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; +import { InvokeLogLevel, VALID_LOG_LEVELS } from 'app/logging/useLogger'; +import { LogLevelName } from 'roarr'; const selector = createSelector( [systemSelector, uiSelector], @@ -52,6 +55,7 @@ const selector = createSelector( model_list, saveIntermediatesInterval, enableImageDebugging, + consoleLogLevel, } = system; const { shouldUseCanvasBetaLayout, shouldUseSliders } = ui; @@ -65,6 +69,7 @@ const selector = createSelector( enableImageDebugging, shouldUseCanvasBetaLayout, shouldUseSliders, + consoleLogLevel, }; }, { @@ -116,6 +121,7 @@ const SettingsModal = ({ children }: SettingsModalProps) => { enableImageDebugging, shouldUseCanvasBetaLayout, shouldUseSliders, + consoleLogLevel, } = useAppSelector(selector); /** @@ -135,6 +141,13 @@ const SettingsModal = ({ children }: SettingsModalProps) => { dispatch(setSaveIntermediatesInterval(value)); }; + const handleLogLevelChanged = useCallback( + (e: ChangeEvent) => { + dispatch(consoleLogLevelChanged(e.target.value as LogLevelName)); + }, + [dispatch] + ); + return ( <> {cloneElement(children, { @@ -211,6 +224,12 @@ const SettingsModal = ({ children }: SettingsModalProps) => { Developer + ) => { state.subscribedNodeIds = action.payload; }, + consoleLogLevelChanged: (state, action: PayloadAction) => { + state.consoleLogLevel = action.payload; + }, }, extraReducers(builder) { /** @@ -353,7 +363,6 @@ export const systemSlice = createSlice({ */ builder.addCase(socketSubscribed, (state, action) => { state.sessionId = action.payload.sessionId; - console.log(`Subscribed to session ${action.payload.sessionId}`); }); /** @@ -374,7 +383,7 @@ export const systemSlice = createSlice({ state.log.push({ timestamp, message: `Connected to server`, - level: 'info', + level: 'error', }); }); @@ -562,6 +571,7 @@ export const { scheduledCancelAborted, cancelTypeChanged, subscribedNodeIdsSet, + consoleLogLevelChanged, } = systemSlice.actions; export default systemSlice.reducer; diff --git a/invokeai/frontend/web/src/services/events/middleware.ts b/invokeai/frontend/web/src/services/events/middleware.ts index 824e48648c..0b52ae8f0b 100644 --- a/invokeai/frontend/web/src/services/events/middleware.ts +++ b/invokeai/frontend/web/src/services/events/middleware.ts @@ -6,13 +6,9 @@ import { ServerToClientEvents, } from 'services/events/types'; import { - generatorProgress, invocationComplete, - invocationError, - invocationStarted, socketConnected, socketDisconnected, - socketReset, socketSubscribed, socketUnsubscribed, } from './actions'; @@ -25,7 +21,6 @@ import { getTimestamp } from 'common/util/getTimestamp'; import { sessionInvoked, isFulfilledSessionCreatedAction, - sessionCanceled, } from 'services/thunks/session'; import { OpenAPI } from 'services/api'; import { receivedModels } from 'services/thunks/model'; @@ -33,6 +28,9 @@ import { receivedOpenAPISchema } from 'services/thunks/schema'; import { isImageOutput } from 'services/types/guards'; import { imageReceived, thumbnailReceived } from 'services/thunks/image'; import { setEventListeners } from 'services/events/util/setEventListeners'; +import { log } from 'app/logging/useLogger'; + +const moduleLog = log.child({ namespace: 'socketio' }); export const socketMiddleware = () => { let areListenersSet = false; @@ -91,6 +89,8 @@ export const socketMiddleware = () => { // Must happen in middleware to get access to `dispatch` if (!areListenersSet) { socket.on('connect', () => { + moduleLog.debug('Connected'); + dispatch(socketConnected({ timestamp: getTimestamp() })); const { results, uploads, models, nodes, config, system } = @@ -116,7 +116,10 @@ export const socketMiddleware = () => { } if (system.sessionId) { - console.log(`Re-subscribing to session ${system.sessionId}`); + const sessionLog = moduleLog.child({ sessionId: system.sessionId }); + + sessionLog.debug('Re-subscribe'); + socket.emit('subscribe', { session: system.sessionId }); dispatch( socketSubscribed({ @@ -124,11 +127,12 @@ export const socketMiddleware = () => { timestamp: getTimestamp(), }) ); - setEventListeners({ socket, store }); + setEventListeners({ socket, store, sessionLog }); } }); socket.on('disconnect', () => { + moduleLog.debug('Disconnected'); dispatch(socketDisconnected({ timestamp: getTimestamp() })); }); @@ -140,6 +144,8 @@ export const socketMiddleware = () => { // Everything else only happens once we have created a session if (isFulfilledSessionCreatedAction(action)) { + const sessionId = action.payload.id; + const sessionLog = moduleLog.child({ sessionId }); const oldSessionId = getState().system.sessionId; // const subscribedNodeIds = getState().system.subscribedNodeIds; @@ -152,6 +158,9 @@ export const socketMiddleware = () => { // }; if (oldSessionId) { + sessionLog + .child({ oldSessionId }) + .debug('Unsubscribe from old session'); // Unsubscribe when invocations complete socket.emit('unsubscribe', { session: oldSessionId, @@ -176,8 +185,7 @@ export const socketMiddleware = () => { }); } - const sessionId = action.payload.id; - + sessionLog.debug('Subscribe'); socket.emit('subscribe', { session: sessionId }); dispatch( socketSubscribed({ @@ -185,7 +193,7 @@ export const socketMiddleware = () => { timestamp: getTimestamp(), }) ); - setEventListeners({ socket, store }); + setEventListeners({ socket, store, sessionLog }); // Finally we actually invoke the session, starting processing dispatch(sessionInvoked({ sessionId })); diff --git a/invokeai/frontend/web/src/services/events/util/setEventListeners.ts b/invokeai/frontend/web/src/services/events/util/setEventListeners.ts index 950cfb4083..b7599df9cc 100644 --- a/invokeai/frontend/web/src/services/events/util/setEventListeners.ts +++ b/invokeai/frontend/web/src/services/events/util/setEventListeners.ts @@ -10,29 +10,36 @@ import { invocationStarted, } from '../actions'; import { ClientToServerEvents, ServerToClientEvents } from '../types'; +import { Logger } from 'roarr'; +import { JsonObject } from 'roarr/dist/types'; type SetEventListenersArg = { socket: Socket; store: MiddlewareAPI; + sessionLog: Logger; }; export const setEventListeners = (arg: SetEventListenersArg) => { - const { socket, store } = arg; + const { socket, store, sessionLog } = arg; const { dispatch, getState } = store; // Set up listeners for the present subscription socket.on('invocation_started', (data) => { + sessionLog.child({ data }).info('Invocation started'); dispatch(invocationStarted({ data, timestamp: getTimestamp() })); }); socket.on('generator_progress', (data) => { + sessionLog.child({ data }).trace('Generator progress'); dispatch(generatorProgress({ data, timestamp: getTimestamp() })); }); socket.on('invocation_error', (data) => { + sessionLog.child({ data }).error('Invocation error'); dispatch(invocationError({ data, timestamp: getTimestamp() })); }); socket.on('invocation_complete', (data) => { + sessionLog.child({ data }).info('Invocation complete'); const sessionId = data.graph_execution_state_id; const { cancelType, isCancelScheduled } = getState().system; diff --git a/invokeai/frontend/web/src/services/thunks/gallery.ts b/invokeai/frontend/web/src/services/thunks/gallery.ts index 4361ce1499..824baa1bca 100644 --- a/invokeai/frontend/web/src/services/thunks/gallery.ts +++ b/invokeai/frontend/web/src/services/thunks/gallery.ts @@ -1,8 +1,11 @@ +import { log } from 'app/logging/useLogger'; import { createAppAsyncThunk } from 'app/store/storeUtils'; import { ImagesService } from 'services/api'; export const IMAGES_PER_PAGE = 20; +const galleryLog = log.child({ namespace: 'gallery' }); + export const receivedResultImagesPage = createAppAsyncThunk( 'results/receivedResultImagesPage', async (_arg, { getState }) => { @@ -12,6 +15,8 @@ export const receivedResultImagesPage = createAppAsyncThunk( perPage: IMAGES_PER_PAGE, }); + galleryLog.info({ response }, 'Received page of results images'); + return response; } ); @@ -25,6 +30,8 @@ export const receivedUploadImagesPage = createAppAsyncThunk( perPage: IMAGES_PER_PAGE, }); + galleryLog.info({ response }, 'Received page of uploads images'); + return response; } ); diff --git a/invokeai/frontend/web/src/services/thunks/image.ts b/invokeai/frontend/web/src/services/thunks/image.ts index d9fdd1c589..7010e1565a 100644 --- a/invokeai/frontend/web/src/services/thunks/image.ts +++ b/invokeai/frontend/web/src/services/thunks/image.ts @@ -1,10 +1,13 @@ import { isFulfilled, isRejected } from '@reduxjs/toolkit'; +import { log } from 'app/logging/useLogger'; import { createAppAsyncThunk } from 'app/store/storeUtils'; import { imageSelected } from 'features/gallery/store/gallerySlice'; import { clamp } from 'lodash-es'; import { ImagesService } from 'services/api'; import { getHeaders } from 'services/util/getHeaders'; +const imagesLog = log.child({ namespace: 'image' }); + type ImageReceivedArg = Parameters<(typeof ImagesService)['getImage']>[0]; /** @@ -14,6 +17,9 @@ export const imageReceived = createAppAsyncThunk( 'api/imageReceived', async (arg: ImageReceivedArg, _thunkApi) => { const response = await ImagesService.getImage(arg); + + imagesLog.info({ arg, response }, 'Received image'); + return response; } ); @@ -29,6 +35,9 @@ export const thumbnailReceived = createAppAsyncThunk( 'api/thumbnailReceived', async (arg: ThumbnailReceivedArg, _thunkApi) => { const response = await ImagesService.getThumbnail(arg); + + imagesLog.info({ arg, response }, 'Received thumbnail'); + return response; } ); @@ -43,6 +52,9 @@ export const imageUploaded = createAppAsyncThunk( async (arg: ImageUploadedArg, _thunkApi) => { const response = await ImagesService.uploadImage(arg); const { location } = getHeaders(response); + + imagesLog.info({ arg: '', response, location }, 'Image uploaded'); + return { response, location }; } ); @@ -96,6 +108,8 @@ export const imageDeleted = createAppAsyncThunk( const response = await ImagesService.deleteImage(arg); + imagesLog.info({ arg, response }, 'Image deleted'); + return response; } ); diff --git a/invokeai/frontend/web/src/services/thunks/model.ts b/invokeai/frontend/web/src/services/thunks/model.ts index a4aac7563d..78d74569dc 100644 --- a/invokeai/frontend/web/src/services/thunks/model.ts +++ b/invokeai/frontend/web/src/services/thunks/model.ts @@ -1,14 +1,18 @@ +import { log } from 'app/logging/useLogger'; import { createAppAsyncThunk } from 'app/store/storeUtils'; import { Model } from 'features/system/store/modelSlice'; import { reduce } from 'lodash-es'; import { ModelsService } from 'services/api'; +const models = log.child({ namespace: 'model' }); + export const IMAGES_PER_PAGE = 20; export const receivedModels = createAppAsyncThunk( 'models/receivedModels', - async (_arg) => { + async (_) => { const response = await ModelsService.listModels(); + const deserializedModels = reduce( response.models, (modelsAccumulator, model, modelName) => { @@ -19,6 +23,8 @@ export const receivedModels = createAppAsyncThunk( {} as Record ); + models.info({ response }, 'Received models'); + return deserializedModels; } ); diff --git a/invokeai/frontend/web/src/services/thunks/schema.ts b/invokeai/frontend/web/src/services/thunks/schema.ts index 7da8514427..bc93fa0fae 100644 --- a/invokeai/frontend/web/src/services/thunks/schema.ts +++ b/invokeai/frontend/web/src/services/thunks/schema.ts @@ -1,16 +1,19 @@ import { createAsyncThunk } from '@reduxjs/toolkit'; +import { log } from 'app/logging/useLogger'; import { parsedOpenAPISchema } from 'features/nodes/store/nodesSlice'; import { OpenAPIV3 } from 'openapi-types'; +const schemaLog = log.child({ namespace: 'schema' }); + export const receivedOpenAPISchema = createAsyncThunk( 'nodes/receivedOpenAPISchema', async (_, { dispatch }): Promise => { const response = await fetch(`openapi.json`); - const openAPISchema = (await response.json()) as OpenAPIV3.Document; + const openAPISchema = await response.json(); - console.debug('OpenAPI schema: ', openAPISchema); + schemaLog.info({ openAPISchema }, 'Received OpenAPI schema'); - dispatch(parsedOpenAPISchema(openAPISchema)); + dispatch(parsedOpenAPISchema(openAPISchema as OpenAPIV3.Document)); return openAPISchema; } diff --git a/invokeai/frontend/web/src/services/thunks/session.ts b/invokeai/frontend/web/src/services/thunks/session.ts index ba796f7467..ff9592e8c8 100644 --- a/invokeai/frontend/web/src/services/thunks/session.ts +++ b/invokeai/frontend/web/src/services/thunks/session.ts @@ -3,6 +3,9 @@ import { SessionsService } from 'services/api'; import { buildLinearGraph as buildGenerateGraph } from 'features/nodes/util/linearGraphBuilder/buildLinearGraph'; import { isAnyOf, isFulfilled } from '@reduxjs/toolkit'; import { buildNodesGraph } from 'features/nodes/util/nodesGraphBuilder/buildNodesGraph'; +import { log } from 'app/logging/useLogger'; + +const sessionLog = log.child({ namespace: 'session' }); export const generateGraphBuilt = createAppAsyncThunk( 'api/generateGraphBuilt', @@ -43,12 +46,12 @@ type SessionCreatedArg = { export const sessionCreated = createAppAsyncThunk( 'api/sessionCreated', async (arg: SessionCreatedArg, { dispatch, getState }) => { - console.log('Session created, graph: ', arg.graph); - const response = await SessionsService.createSession({ requestBody: arg.graph, }); + sessionLog.info({ arg, response }, 'Session created'); + return response; } ); @@ -74,6 +77,8 @@ export const nodeAdded = createAppAsyncThunk( sessionId: arg.sessionId, }); + sessionLog.info({ arg, response }, 'Node added'); + return response; } ); @@ -91,6 +96,8 @@ export const sessionInvoked = createAppAsyncThunk( all: true, }); + sessionLog.info({ arg, response }, 'Session invoked'); + return response; } ); @@ -111,6 +118,8 @@ export const sessionCanceled = createAppAsyncThunk( sessionId, }); + sessionLog.info({ arg, response }, 'Session canceled'); + return response; } ); @@ -127,6 +136,8 @@ export const listedSessions = createAppAsyncThunk( async (arg: SessionsListedArg, _thunkApi) => { const response = await SessionsService.listSessions(arg); + sessionLog.info({ arg, response }, 'Sessions listed'); + return response; } ); diff --git a/invokeai/frontend/web/yarn.lock b/invokeai/frontend/web/yarn.lock index b0811ad877..f117d4f2de 100644 --- a/invokeai/frontend/web/yarn.lock +++ b/invokeai/frontend/web/yarn.lock @@ -1421,6 +1421,15 @@ redux-thunk "^2.4.2" reselect "^4.1.8" +"@roarr/browser-log-writer@^1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@roarr/browser-log-writer/-/browser-log-writer-1.1.5.tgz#755ff62ddaa297bb3488067408a7085db382352b" + integrity sha512-yLn//DRjh1/rUgZpZkwmT/5RqHYfkdOwGXWXnKBR3l/HE04DIhSVeYin3sc8aWHBa7s7WglQpYX/uw/WI6POpw== + dependencies: + boolean "^3.1.4" + globalthis "^1.0.2" + liqe "^3.6.0" + "@rollup/pluginutils@^4.2.1": version "4.2.1" resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" @@ -2077,7 +2086,7 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv@^6.10.0, ajv@^6.12.4, ajv@~6.12.6: +ajv@^6.10.0, ajv@^6.11.0, ajv@^6.12.4, ajv@~6.12.6: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -2307,6 +2316,11 @@ bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" +boolean@^3.1.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b" + integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw== + boxen@^5.0.0: version "5.1.2" resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" @@ -2609,7 +2623,7 @@ commander@^10.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== -commander@^2.16.0, commander@^2.20.0, commander@^2.20.3, commander@^2.8.1: +commander@^2.16.0, commander@^2.19.0, commander@^2.20.0, commander@^2.20.3, commander@^2.8.1: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -2828,6 +2842,11 @@ deepmerge@^2.1.1: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170" integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + defaults@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" @@ -3031,6 +3050,11 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +discontinuous-range@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" + integrity sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ== + doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -3442,11 +3466,28 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== +fast-json-stringify@^2.7.10: + version "2.7.13" + resolved "https://registry.yarnpkg.com/fast-json-stringify/-/fast-json-stringify-2.7.13.tgz#277aa86c2acba4d9851bd6108ed657aa327ed8c0" + integrity sha512-ar+hQ4+OIurUGjSJD1anvYSDcUflywhKjfxnsW4TBTD7+u0tJufv6DKRWoQk3vI6YBOWMoz0TQtfbe7dxbQmvA== + dependencies: + ajv "^6.11.0" + deepmerge "^4.2.2" + rfdc "^1.2.0" + string-similarity "^4.0.1" + fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-printf@^1.6.9: + version "1.6.9" + resolved "https://registry.yarnpkg.com/fast-printf/-/fast-printf-1.6.9.tgz#212f56570d2dc8ccdd057ee93d50dd414d07d676" + integrity sha512-FChq8hbz65WMj4rstcQsFB0O7Cy++nmbNfLYnD9cYv2cRn8EG6k/MGn9kO/tjO66t09DLDugj3yL+V2o6Qftrg== + dependencies: + boolean "^3.1.4" + fastq@^1.6.0: version "1.15.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" @@ -3768,7 +3809,7 @@ globals@^13.19.0: dependencies: type-fest "^0.20.2" -globalthis@^1.0.3: +globalthis@^1.0.2, globalthis@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== @@ -4465,6 +4506,14 @@ lint-staged@^13.2.2: string-argv "^0.3.1" yaml "^2.2.2" +liqe@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/liqe/-/liqe-3.6.0.tgz#2d05376e93ff9f4bfdb3e76481f6456d165b499f" + integrity sha512-CYVQr0bk5CCTkX3wW2MdyEWdr9FHLpiE/1cQXQ36Sdjn5gv7JIpm9jnkovFwiVzumw7f6JDFXpljwUY+fAcFYQ== + dependencies: + nearley "^2.20.1" + ts-error "^1.0.6" + listr2@^5.0.7: version "5.0.8" resolved "https://registry.yarnpkg.com/listr2/-/listr2-5.0.8.tgz#a9379ffeb4bd83a68931a65fb223a11510d6ba23" @@ -4714,6 +4763,11 @@ module-lookup-amd@^7.0.1: requirejs "^2.3.5" requirejs-config-file "^4.0.0" +moo@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/moo/-/moo-0.5.2.tgz#f9fe82473bc7c184b0d32e2215d3f6e67278733c" + integrity sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -4734,6 +4788,16 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +nearley@^2.20.1: + version "2.20.1" + resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.20.1.tgz#246cd33eff0d012faf197ff6774d7ac78acdd474" + integrity sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ== + dependencies: + commander "^2.19.0" + moo "^0.5.0" + railroad-diagrams "^1.0.0" + randexp "0.4.6" + neo-async@^2.6.0: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" @@ -5215,6 +5279,19 @@ quote-unquote@^1.0.0: resolved "https://registry.yarnpkg.com/quote-unquote/-/quote-unquote-1.0.0.tgz#67a9a77148effeaf81a4d428404a710baaac8a0b" integrity sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg== +railroad-diagrams@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e" + integrity sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A== + +randexp@0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3" + integrity sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ== + dependencies: + discontinuous-range "1.0.0" + ret "~0.1.10" + rc@1.2.8, rc@^1.2.7, rc@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -5554,12 +5631,17 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rfdc@^1.3.0: +rfdc@^1.2.0, rfdc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== @@ -5578,6 +5660,18 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +roarr@^7.15.0: + version "7.15.0" + resolved "https://registry.yarnpkg.com/roarr/-/roarr-7.15.0.tgz#09b792f0cd31b4a7f91030bb1c47550ceec98ee4" + integrity sha512-CV9WefQfUXTX6wr8CrEMhfNef3sjIt9wNhE/5PNu4tNWsaoDNDXqq+OGn/RW9A1UPb0qc7FQlswXRaJJJsqn8A== + dependencies: + boolean "^3.1.4" + fast-json-stringify "^2.7.10" + fast-printf "^1.6.9" + globalthis "^1.0.2" + safe-stable-stringify "^2.4.1" + semver-compare "^1.0.0" + rollup-plugin-visualizer@^5.9.0: version "5.9.0" resolved "https://registry.yarnpkg.com/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.9.0.tgz#013ac54fb6a9d7c9019e7eb77eced673399e5a0b" @@ -5630,6 +5724,11 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" +safe-stable-stringify@^2.4.1: + version "2.4.3" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" + integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== + sass-lookup@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/sass-lookup/-/sass-lookup-3.0.0.tgz#3b395fa40569738ce857bc258e04df2617c48cac" @@ -5644,6 +5743,11 @@ scheduler@^0.23.0: dependencies: loose-envify "^1.1.0" +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== + semver-diff@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" @@ -5810,6 +5914,11 @@ string-argv@^0.3.1, string-argv@~0.3.1: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== +string-similarity@^4.0.1: + version "4.0.4" + resolved "https://registry.yarnpkg.com/string-similarity/-/string-similarity-4.0.4.tgz#42d01ab0b34660ea8a018da8f56a3309bb8b2a5b" + integrity sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ== + string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" @@ -6032,6 +6141,11 @@ tree-kill@^1.2.2: resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== +ts-error@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/ts-error/-/ts-error-1.0.6.tgz#277496f2a28de6c184cfce8dfd5cdd03a4e6b0fc" + integrity sha512-tLJxacIQUM82IR7JO1UUkKlYuUTmoY9HBJAmNWFzheSlDS5SPMcNIepejHJa4BpPQLAcbRhRf3GDJzyj6rbKvA== + ts-graphviz@^1.5.0: version "1.6.1" resolved "https://registry.yarnpkg.com/ts-graphviz/-/ts-graphviz-1.6.1.tgz#f44525c048cb8c8c188b7324d2a91015fd31ceaf"